Compare commits

..

No commits in common. 'master' and 'develop' have entirely different histories.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 945 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 KiB

After

Width:  |  Height:  |  Size: 667 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

@ -1,2 +0,0 @@
[LocalizedFileNames]
ÐèÇóÆ¥Åä (1).png=@ÐèÇóÆ¥Åä (1),0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

@ -1,13 +0,0 @@
[*]
charset = utf-8
end_of_line = crlf
indent_size = 4
indent_style = space
insert_final_newline = false
tab_width = 4
[*.vue]
indent_size = 2
tab_width = 2
ij_vue_indent_children_of_top_level = template, script, style

@ -1,30 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo

@ -1,29 +0,0 @@
# walktofree
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```

@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

@ -1,8 +0,0 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

File diff suppressed because it is too large Load Diff

@ -1,27 +0,0 @@
{
"name": "walktofree",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vuepic/vue-datepicker": "^8.6.0",
"axios": "^1.6.8",
"echarts": "^5.5.1",
"element-china-area-data": "^6.1.0",
"element-plus": "^2.7.3",
"sass": "^1.77.6",
"vue": "^3.4.27",
"vue-router": "^4.3.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"@vue/cli-service": "^5.0.8",
"vite": "^5.2.8"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

@ -1,24 +0,0 @@
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: Arial, sans-serif;
text-align: center;
margin-top: 20px;
}
*{
padding: 0;
margin: 0;
}
</style>

@ -1,11 +0,0 @@
import axios from 'axios'
const baseURL = 'http://192.168.243.35:9000'
export const login = (data) => {
return axios.post(`${baseURL}/Login/login`, data)
}
export const register = (data) => {
return axios.post(`${baseURL}/Login/register`, data)
}

@ -1,86 +0,0 @@
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition:
color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

Before

Width:  |  Height:  |  Size: 276 B

@ -1,35 +0,0 @@
@import './base.css';
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
padding: 3px;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
}

@ -1,16 +0,0 @@
<template>
<div>
<label for="user-input"></label>
<input type="text" id="user-input" v-model="userInput" placeholder="请输入">
</div>
</template>
<script>
export default {
data() {
return {
userInput: '', //
};
},
};
</script>

@ -1,140 +0,0 @@
<template>
<div class="layout-container">
<div class="header" :style="{ backgroundColor: headerColor, height: headerHeight}">
<div class="header-content">
<div class="main-title">FreeToGo 自由同行-众包导游</div>
<h1 class="sub-title">{{ title }}</h1> <!-- 一级标题 -->
</div>
</div>
<!-- 导航栏使用 position: fixed 以确保它固定在页面的最左侧 -->
<nav class="navbar" :style="{ backgroundColor: headerColor, width: navWidth, position: 'fixed', top: '80px', height: 'calc(100vh - 80px)', left: '0' }">
<ul>
<li v-for="(link, index) in links" :key="index">
<router-link :to="link.path" class="nav-link">{{ link.name }}</router-link>
</li>
</ul>
</nav>
<!-- 内容区域使用 margin-left 来保证不被导航栏覆盖 -->
<div class="content" :style="{ marginLeft: navWidth, paddingTop: headerHeight }">
<slot></slot> <!-- 插槽用于插入不同页面的主体内容 -->
</div>
</div>
</template>
<script>
export default {
name: 'Layout',
props: {
title: {
type: String,
default: '页面标题'
},
links: {
type: Array,
default: () => []
},
headerColor: {
type: String,
default: 'gray' // CSS
},
navWidth: {
type: String,
default: '200px' //
},
headerHeight: {
type: String,
default: '80px' //
}
}
}
</script>
<style scoped>
:root {
--header-height: 80px;
--nav-width: 200px;
}
.layout-container {
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10;
background-image: url('../data/picture/loginBackground.jpg'); /* 替换为标题栏背景图片的URL */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.header-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: var(--header-height);
}
.main-title {
margin: 0;
font-size: 24px;
color: black;
}
.sub-title {
margin: 0;
font-size: 16px;
color: black;
}
.navbar {
position: fixed;
top: var(--header-height);
left: 0;
bottom: 0;
width: var(--nav-width);
z-index: 5;
padding: 10px 0;
list-style-type: none;
overflow-y: auto;
background-image: url('../data/picture/loginBackground.jpg'); /* 替换为导航栏背景图片的URL */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.navbar li {
padding: 10px 0;
}
.nav-link {
color: white;
text-decoration: none;
display: block;
padding: 5px 15px;
transition: background-color 0.3s ease;
}
.nav-link:hover, .nav-link.router-link-active {
background-color: #333;
}
.content {
flex-grow: 1;
padding: 20px;
overflow-y: auto;
margin-left: var(--nav-width);
padding-top: var(--header-height);
background-image: url('../data/picture/mainBackground.jpg'); /* 替换为内容区域背景图片的URL */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
</style>

@ -1,67 +0,0 @@
<template>
<div class="footer-nav">
<div class="button-with-icon" @click="gotohome()">
<el-icon><House /></el-icon>
<span>首页</span>
</div>
<div class="button-with-icon" @click="gotomessage()()">
<el-icon><ChatDotSquare /></el-icon>
<span>消息</span>
</div>
<div class="button-with-icon" @click="gotomine()">
<el-icon><User /></el-icon>
<span>我的</span>
</div>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
gotohome() {
this.$router.push('/home');
},
gotomessage() {
this.$router.push('/message');
},
gotomine() {
this.$router.push('/mine');
},
gotoSearchPage() {
this.$router.push('/searchPage');
},
gotoAddDemandPage() {
this.$router.push('/addDemandPage');
},
}
}
</script>
<style>
.footer-nav {
/* 定义底部导航的样式 */
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-around;
padding: 10px;
background-color: #f5f5f5; /* 示例背景色 */
}
.button-with-icon {
/* 定义按钮的样式 */
flex: 1;
border: none;
padding: 10px;
background-color: #d5d5d5;
color: #333;
cursor: pointer;
}
.button-with-icon:hover {
background-color: #aaaaaa;
}
</style>

@ -1,118 +0,0 @@
<template>
<div>
<div
ref="chinaMap"
style="height: 700px;border: solid 1px red;width: 100%;background: #ffffff;"
>
地图1
</div>
</div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts'
import chinaJSON from '../data/china.json'
import { onMounted, ref } from 'vue'
const chinaMap = ref()
onMounted(() => {
drawChina()
})
let regions = [
{
name: '新疆维吾尔自治区',
itemStyle: {
areaColor: '#374ba4',
opacity: 1,
},
},
{
name: '四川省',
itemStyle: {
areaColor: '#fe9b45',
opacity: 1,
},
},
{
name: '陕西省',
itemStyle: {
areaColor: '#fd691b',
opacity: 1,
},
},
{
name: '黑龙江省',
itemStyle: {
areaColor: '#ffc556',
opacity: 1,
},
},
]
let scatter = [
{ name: '云南', value: [102.710002, 25.045806, 9] },
]
function drawChina() {
var myChart = echarts.init(chinaMap.value)
echarts.registerMap('china', chinaJSON) //
var option = {
geo: {
map: 'china',
roam: true, //
zoom: 1, //
//
scaleLimit: {
min: 1, //
max: 2, //
},
//
center: [115.97, 29.71],
//
regions: regions,
itemStyle: {
areaColor: '#00ff00',
color: 'red',
borderColor: '#232652',
borderWidth: 2,
},
//
emphasis: {
itemStyle: {
areaColor: '#1af9e5',
color: '#fff',
},
},
},
//
series: {
type: 'effectScatter',
coordinateSystem: 'geo',
data: scatter,
showEffectOn: 'render',
rippleEffect: {
//
brushType: 'stroke', // 'stroke' 'fill'
},
hoverAnimation: true, // hover
label: {
//
normal: {
formatter: '{b}',
position: 'right',
show: true,
},
},
itemStyle: {
//normal emphasis
normal: {
color: '#ffffff', //
shadowBlur: 10,
shadowColor: 20,
fontSize: '12px',
},
},
zlevel: 1,
},
}
myChart.setOption(option)
}
</script>

@ -1,27 +0,0 @@
<template>
<div>
<el-carousel :interval="4000" arrow="always">
<el-carousel-item v-for="(item, index) in imagePaths" :key="index">
<img :src="item" alt = "描述图像的文本">
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const imagePaths = ref([
'https://dimg04.c-ctrip.com/images/0102p12000828jmogCF2E_C_1600_1200.jpg',
'https://pic.kuaizhan.com/g3/b7/18/7a16-bad5-4d28-b5aa-571710c674cb36',
'https://img.shetu66.com/2023/07/11/1689058469100908.png'
]);
return {
imagePaths
};
}
};
</script>

@ -1,7 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
<path
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
/>
</svg>
</template>

@ -1,7 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
<path
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
/>
</svg>
</template>

@ -1,7 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
<path
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
/>
</svg>
</template>

@ -1,7 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
<path
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
/>
</svg>
</template>

@ -1,19 +0,0 @@
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--mdi"
width="24"
height="24"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
>
<path
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
fill="currentColor"
></path>
</svg>
</template>

@ -1,70 +0,0 @@
<template>
<el-button plain class="addServe-button" @click="isGuide()">
我是导游
</el-button>
<el-dialog
v-model="dialogVisible"
width="500"
>
<span>您还不是导游是否申请平台导游资格</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="gotoRegisterGuide">
申请
</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router';
import axios from 'axios';
const router = useRouter();
const dialogVisible = ref(false)
const gotoRegisterGuide = () => {
router.push('/registerGuide')
}
const isGuide = () => {
axios.get(`/serve/users/isGuide?phone=${sessionStorage.getItem('phone')}`)
.then(response => {
if (response.data == true){
router.push('/addServe')
}
else{
dialogVisible.value = true;
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
}
</script>
<style>
.addServe-button {
/* 定义返回按钮的样式 */
position: fixed; /* 使按钮位置固定 */
top: 10px;
right: 10px;
margin: 0;
padding: 10px 20px;
border: none;
border-radius: 5px;
background-color: #ccc;
color: #333;
cursor: pointer;
}
.addServe-button:hover {
background-color: #aaaaaa;
}
</style>

@ -1,126 +0,0 @@
<template>
<div>
<div
ref="chinaMap"
style="height: 700px;border: solid 1px red;width: 100%;background: #b4b8b9;"
>
地图1
</div>
</div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts'
import chinaJSON from '../data/china.json'
import { onMounted, ref } from 'vue'
import axios from 'axios'
const chinaMap = ref()
let myChart: any = null
onMounted(() => {
fetchData()
})
async function fetchData() {
try {
const response = await axios.get('/serve/HeatMap/guideServiceHeatMapRegister')
const data = response.data
drawChina(data)
} catch (error) {
console.error('Failed to fetch data:', error)
}
}
function drawChina(provinceData: any) {
if (myChart) {
myChart.dispose() //
}
myChart = echarts.init(chinaMap.value)
echarts.registerMap('china', chinaJSON)
const regions = provinceData.map((item: any) => ({
name: item.name,
itemStyle: {
areaColor: getColorByPopulation(item.data),
opacity: 1,
},
}))
const option = {
geo: {
map: 'china',
roam: true, //
zoom: 1, //
//
scaleLimit: {
min: 1, //
max: 2, //
},
//
center: [115.97, 29.71],
//
regions: regions,
itemStyle: {
areaColor: '#28a7a3',
color: 'red',
borderColor: '#232652',
borderWidth: 2,
},
//
emphasis: {
itemStyle: {
areaColor: '#1af9e5',
color: '#fff',
},
},
},
//
series: {
type: 'effectScatter',
coordinateSystem: 'geo',
showEffectOn: 'render',
rippleEffect: {
//
brushType: 'stroke', // 'stroke' 'fill'
},
hoverAnimation: true, // hover
label: {
//
normal: {
formatter: '{b}',
position: 'right',
show: true,
},
},
itemStyle: {
//normal emphasis
normal: {
color: '#ffffff', //
shadowBlur: 10,
shadowColor: 20,
fontSize: '12px',
},
},
zlevel: 1,
},
}
myChart.setOption(option)
}
function getColorByPopulation(population: number): string {
//
const minPopulation = 0;
const maxPopulation = 10; // 1亿
const minColor = [173, 216, 230]; //
const maxColor = [255, 0, 0]; //
// 线
const ratio = (population - minPopulation) / (maxPopulation - minPopulation);
const r = Math.floor(minColor[0] + (maxColor[0] - minColor[0]) * ratio);
const g = Math.floor(minColor[1] + (maxColor[1] - minColor[1]) * ratio);
const b = Math.floor(minColor[2] + (maxColor[2] - minColor[2]) * ratio);
return `rgb(${r},${g},${b})`;
}
</script>

@ -1,45 +0,0 @@
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import { format } from 'date-fns'
const startDateValue = ref(format(new Date(), 'yyyy-MM-dd'))
const endDateValue = ref(format(new Date(), 'yyyy-MM-dd'))
watchEffect(() => {
console.log('startDateValue:', startDateValue.value)
console.log('endDateValue:', endDateValue.value)
})
</script>
<template>
<VueDatePicker
placeholder="请选择预计出发日期"
:min-date="new Date()"
format="yyyy-MM-dd"
v-model="startDateValue" />
<VueDatePicker
placeholder="请选择预计返回日期"
:min-date="new Date()"
format="yyyy-MM-dd"
v-model="endDateValue" />
</template>
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import { format } from 'date-fns'
const startDateValue = ref(format(new Date(), 'yyyy-MM-dd'))
const endDateValue = ref(format(new Date(), 'yyyy-MM-dd'))
watchEffect(() => {
console.log('startDateValue:', startDateValue.value)
console.log('endDateValue:', endDateValue.value)
})
</script>
<template>
<VueDatePicker
placeholder="请选择预计出发日期"
:min-date="new Date()"
format="yyyy-MM-dd"
v-model="startDateValue" />
<VueDatePicker
placeholder="请选择预计返回日期"
:min-date="new Date()"
format="yyyy-MM-dd"
v-model="endDateValue" />
</template>

@ -1,76 +0,0 @@
<template>
<div style="height:100vh;width:100%;">
<!-- 标题栏 -->
<div class="header" style="height: 11.11%;">
<h1>FreeToGo 自由同行-众包导游</h1>
</div>
<!-- 导航栏 -->
<aside class="sidebar" style="position: absolute; top: 11.11%; height: 88.89%;">
<!-- ...导航栏的其余部分... -->
</aside>
<!-- 主内容区域 -->
<div class="main-content" style="margin-left: 11.11%; height: 88.88%;">
<!-- 你的主要内容 -->
</div>
</div>
</template>
<script setup>
import { defineComponent, ref, onMounted, nextTick } from 'vue';
import { useRoute } from 'vue-router';
//
const links = ref([
{ to: '/home', text: '首页' },
{ to: '/mine', text: '个人信息' },
{ to: '/addDemand', text: '添加出行' },
{ to: '/order', text: '历史订单' },
]);
const route = useRoute();
const activeLink = ref(route.path);
onMounted(() => {
nextTick(() => {
activeLink.value = route.path;
});
});
function isActive(path) {
return path === activeLink.value;
}
</script>
<style scoped>
.header {
background-color: #13202d;
color: white;
text-align: center;
padding: 1rem;
/* ...其余样式... */
}
.sidebar {
background-color: #000000;
width: 11.11%; /* 根据页面布局调整 */
padding: 1rem;
overflow-y: auto;
/* ...其余样式... */
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.2);
position: absolute;
left: 0;
}
/* ...其余样式... */
.main-content {
padding: 1rem;
overflow-y: auto;
position: absolute;
left: 11.11%; /* 导航栏宽度 */
width: 88.89%; /* 减去导航栏宽度 */
/* ...其余样式... */
}
</style>

@ -1,6 +0,0 @@
export type AreaList = {
code: string;
level: number;
name: string;
areaList: AreaList[];
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 787 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

@ -1,18 +0,0 @@
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import ElementPlus from 'element-plus';
import 'element-plus/theme-chalk/index.css';
import VueDatePicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(ElementPlus);
app.use(router);
app.component('VueDatePicker', VueDatePicker);
app.mount('#app');

@ -1,167 +0,0 @@
<template>
<div style="height:100vh;width:100%;">
<el-container class="fullScreen">
<el-header class="header"><h1>FreeToGo 自由同行-众包导游</h1></el-header>
<el-container>
<el-aside width="200px" class="nav">
<ul>
<li>
<RouterLink to="/markdown" active-class="active">MD编辑器</RouterLink>
</li>
<li>
<RouterLink to="/tree" active-class="active">树状图</RouterLink>
</li>
<li>
<RouterLink to="/svg" active-class="active">SVG</RouterLink>
</li>
<li>
<RouterLink to="/todo" active-class="active">TodoMVC</RouterLink>
</li>
<li>
<RouterLink to="/list" active-class="active">动效列表</RouterLink>
</li>
<li>
<RouterLink to="/blur" active-class="active">模糊提示框</RouterLink>
</li>
</ul>
</el-aside>
<el-main>
<el-row :gutter="20">
<el-col :span="16">
<el-row>
<el-col :span="24">
<!-- 左边2/3的上容器 -->
<div class="container-style">上容器1</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<!-- 左边2/3的下容器 -->
<div class="container-style">下容器2</div>
</el-col>
</el-row>
</el-col>
<el-col :span="8">
<!-- 右边1/3的容器 -->
<div class="container-style">右边容器3</div>
</el-col>
</el-row>
</el-main>
</el-container>
</el-container>
</div>
</template>
<style>
*{
margin:0;
padding:0;
border:0
}
*, *:before, *:after {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
height: 100%;
}
body{
margin: 0;
padding: 0;
border: 0;
}
a {
text-decoration: none;
color: inherit;
}
.header {
background-color: #13202d;
color: white;
text-align: center;
padding: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
h1 {
font-size: 1.5rem;
}
.nav {
background-color: #2b3642;
width: 100px;
height: 95vh;
margin: 0;
padding: 0;
}
.nav ul {
padding: 1rem;
list-style-type: none;
}
.nav li {
margin-bottom: 1rem;
}
.nav li a {
display: block;
color: white;
padding: 0.5rem 1rem;
transition: background-color 0.3s;
}
.nav li a:hover, .active {
background-color: #8bb9ed;
}
.el-main {
padding: 1rem;
overflow-y: auto;
flex-grow: 1;
}
@media (max-width: 768px) {
.el-aside {
width: 100%;
height: auto;
}
.nav ul {
flex-direction: column;
width: 100%;
}
.el-main {
margin-left: 0;
}
}
.fullScreen {
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
}
.el-container {
flex: 1;
display: flex;
flex-direction: row;
overflow: hidden;
padding: 0 !important;
}
.el-header, .el-aside, .el-main {
overflow-y: auto;
}
</style>

@ -1,131 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<div class="order-container">
<div
v-for="(list, index) in lists"
:key="list.orderId"
class="order-card"
@click="goToOrderDetails(list.did)"
>
<div class="order-header">
<h3>{{ list.city }}</h3>
</div>
<div class="order-body">
<p>开始时间: {{ list.departureDate }}</p>
<p>结束时间: {{ list.endDate }}</p>
</div>
<!-- 这里可以添加状态显示如果需要 -->
</div>
</div>
</Layout>
</template>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
components: {
Layout
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
lists: [],
title: '历史出行',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
async created() {
//
axios.get(`/serve/users/getByPhone?phone=${this.phone}`)
.then(response => {
this.user = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
axios.get(`/serve/SendDemand/sendAllDemands?phone=${this.phone}`)
.then(response => {
this.lists = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
methods: {
goToOrderDetails(orderId) {
this.$router.push({ name: 'OrderDetails', params: { orderId } });
},
}
};
</script>
<style scoped>
/* 基本文本样式 */
.trip-info p {
margin: 8px 0;
font-size: 16px;
color: #333;
}
/* 订单容器样式 */
.order-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 20px;
}
/* 订单卡片样式 */
.order-card {
border: 1px solid #eaeaea;
border-radius: 10px;
margin: 10px;
padding: 20px;
background-color: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: calc(33% - 40px);
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
}
.order-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
/* 订单头部和内容样式 */
.order-header h3 {
margin: 0 0 10px;
font-size: 20px;
color: #007BFF;
}
.order-body {
font-size: 14px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.order-card {
width: calc(50% - 40px);
}
}
@media (max-width: 480px) {
.order-card {
width: 100%;
}
}
</style>

@ -1,112 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<div>
<h2>订单号: {{ orderId }}</h2>
<div v-for="(service, index) in services" :key="service.gid" class="service-box">
<div class="service-info">
<p class="nickname">导游姓名{{ service.nickname }}</p>
<p class="end-date">导游性别{{ service.endDate }}</p>
</div>
<button class="send-button" @click="sendServiceId(service.gid)"></button>
</div>
</div>
</Layout>
</template>
<style scoped>
/* 为按钮添加一些样式 */
.send-button {
display: block;
margin-left: auto; /* 将按钮推到右侧 */
margin-top: 10px; /* 顶部添加一些间距 */
padding: 5px 10px; /* 内边距 */
border: none; /* 移除边框 */
border-radius: 4px; /* 添加圆角 */
background-color: #4CAF50; /* 背景色 */
color: white; /* 文字颜色 */
cursor: pointer; /* 鼠标悬停时显示小手 */
transition: background-color 0.3s ease; /* 添加背景色过渡效果 */
}
.send-button:hover {
background-color: #45a049; /* 鼠标悬停时改变背景色 */
}
/* 为服务信息盒子添加样式 */
.service-box {
border: 1px solid #ccc;
padding: 15px;
margin-bottom: 15px;
background-color: #fff; /* 添加背景色 */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
border-radius: 5px; /* 添加圆角 */
}
/* 为昵称和结束日期添加样式 */
.service-info {
display: flex;
justify-content: space-between; /* 内容两端对齐 */
align-items: center; /* 内容垂直居中 */
}
.nickname, .end-date {
margin: 0; /* 移除默认的外边距 */
}
</style>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
props: ['orderId'],
components: {
Layout,
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
services: [],
title: '匹配情况',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
methods: {
async sendServiceId(gid) {
try {
// APIgiddidPOST
const orderIdAsInt = parseInt(this.orderId, 10);
const gidAsInt = parseInt(gid, 10);
const response = await axios.post('/serve/DemandMatch/match', { did:orderIdAsInt,gid:gidAsInt});
alert('已向导游发送确认信息');
} catch (error) {
console.error('Error sending service ID and order ID:', error);
}
}
},
async created() {
//
axios.get(`/serve/DemandMatch/register?did=${this.orderId}`)
.then(response => {
this.services = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
}
};
</script>

@ -1,146 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<div class="user-feedback">
<!-- 输入评价 -->
<div class="feedback-input">
<h2>行程评价</h2>
<form>
<textarea id="ebody" v-model.trim="evaluation.ebody" rows="4" cols="50"></textarea>
<button type="submit" @click="send"></button>
</form>
</div>
<el-space direction="vertical">
<el-row>
<el-text>星级评价</el-text>
<el-rate class="ml-1"
v-model="evaluation.satisfaction"
:texts="['oops', 'disappointed', 'normal', 'good', 'great']"
show-text
@change="handleRateChange"
clearable />
</el-row>
</el-space>
</div>
</Layout>
</template>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
props: ['orderId'],
components: {
Layout,
},
data() {
return {
ebody: '',
satisfaction:'',
did:'',
evaluation: {}, //
phone: sessionStorage.getItem('phone') || '',
title: '行程评价',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
methods: {
send() {
axios.post('/serve/evaluate/addEvaluation', {
did: this.orderId,
satisfaction: this.evaluation.satisfaction,
ebody: this.evaluation.ebody,
}, {
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
}).then(response => {
//
location.reload();
}).catch(error => {
//
console.error('评价发送失败', error);
});
},
fetchEvaluation() {
axios.get(`/serve/users/getByPhone?phone=${this.phone}`)
.then(response => {
this.user = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
axios.get(`/serve/evaluate/getEvaluation?eid=${this.orderId}`)
.then(response => {
this.evaluation = response.data;// evaluation
})
.catch(error => {
console.error('获取评价信息失败', error);
});
},
handleRateChange(satisfaction) {
this.evaluation.satisfaction = satisfaction; //
}
},
mounted() {
this.fetchEvaluation(); // fetchEvaluation
}
};
</script>
<style scoped>
.user-feedback {
max-width: 600px;
margin: 0 auto;
}
.feedback-input {
margin-bottom: 20px;
}
textarea {
width: 100%;
padding: 8px;
font-size: 16px;
border: 1px solid #28a7a3;
border-radius: 4px;
margin-bottom: 10px;
}
button {
padding: 8px 16px;
font-size: 16px;
border: none;
border-radius: 4px;
background-color: #007bff;
color: #003f3f;
cursor: pointer;
}
.submitted-feedback {
border-top: 1px solid #a6cfee;
padding-top: 20px;
}
.feedback-item {
background-color: #abd4ee;
border: 1px solid #c2f1fb;
border-radius: 4px;
padding: 10px;
}
.feedback-item p {
margin: 0;
}
</style>

@ -1,11 +0,0 @@
<script setup>
</script>
<template>
</template>
<style scoped>
</style>

@ -1,94 +0,0 @@
<template>
<div class="item-manager">
<el-button type="primary" @click="add">Add Item</el-button>
<el-button type="danger" @click="onDelete">Delete Item</el-button>
<el-scrollbar class="custom-scrollbar" max-height="800px">
<div v-for="(item, index) in count" :key="index" class="item-container">
<p class="scrollbar-demo-item">{{ item }}</p>
</div>
<div v-for="review in reviews" :key="review.id" class="review-container">
<p class="scrollbar-demo-item">{{ review.content }}</p>
</div>
</el-scrollbar>
</div>
</template>
<style scoped>
.scrollbar-demo-item {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin: 10px;
text-align: center;
border-radius: 4px;
background: var(--el-color-primary-light-9);
color: var(--el-color-primary);
}
.item-manager {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 20px;
}
.custom-scrollbar {
width: 100%; /* 根据需要调整滚动条容器的宽度 */
border-radius: 8px; /* 添加圆角 */
overflow: auto; /* 确保滚动条出现 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影 */
}
.scrollbar-demo-item {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin: 10px;
padding: 0 15px; /* 添加内边距 */
border-radius: 4px;
background: var(--el-color-primary-light-9);
color: var(--el-color-primary);
transition: background-color 0.3s ease; /* 添加背景色过渡效果 */
}
.item-container,
.review-container {
}
.custom-scrollbar::-webkit-scrollbar {
width: 10px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: #f1f1f1;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #888;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
<script lang="ts" setup>
import { ref } from 'vue'
const count = ref(3)
const reviews = ref([
{ id: 1, content: 'Great product!' },
{ id: 2, content: 'Fast shipping!' },
{ id: 3, content: 'Excellent customer service!' }
])
const add = () => {
count.value++
}
const onDelete = () => {
if (count.value > 0) {
count.value--
}
}
</script>

@ -1,191 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<!-- 将flex-direction改为row以实现水平排列 -->
<div class="main-content" :style="{ display: 'flex', flexDirection: 'row' }">
<div class="left-container" :style="{ flex: '3', height: 'calc(100vh - 20px)' }">
<h2>全国城市旅游热力图</h2>
<MapComponent></MapComponent>
</div>
<div class="right-container" :style="{ flex: '1', height: '100vh', marginLeft: '20px' }">
<h1>排行榜</h1>
<div class="ranking-container">
<div v-for="(item, index) in rankingList" :key="index" class="ranking-item">
<span class="ranking-number">{{ index + 1 }}.</span>
<span class="city-name">{{ item.city }}</span>
<span class="visitors-count">{{ item.visitors }}</span>
</div>
</div>
</div>
</div>
</Layout>
</template>
<script>
import Layout from '../components/Layout.vue'; //
import MapComponent from '../components/map.vue';
import axios from 'axios';
export default {
name: 'HomePage',
components: {
Layout,
MapComponent
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
title: '首页',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
rankingList: [
{ city: '广东', visitors: 3 },
{ city: '湖南', visitors: 2 },
// ...
],
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
mounted() {
this.fetchUser(this.phone);
},
methods: {
fetchUser(phone) {
// API
axios.get(`/serve/users/getByPhone?phone=${phone}`)
.then(response => {
this.user = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
}
}
</script>
<style scoped>
/* 整体页面样式 */
.main-content {
height: calc(100vh - 80px);
padding: 20px;
transition: background-color 0.3s; /* 过渡效果 */
background-color: rgba(255, 255, 255, 0.1);
}
/* 左侧容器样式 */
.left-container {
flex: 3;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 5px;
padding: 20px;
transition: box-shadow 0.3s, transform 0.3s; /* 过渡效果 */
background-color: rgba(255, 255, 255, 0.1);
}
/* 右侧容器样式 */
.right-container {
flex: 1;
margin-left: 20px;
background-color: rgba(255, 255, 255, 0.1);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 5px;
padding: 20px;
transition: box-shadow 0.3s, transform 0.3s; /* 过渡效果 */
}
/* 排行榜容器样式 */
.ranking-container {
width: 100%;
border: 1px solid #666c6e;
border-radius: 5px;
padding: 10px;
background-color: #abd4ee;
transition: background-color 0.3s; /* 过渡效果 */
}
/* 排行榜项样式 */
.ranking-item {
display: flex;
align-items: center;
margin-bottom: 5px;
padding: 8px;
border-bottom: 1px solid #28a7a3;
transition: background-color 0.3s, transform 0.3s; /* 过渡效果 */
}
.ranking-item:hover {
background-color: #e0e2e3;
transform: scale(1.02); /* 放大效果 */
}
/* 排行榜序号样式 */
.ranking-number {
font-weight: bold;
margin-right: 5px;
color: #333;
transition: color 0.3s; /* 过渡效果 */
}
/* 城市名称样式 */
.city-name {
flex: 1;
font-size: 16px;
color: #555;
transition: color 0.3s; /* 过渡效果 */
}
/* 游客数量样式 */
.visitors-count {
margin-left: 5px;
color: #666;
transition: color 0.3s; /* 过渡效果 */
}
/* 标题样式 */
h1, h2 {
color: #333;
margin-bottom: 20px;
transition: color 0.3s; /* 过渡效果 */
}
/* 链接样式 */
.links {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
}
.link {
margin-left: 10px;
color: #007bff;
text-decoration: none;
transition: color 0.3s, transform 0.3s; /* 过渡效果 */
}
.link:hover {
color: #0056b3;
transform: scale(1.1); /* 放大效果 */
}
/* 页面滚动特效 */
.main-content.scrolled {
background-color: #e5e5e5; /* 滚动后的背景色 */
}
.left-container.scrolled,
.right-container.scrolled {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 滚动后的阴影效果 */
transform: translateY(-10px); /* 滚动后的位移效果 */
}
/* 使用JavaScript监听滚动事件来添加.scrolled类 */
</style>

@ -1,158 +0,0 @@
<template>
<div class="login-container">
<div class="background" ref="background"></div>
<div class="login-content" @mouseover="applyBlur" @mouseleave="removeBlur">
<div class="login-header">
<h1>登录</h1>
</div>
<div class="login-form">
<label for="phone">手机号:</label><br>
<input type="text" id="phone" v-model="phone" name="phone" class="input-field" placeholder="输入您的手机号"><br>
<label for="password">密码:</label><br>
<input type="password" id="password" v-model="password" name="password" class="input-field" placeholder="输入您的密码"><br>
<button class="submit-button" @click="login"></button>
</div>
<div class="register-link">
<p>没有账号? <a href="/register">现在注册</a></p>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
phone: '',
password: ''
}
},
methods: {
applyBlur() {
this.$refs.background.style.filter = 'blur(5px)';
},
removeBlur() {
this.$refs.background.style.filter = 'none';
},
login() {
console.log("手机号:", this.phone);
console.log("密码:", this.password);
axios.post('/serve/Login/login', {
//
phone: this.phone,
password: this.password
}, {
// cookie
withCredentials: true,
// JSON
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.data == 1) {
sessionStorage.setItem('phone', this.phone);
//
this.$router.push('/home');
}
else if (response.data == 2) {
alert('登录失败:账号或密码错误' );
}
else if(response.data == 3){
alert('登录失败:账号未注册');
}
else if(response.data == 6) {
alert('登录失败:未输入账号密码');
}
else if(response.data == 7) {
alert('登录失败:未输入账号');
}
else if(response.data == 8) {
alert('登录失败:未输入密码');
}
else {
alert('登录失败:未知原因');
}
})
.catch(error => {
console.error(error);
//
alert('登录失败:网络错误或服务器错误');
});
},
},
};
</script>
<style>
.login-container {
position: relative;
}
.background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('../data/picture/微信图片_20240629090627.jpg');
background-size: cover;
filter: blur(0);
transition: filter 0.5s;
}
.login-content {
position: relative;
z-index: 1;
width: 400px;
margin: 100px auto;
background-color: #fdfcfc;
border-radius: 5px;
box-shadow: 0 2px 4px rgb(0, 63, 63);
padding: 20px;
}
.login-header h1 {
text-align: center;
font-size: 2rem;
margin-bottom: 10px;
color: #000000;
}
.login-form {
margin-top: 20px;
display: inline-block;
}
.input-field {
margin: 10px 0;
padding: 10px;
width: 100%;
border: 1px solid #000000;
border-radius: 5px;
}
.submit-button {
padding: 10px 20px;
margin-top: 20px;
background-color: #007bff;
color: #fdfcfc;
border: none;
border-radius: 5px;
cursor: pointer;
}
.submit-button:hover {
background-color: #003f3f;
}
.register-link {
margin-top: 20px;
text-align: center;
color: #000000;
}
</style>

@ -1,113 +0,0 @@
<template>
<div class="payment">
<h2>支付订单</h2>
<div class="order-summary">
<p>订单金额: {{ orderAmount }} </p>
</div>
<div class="payment-form">
<label for="cardNumber">银行卡号</label>
<input type="text" id="cardNumber" v-model.trim="cardNumber" placeholder="请输入银行卡号">
<label for="expiry">到期日期</label>
<input type="text" id="expiry" v-model.trim="expiry" placeholder="MM/YY">
<label for="cvv">CVV</label>
<input type="text" id="cvv" v-model.trim="cvv" placeholder="请输入CVV">
<button @click="submitPayment" :disabled="loading">支付</button>
<p v-if="error" class="error-message">{{ error }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
orderAmount: 100, // 100
cardNumber: '',
expiry: '',
cvv: '',
loading: false,
error: ''
};
},
methods: {
submitPayment() {
//
this.loading = true;
const paymentData = {
cardNumber: this.cardNumber,
expiry: this.expiry,
cvv: this.cvv,
amount: this.orderAmount
};
// '/api/payment'
fetch('/api/payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(paymentData)
})
.then(response => {
if (!response.ok) {
throw new Error('支付失败,请稍后重试。');
}
return response.json();
})
.then(data => {
//
console.log('支付成功:', data);
this.error = '';
})
.catch(error => {
//
console.error('支付失败:', error.message);
this.error = error.message;
})
.finally(() => {
this.loading = false;
});
}
}
};
</script>
<style scoped>
.payment {
max-width: 600px;
margin: 0 auto;
}
.order-summary {
margin-bottom: 20px;
}
label {
font-weight: bold;
}
input {
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 8px 16px;
font-size: 16px;
border: none;
border-radius: 4px;
background-color: #007bff;
color: #fff;
cursor: pointer;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.error-message {
color: #dc3545;
}
</style>

@ -1,195 +0,0 @@
<template>
<div class="register-container">
<div class="background" ref="background"></div>
<div class="register-content" @mouseover="applyBlur" @mouseleave="removeBlur">
<div class="register-header">
<h1>注册</h1>
</div>
<div class="register-form">
<label for="phone" class="required-field">手机号:</label><br>
<input type="text" id="phone" v-model="phone" name="phone" class="input-field" placeholder="输入您的手机号"><br>
<label for="password" class="required-field">密码:</label><br>
<input type="password" id="password" v-model="password" name="password" class="input-field" placeholder="输入您的密码"><br>
<label for="confirmPassword" class="required-field">确认密码:</label>
<input type="password" id="confirmPassword" v-model="confirmPassword" name="confirmPassword" class="input-field" placeholder="确认您的密码">
<label for="name" class="required-field">姓名:</label><br>
<input type="text" id="name" v-model="name" name="name" class="input-field" placeholder="输入您的姓名"><br>
<label for="IDcard" class="required-field">身份证号:</label><br>
<input type="text" id="idNumber" v-model="IDcard" name="idNumber" class="input-field" placeholder="输入您的身份证号"><br>
<label for="nickname" class="required-field">昵称:</label><br>
<input type="text" id="nickname" v-model="nickname" name="nickname" class="input-field" placeholder="输入您的昵称"><br>
<label for="place">居住地:</label><br>
<el-cascader
placeholder="请选择"
:options="options"
v-model="selectedOptions"
@change="handleChange"
></el-cascader>
</div>
<div class="login-link">
<button class="submit-button" @click="register"></button>
<p>已有账号? <a href="/login">立即登录</a></p>
</div>
</div>
</div>
</template>
<style>
.required-field::after {
content: '*';
color: red;
margin-left: 5px; /* 根据需要调整间距 */
}
.register-container {
position: relative;
}
.background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('../data/picture/loginBackground.jpg');
background-size: cover;
filter: blur(0);
transition: filter 0.5s;
}
.register-content {
position: relative;
z-index: 1;
width: 400px;
margin: 100px auto;
background-color: #fdfcfc;
border-radius: 5px;
box-shadow: 0 2px 4px rgb(0, 63, 63);
padding: 20px;
}
.register-header h1 {
text-align: center;
font-size: 2rem;
margin-bottom: 10px;
color: #000000;
}
.register-form {
margin-top: 20px;
display: inline-block;
}
.input-field {
margin: 10px 0;
padding: 10px;
width: 100%;
border: 1px solid #000000;
border-radius: 5px;
}
.submit-button {
padding: 10px 20px;
margin-top: 20px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}
.submit-button:hover {
background-color: #003f3f;
}
.login-link {
margin-top: 20px;
text-align: center;
color: #000000;
}
</style>
<script>
import axios from "axios";
import { regionData } from 'element-china-area-data'
export default {
data() {
return {
phone: '',
password: '',
name:'',
nickname:'',
IDcard:'',
confirmPassword: '',
email: '',
place: '',
passwordsMatch: false,
selectedOptions: [],
options: regionData
}
},
methods:{
applyBlur() {
this.$refs.background.style.filter = 'blur(5px)';
},
removeBlur() {
this.$refs.background.style.filter = 'none';
},
register() {
if (this.password !== this.confirmPassword) {
this.passwordsMatch = false;
alert('密码和确认密码不一致');
}
else if (this.password === this.confirmPassword){
console.log("手机号:", this.phone);
console.log("密码:", this.password);
console.log("姓名:",this.name);
console.log("身份证号:",this.IDcard);
console.log("昵称:",this.nickname);
console.log("居住地:",this.place);
axios.post(`/serve/Login/register`, {
//
phone: this.phone,
password: this.password,
name:this.name,
IDCard:this.IDcard,
nickname:this.nickname
}, {
// cookie
withCredentials: true,
// JSON
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if(response.data == 5){
alert("注册成功");
this.$router.push('/login');
}else if(response.data == 4){
alert("该账号已注册")
}else if(response.data == 9){
alert("身份证错误")
}else if (response.data == 11){
alert("手机号错误")
}else if (response.data == 12){
alert("密码过于简单请输入8位以上密码")
}else if (response.data == 13){
alert("请输入真实姓名")
}else{
alert("未知错误")
}
})
.catch(error => {
console.error(error)
//
alert("网络或服务器错误");
})
}
},
handleChange(value, selectedData) {
console.log(value, selectedData);
}
}
}
</script>

@ -1,116 +0,0 @@
<template>
<div class="security-verification">
<h2>安全验证</h2>
<!-- 身份证号验证 -->
<div class="verification-item">
<label for="idCard">身份证号</label>
<input type="text" id="idCard" v-model.trim="idCard" placeholder="请输入身份证号">
<button @click="verifyIdCard" :disabled="loading">验证</button>
<p v-if="idCardValid" class="valid-message"></p>
<p v-else-if="idCard !== ''" class="invalid-message">请输入有效的身份证号</p>
</div>
<!-- 银行卡号验证 -->
<div class="verification-item">
<label for="bankCard">银行卡号</label>
<input type="text" id="bankCard" v-model.trim="bankCard" placeholder="请输入银行卡号">
<button @click="verifyBankCard" :disabled="loading">验证</button>
<p v-if="bankCardValid" class="valid-message"></p>
<p v-else-if="bankCard !== ''" class="invalid-message">请输入有效的银行卡号</p>
</div>
<p v-if="error" class="error-message">{{ error }}</p>
</div>
</template>
<script>
export default {
data() {
return {
idCard: '',
idCardValid: false,
bankCard: '',
bankCardValid: false,
loading: false,
error: ''
};
},
methods: {
verifyIdCard() {
this.loading = true;
//
setTimeout(() => {
if (/^\d{17}[\dXx]$/.test(this.idCard)) {
this.idCardValid = true;
this.error = '';
} else {
this.idCardValid = false;
this.error = '请输入有效的身份证号!';
}
this.loading = false;
}, 1000); // 1
},
verifyBankCard() {
this.loading = true;
//
setTimeout(() => {
if (/^\d{16,19}$/.test(this.bankCard)) {
this.bankCardValid = true;
this.error = '';
} else {
this.bankCardValid = false;
this.error = '请输入有效的银行卡号!';
}
this.loading = false;
}, 1000); // 1
}
}
};
</script>
<style scoped>
.security-verification {
max-width: 600px;
margin: 0 auto;
}
.verification-item {
margin-bottom: 20px;
}
label {
font-weight: bold;
}
input {
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 8px 16px;
font-size: 16px;
border: none;
border-radius: 4px;
background-color: #007bff;
color: #fff;
cursor: pointer;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.valid-message {
color: #28a745;
}
.invalid-message {
color: #dc3545;
}
.error-message {
color: #dc3545;
}
</style>

@ -1,223 +0,0 @@
<script lang="ts" setup>
import { ref, computed, onMounted, watch } from 'vue';
import axios from 'axios';
import { ElSelect, ElOption } from 'element-plus';
import { AreaList } from '../components/types';
import { format, addDays } from 'date-fns';
import Layout from '../components/Layout.vue';
// 使ref
const phone = ref(sessionStorage.getItem('phone') || '');
const title = '添加出行';
const links = ref([
{ name: '首页', path: '/home' },
{ name: '个人信息', path: '/mine' },
{ name: '添加出行', path: '/addDemandPage' },
{ name: '历史出行', path: '/demandList' }
]);
const user = ref({
membertype: false,
});
const guideGender = ref('');
const travelersCount = ref(1);
const province = ref('');
const city = ref('');
const area = ref('');
const remark = ref('');
const provinceList = ref<AreaList[]>([]);
const cityList = ref<AreaList[]>([]);
const areaList = ref<AreaList[]>([]);
const rangeValue = ref<string[]>([format(new Date(), 'yyyy-MM-dd'), format(addDays(new Date(), 1), 'yyyy-MM-dd')]);
//
const getProvinceList = async () => {
try {
const res = await axios.get<AreaList[]>('https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json');
provinceList.value = res.data;
} catch (error) {
console.error('Error fetching province list:', error);
}
};
//
const publish = async () => {
if (city.value !== '') {
try {
const response = await axios.post(`/serve/SendDemand/register`, {
phone: phone.value,
city: city.value,
time: rangeValue.value,
remark: remark.value
});
alert("发布成功");
} catch (error) {
console.error('发布失败', error);
}
} else {
alert("请输入目的地");
}
};
//
onMounted(async () => {
await getProvinceList();
try {
const response = await axios.get(`/serve/users/getByPhone?phone=${phone.value}`);
if (response.data) {
user.value = response.data;
}
} catch (error) {
console.error('Error fetching user data:', error);
}
});
//
const computedLinks = computed(() => {
return user.value.membertype === true
? links.value.concat([{ name: '服务发布', path: '/addServe' }, { name: '导游记录', path: '/serverList' }])
: links.value.concat([{ name: '注册导游', path: '/registerGuide' }]);
});
// watcher
watch(province, (newValue, oldValue) => {
const matchedProvince = provinceList.value.find(item => item.name === newValue);
if (matchedProvince) {
cityList.value = matchedProvince.areaList;
city.value = ''; //
areaList.value = []; //
}
});
// watcher
watch(city, (newValue, oldValue) => {
const matchedCity = cityList.value.find(item => item.name === newValue);
if (matchedCity) {
areaList.value = matchedCity.areaList;
area.value = ''; //
}
});
</script>
<template>
<Layout :title="title" :links="computedLinks">
<h3>选择出行城市</h3>
<div class="city" style="display: flex; align-items: center;">
<p style="color: red;">*</p>
<el-select v-model="province" clearable placeholder="省份">
<el-option v-for="item in provinceList" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
<el-select v-model="city" clearable placeholder="城市">
<el-option v-for="item in cityList" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
</div>
<h3>选择出行时间</h3>
<div class="time-select">
<VueDatePicker
placeholder="请选择出行时间"
range
:min-date="new Date()"
format="yyyy-MM-dd"
:width="280"
v-model="rangeValue" />
</div>
<h3>期望导游性别</h3>
<div>
<el-select v-model="guideGender" placeholder="请选择">
<el-option label="男" value="male" />
<el-option label="女" value="female" />
</el-select>
</div>
<h3>出行人数</h3>
<div>
<label for="travelers-count"></label>
<input type="number" id="travelers-count" v-model.number="travelersCount"
placeholder="请输入出行人数" min="1" max="100" />
</div>
<h3>填写备注信息</h3>
<div>
<label for="user-input"></label>
<input type="text" id="remark" v-model="remark" placeholder="请输入备注信息">
</div>
<el-button type="primary" @click="publish"></el-button>
</Layout>
</template>
<style scoped>
body {
font-family: 'Helvetica Neue', Arial, sans-serif;
background: #f4f4f4;
color: #333;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
/* Form container - removed to achieve elements centered */
.addDemand-container { /* Removed */
}
/* Update styles for form elements */
.el-select, input[type="number"], input[type="text"], .time-select, .city, .el-button {
width: 70%;
margin: 0 auto; /* Center the elements horizontally */
padding: 10px;
margin-bottom: 20px;
border: none;
border-radius: 4px;
background-color: #f9f9f9;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s;
}
.el-select:hover, input[type="number"]:hover, input[type="text"]:hover, .time-select:hover, .city:hover, .el-button:hover {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.el-select:focus, input[type="number"]:focus, input[type="text"]:focus, .time-select:focus, .city:focus, .el-button:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
/* Reset select inner border and styles */
.el-select .el-input__inner {
border: none;
background-color: #f9f9f9;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
/* Button styles */
.el-button {
width: 40%; /* Update button width */
padding: 15px;
font-size: 1em;
border: none;
border-radius: 4px;
background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%); /* Change background color to blue gradient */
color: white;
transition: background-image 0.3s;
margin-top: 20px;
}
.el-button:hover {
background-image: linear-gradient(to right, #2575fc 0%, #6a11cb 100%);
}
/* Responsive design */
@media (max-width: 768px) {
.addDemand-container {
width: 90%;
padding: 20px;
}
}
</style>

@ -1,194 +0,0 @@
<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
import axios, { AxiosError } from 'axios';
import { ElSelect, ElOption, ElButton } from 'element-plus';
import { AreaList } from '../components/types';
import { format, addDays } from 'date-fns';
import Layout from '../components/Layout.vue';
const phone = ref(sessionStorage.getItem('phone') || '');
const title = '发布服务';
const links = ref([
{ name: '首页', path: '/home' },
{ name: '个人信息', path: '/mine' },
{ name: '添加出行', path: '/addDemandPage' },
{ name: '历史出行', path: '/demandList' }
]);
const user = ref({
membertype: true,
});
const province = ref('');
const city = ref('');
const area = ref('');
const remark = ref('');
const provinceList = ref<AreaList[]>([]);
const cityList = ref<AreaList[]>([]);
const areaList = ref<AreaList[]>([]);
const rangeValue = ref<string[]>([format(new Date(), 'yyyy-MM-dd'), format(addDays(new Date(), 1), 'yyyy-MM-dd')]);
// JSON
const getProvinceList = async () => {
const res = await axios.get<AreaList[]>('https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json')
provinceList.value = res.data
console.log(provinceList.value)
}
const publish = () => {
//
if(city.value!=''){
axios.post(`/serve/SendGuideService/register`,{phone:sessionStorage.getItem('phone') || '',city:city.value,time:rangeValue.value,remark:remark.value})
.then(response => {
alert("发布成功")
})
.catch(error => {
console.error('发布失败', error);
});}
else{
alert("请输入目的地")
}
};
onMounted(async () => {
try {
await getProvinceList();
const response = await axios.get(`/serve/users/getByPhone?phone=${phone.value}`);
if (response.data) {
user.value = response.data;
}
} catch (error) {
console.error('Error fetching user or province list:', error);
//
}
});
//
const computedLinks = computed(() => {
return user.value.membertype === true
? links.value.concat([{ name: '服务发布', path: '/addServe' }, { name: '导游记录', path: '/serverList' }])
: links.value.concat([{ name: '注册导游', path: '/registerGuide' }]);
});
watch(province, (newValue, oldValue) => {
if (newValue) {
const matchedProvince = provinceList.value.find(item => item.name === newValue);
if (matchedProvince) {
cityList.value = matchedProvince.areaList;
city.value = ''; //
areaList.value = []; //
}
}
});
// watcher
watch(city, (newValue, oldValue) => {
if (newValue) {
const matchedCity = cityList.value.find(item => item.name === newValue);
if (matchedCity) {
areaList.value = matchedCity.areaList;
area.value = ''; //
}
}
});
</script>
<template>
<Layout :title="title" :links="computedLinks">
<h1>导游服务</h1>
<h3>选择导游城市</h3>
<div class="city" style="display: flex; align-items: center;">
<p style="color: red;">*</p>
<el-select v-model="province" clearable placeholder="省份">
<el-option v-for="item in provinceList" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
<el-select v-model="city" clearable placeholder="城市">
<el-option v-for="item in cityList" :key="item.code" :label="item.name" :value="item.name" />
</el-select>
</div>
<h3>选择导游时间</h3>
<div class="time-select">
<VueDatePicker
placeholder="请选择出行时间"
range
:min-date="new Date()"
format="yyyy-MM-dd"
:width="280"
v-model="rangeValue" />
</div>
<h3>添加备注信息</h3>
<div>
<input type="text" v-model="remark" placeholder="请输入备注信息" />
</div>
<el-button type="primary" @click="publish"></el-button>
</Layout>
</template>
<style scoped>
/* 页面整体样式 */
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
color: #333;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
/* 标题样式 */
h1, h3 {
color: #333;
margin-left: 20px; /* 为标题添加左边距 */
}
h1 {
font-size: 24px;
text-align: center; /* 标题居中 */
margin-bottom: 20px;
}
h3 {
font-size: 18px;
margin-bottom: 10px;
}
/* 表单控件美化 */
.el-select, input[type="text"], .time-select, .el-button {
width: 70%;
margin: 0 auto; /* Center the elements horizontally */
padding: 10px;
margin-bottom: 20px;
border: none;
border-radius: 4px;
background-color: #f9f9f9;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s;
}
/* 按钮样式 */
.el-button {
width: 40%; /* 按钮宽度 */
padding: 15px;
font-size: 1em;
border: none;
border-radius: 4px;
background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);
color: white;
transition: background-image 0.3s;
margin-top: 20px;
}
.el-button:hover {
background-image: linear-gradient(to right, #2575fc 0%, #6a11cb 100%);
}
/* 响应式设计 */
@media (max-width: 768px) {
.form-container {
width: 90%;
}
}
</style>

@ -1,131 +0,0 @@
<template>
<div><button class="back-button" @click="goBack"></button></div>
<div class="profile-edit">
<h2>修改个人信息</h2>
<form @submit.prevent="updateProfile">
<div>
<label for="nickname">昵称</label>
<input type="text" id="nickname" v-model="userInfo.nickname" class="input-field">
</div>
<div>
<label for="email">邮箱</label>
<input type="email" id="email" v-model="userInfo.email" class="input-field">
</div>
<div>
<label for="phone">手机号</label>
<input type="tel" id="phone" v-model="userInfo.phone" class="input-field">
</div>
<div>
<label for="password">个人简介</label>
<input type="text" id="brief" v-model="userInfo.brief" class="input-field">
</div>
<button type="submit">保存</button>
</form>
<div v-if="message" class="message">{{ message }}</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
userInfo: { },
message: '',
phone:sessionStorage.getItem('phone') || '',
};
},
mounted() {
this.fetchUser(this.phone);
},
methods: {
fetchUser(phone) {
// API
axios.get(`/serve/users/getByPhone?phone=${phone}`)
.then(response => {
this.userInfo = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
updateProfile() {
//
axios.post(`/serve/users/Pupdate`,{user:this.userInfo})
.then(response => {
})
.catch(error => {
console.error('Error updating nickname:', error);
});
this.message = '个人信息更新成功!';
//
//
setTimeout(() => {
this.message = '';
}, 2000);
},
goBack(){
this.$router.push('/mine')
}
},
};
</script>
<style scoped>
.back-button {
/* 这里是自定义按钮的样式 */
display: inline-block;
padding: 10px 20px;
font-size: 16px;
color: white;
background-color: #55aa00; /* 蓝色背景 */
border: none;
border-radius: 4px;
cursor: pointer;
margin-bottom: 20px; /* 底部留一些空间 */
position: absolute; /* 绝对定位以将其放置在左上角 */
top: 10px; /* 距离顶部的距离 */
left: 10px; /* 距离左侧的距离 */
}
.profile-edit {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.input-field {
margin-bottom: 10px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 3px;
}
button {
display: inline-block;
padding: 5px 10px;
margin-top: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #45a049;
}
.message {
color: #333;
margin-top: 10px;
text-align: center;
}
</style>

@ -1,248 +0,0 @@
<script setup>
// request
import {
getBaseUrl,
requestUtil
} from '../../utils/requestUtil.js';
Page({
/**
* 页面的初始数据
*/
data: {
baseUrl: '',
cart:[],
address:{},
totalPrice:0,
totalNum:0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const baseUrl=getBaseUrl();
this.setData({
baseUrl
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
console.log("show")
const address=wx.getStorageSync('address');
let cart=wx.getStorageSync('cart')||[];
//
cart=cart.filter(v=>v.checked);
let totalPrice=0;
let totalNum=0;
cart.forEach(v=>{
totalPrice+=v.num*v.price;
totalNum+=v.num;
})
this.setData({
cart,
address,
totalNum,
totalPrice
})
}
})
</script>
<template>
<!-- 收货地址 开始 -->
<view class="revice_address_row">
<view class="user_info">
<view class="user_info_item">{{address.provinceName+address.cityName+address.countyName}}</view>
<view class="user_info_item user_info_detail">{{address.detailInfo}}</view>
<text class="user_info_item" decode="{{true}}">{{address.userName}}&nbsp;&nbsp;{{address.telNumber}}</text>
</view>
</view>
<!-- 收货地址 结束 -->
<!-- 购物车清单 开始 -->
<view class="cart_content">
<view class="cart_main">
<view class="cart_item"
wx:for="{{cart}}"
wx:key="id"
>
<!-- 商品图片 开始 -->
<navigator class="cart_img_warp" url="/pages/product_detail/index?id={{item.id}}">
<image mode="widthFix" src="{{baseUrl+'/image/product/'+item.proPic}}"></image>
</navigator>
<!-- 商品图片 结束 -->
<!-- 商品信息 开始 -->
<view class="cart_info_warp">
<navigator url="/pages/product_detail/index?id={{item.id}}">
<view class="goods_name">{{item.name}}</view>
</navigator>
<view class="goods_price_warp">
<view class="goods_price">¥ {{item.price}}</view>
<view class="cart_num_tool">
<view class="goods_num">×{{item.num}}</view>
</view>
</view>
</view>
<!-- 商品信息 结束 -->
</view>
</view>
</view>
<!-- 购物车清单 结束 -->
<!-- 底部工具类 开始 -->
<view class="footer_tool">
<!-- 总价格 开始 -->
<view class="total_price_wrap">
<view class="total_price">
{{totalNum}}合计<text class="total_price_text" decode="{{true}}">&nbsp;¥ {{totalPrice}}</text>
</view>
</view>
<!-- 总价格 结束 -->
<!-- 结算 开始 -->
<view class="order_pay_wrap" bindtap="handlePay">
去付款
</view>
<!-- 结算 结束 -->
</view>
<!-- 底部工具类 结束 -->
</template>
<style scoped>
page{
padding-bottom: 70rpx;
}
.revice_address_row{
border-bottom: 1rpx dotted gray;
padding: 20rpx;
.user_info{
.user_info_item{
margin-top: 10rpx;
}
.user_info_detail{
font-size: 20px;
font-weight: bolder;
margin-bottom: 10rpx;
}
}
}
.cart_content{
background-color: #F5F5F5;
.cart_main{
padding: 2rpx 10rpx 10rpx 10rpx;
.cart_item{
display: flex;
background-color: white;
border-radius: 10px;
margin: 20rpx;
padding-right: 20rpx;
.cart_img_warp{
flex:2;
display: flex;
justify-content: center;
align-items: center;
margin: 20rpx;
border-radius: 10px;
background-color: #F5F5F5;
image{
width: 80%;
}
}
.cart_info_warp{
flex:4;
display: flex;
flex-direction: column;
justify-content: space-around;
navigator{
.goods_name{
font-weight: bolder;
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
.goods_price_warp{
display: flex;
justify-content: space-between;
.goods_price{
color:var(--themeColor);
font-size:34rpx;
}
.cart_num_tool{
display: flex;
.goods_num{
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
}
}
.footer_tool{
display: flex;
width: 100%;
height: 90rpx;
background-color: #fff;
border-top: 1px solid #ccc;
position: fixed;
bottom: 0;
left: 0;
padding-left: 30rpx;
.total_price_wrap{
flex:5;
display: flex;
align-items: center;
.total_price{
.total_price_text{
color:var(--themeColor);
font-size: 34rpx;
font-weight: bold;
}
}
}
.order_pay_wrap{
flex:3;
display: flex;
justify-content: center;
align-items: center;
background-image: linear-gradient(90deg,#FF740B,#FE6227);
margin: 10rpx;
color:#fff;
font-weight: 600;
font-size: 32rpx;
border-radius: 20px;
}
}
</style>

@ -1,87 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<div>订单号: {{ orderId }}</div>
<div v-for="(service, index) in services" :key="service.gid" class="service-box">
<p>{{ service.nickname }}</p>
<p>{{ service.endDate }}</p>
<!-- 添加一个按钮并绑定 click 事件处理器 sendServiceId -->
<button @click="sendServiceId(service.gid)"></button>
</div>
</Layout>
</template>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
props: ['orderId'],
components: {
Layout,
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
services: [],
title: '导游申请',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
methods: {
async sendServiceId(gid) {
try {
// APIgiddidPOST
const orderIdAsInt = parseInt(this.orderId, 10);
const gidAsInt = parseInt(gid, 10);
const response = await axios.post('/serve/DemandMatch/confirmed', { did:orderIdAsInt,gid:gidAsInt});
alert('已同意');
} catch (error) {
console.error('Error sending service ID and order ID:', error);
}
}
},
async created() {
//
axios.get(`/serve/DemandMatch/confirmedPage?did=${this.orderId}`)
.then(response => {
this.services = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
};
</script>
<style scoped>
/* 样式代码,定义 .service-box 的样式 */
/* 为按钮添加一些样式 */
.service-box button {
margin-left: auto; /* 将按钮推到右侧 */
}
/* 为按钮添加一些样式 */
.service-box button {
margin-left: auto; /* 将按钮推到右侧 */
}
.service-box {
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
/* 其他样式 */
}
</style>

@ -1,146 +0,0 @@
<script setup>
</script>
<template>
<view class="order">
<!-- 背景图片 -->
<view class="background">
<image src="../../static/background/background.jfif"></image>
</view>
<!-- 订单列表 -->
<view class="order_item" v-for="(item,index) in orderList" :key="item.supplier_order_id" @click="navToOrderDetail(item.supplier_order_id)">
<view class="shop"> <!-- 商铺名称 -->
<image src="../../static/order-icon/shop.png"></image>
<view class="shop_name">{{item.super_user_name}}</view>
</view>
<view class="order_info"> <!-- 商铺信息 -->
<view>联系电话{{item.super_phone}}</view>
<view>联系地址{{item.super_address}}</view>
<view>订单时间{{item.supplier_order_createdate | formatDate}}</view>
<view v-if="orderList[index].supplier_goods_price">{{item.supplier_goods_price}}</view>
<view v-if="orderList[index].supplier_goods_amount">{{item.supplier_goods_amount}}</view>
</view>
<view class="line"></view> <!-- 分割线 -->
</view>
</view>
</template>```
```javascript
<script>
export default {
data() {
return {
//
orderList: [],
}
},
methods: {
//
async getOrder() {
const res = await this.$myRequest({
url: '/order/getOrderBySupplierId',
method: 'POST',
data: JSON.stringify({
supplier_id: uni.getStorageSync('supplier_id')
})
})
this.orderList = res.data.data
//
for(let i=0;i<this.orderList.length;i++) {
//
let res2 = await this.$myRequest({
url: '/order/getSingleOrderBySupplierGoodsId',
method: 'POST',
data: JSON.stringify({
supplier_order_id: this.orderList[i].supplier_order_id
})
})
//
let orderDetail = res2.data.data
let order_all_price = 0
let order_all_amount = 0
for(let j=0;j<orderDetail.length;j++) {
order_all_price = order_all_price + orderDetail[j].supplier_goods_price * orderDetail[j].supplier_goods_amount
order_all_amount = order_all_amount + orderDetail[j].supplier_goods_amount
}
this.orderList[i].supplier_goods_price = order_all_price
this.orderList[i].supplier_goods_amount = order_all_amount
}
},
//
navToOrderDetail(supplier_order_id) {
uni.navigateTo({
url: '/pages/order/order-detail?supplier_order_id='+supplier_order_id
})
},
//
onPullDownRefresh() {
setTimeout(()=>{
this.getOrder(()=>{
uni.stopPullDownRefresh()
})
}, 500)
}
},
//
onLoad() {
//
this.getOrder()
}
}
</script>
<style lang="scss">
.order {
.background { //
image {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
}
}
.order_item {
background-color: white;
.shop { //
display: flex;
padding: 10rpx 30rpx 0 30rpx;
image { //
padding: 5rpx 15rpx 0 0;
width: 60rpx;
height: 60rpx;
}
.shop_name { //
font-size: 45rpx;
line-height: 70rpx;
}
}
.order_info { //
color: #555555;
padding: 0 30rpx 10rpx 30rpx;
font-size: 35rpx;
line-height: 60rpx;
}
.line { // 线
width: 750rpx;
height: 8rpx;
background: #eee;
}
}
}
</style>

@ -1,232 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<Layout :title="title" :links="computedLinks">
<div class="profile-container">
<div class="profile-background">
</div>
<div class="profile-content">
<h2>个人信息</h2>
<div class="form-group">
<label>昵称</label>
<div class="form-controls">
<input v-if="showNicknameInput" type="text" v-model="nickname" class="input-field editable-input">
<p v-else class="info-text">{{ user.nickname }}</p>
<button @click="showNicknameInput ? updateNickname() : toggleNicknameInput()" class="button">{{ showNicknameInput ? '保存' : '更换' }}</button>
</div>
</div>
<div class="form-group">
<label>邮箱</label>
<div class="form-controls">
<input v-if="showEmailInput" type="email" v-model="email" class="input-field editable-input">
<p v-else class="info-text">{{ user.email }}</p>
<button @click="showEmailInput ? updateEmail() : toggleEmailInput()" class="button">{{ showEmailInput ? '保存' : '更换' }}</button>
</div>
</div>
<div class="form-group">
<label>手机号</label>
<div class="form-controls">
<input v-if="showPhoneInput" type="tel" v-model="phone" class="input-field editable-input">
<p v-else class="info-text">{{ user.phone }}</p>
<button @click="showPhoneInput ? updatePhone() : togglePhoneInput()" class="button">{{ showPhoneInput ? '保存' : '更换' }}</button>
</div>
</div>
<div class="action-buttons">
<button @click="gotoLogin" class="button">退出登陆</button>
</div>
<div><NavigationBar /></div>
</div>
</div>
</Layout>
</Layout>
</template>
<style scoped>
.profile h2 {
text-align: center;
margin-bottom: 20px;
}
.profile p {
margin-bottom: 10px;
font-size: 16px;
}
.editable-input {
width: 200px; /* 设置一个具体的宽度 */
margin: 0 auto; /* 上下外边距为0左右外边距自动以在父容器中居中 */
}
.form-group {
display: flex;
align-items: center;
margin-bottom: 15px; /* 调整组之间的间距 */
}
.form-group label {
flex: 0 0 100px; /* 固定标签宽度,可根据需要调整 */
}
.form-controls {
display: flex;
flex: 1;
justify-content: center; /* 使输入框和按钮之间有空间 */
align-items: center; /* 垂直居中 */
}
.form-controls .info-text {
flex: 1; /* 输入框或文本占据剩余空间 */
margin-right: 10px; /* 与按钮之间的间距 */
}
input[type="text"], textarea {
width: 100%;
padding: 8px;
margin-bottom: 5px;
border: 1px solid #ccc;
border-radius: 3px;
}
button {
padding: 10px 20px;
background-color: #28a7a3;
color: white;
border: none;
border-radius: 7px;
cursor: pointer;
}
button:hover {
background-color: #28a7a3;
}
label {
display: block;
margin-bottom: 5px;
}
</style>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
name: 'MinePage',
components: {
Layout
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
title: '个人信息',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
nickname:'',
showNicknameInput: false,
email: '',
showEmailInput: false,
showPhoneInput: false,
idcard: '',
createtime: '',
status: 0,
reputation:60,
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serveList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
mounted() {
this.fetchUser(this.phone);
},
methods: {
fetchUser(phone) {
// API
axios.get(`/serve/users/getByPhone?phone=${phone}`)
.then(response => {
this.user = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
toggleNicknameInput(){
this.showNicknameInput = !this.showNicknameInput;
this.nickname = this.user.nickname;
},
updateNickname(){
this.user.nickname = this.nickname;
axios.post(`/serve/users/Pupdate`,{user:this.user})
.then(response => {
this.user.nickname = this.nickname;
this.toggleNicknameInput(); //
})
.catch(error => {
console.error('Error updating nickname:', error);
});
},
toggleEmailInput() {
this.showEmailInput = !this.showEmailInput;
this.email = this.user.email;//
},
updateEmail() {
//
this.user.email = this.email;
axios.post(`/serve/users/Pupdate`,{user:this.user})
.then(response => {
this.user.email = this.email;
this.toggleEmailInput(); //
})
.catch(error => {
console.error('Error updating email:', error);
});
},
togglePhoneInput(){
this.showPhoneInput = !this.showPhoneInput;
this.phone = this.user.phone;
},
updatePhone(){
this.user.phone = this.phone;
axios.post(`/serve/users/Pupdate`,{user:this.user})
.then(response => {
sessionStorage.setItem('phone', this.phone);
this.user.phone = this.phone;
this.togglePhoneInput(); //
})
.catch(error => {
console.error('Error updating phone:', error);
});
},
gotoChangeInfomation(){
this.$router.push('/changeInformation');
},
gotohome() {
this.$router.push('/home');
},
gotomessage() {
this.$router.push('/message');
},
gotoDemandList() {
this.$router.push('/demandlist');
},
gotoServerList() {
this.$router.push('/serverlist');
},
gotoLogin() {
this.$router.push('/login');
sessionStorage.setItem('phone', '');
},
}
};
</script>

@ -1,264 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<div class="form-container">
<form class="order-form">
<div class="content-section">
<h1><i class="fas fa-map-marker-alt"></i> 订单详情</h1>
<p class="trip-info">目的地: {{ list.city }}</p>
<p class="trip-info">开始时间: {{ list.departureDate }}</p>
<p class="trip-info">结束时间: {{ list.endDate }}</p>
<p class="trip-info">创建时间: {{ list.createTime }}</p>
<p class="trip-info">订单号: {{ list.did }}</p>
<p class="trip-info">备注: {{ list.message }}</p>
<p class="status-info">
当前状态:
<span v-if="list.status === 0" class="matching"></span>
<span v-else-if="list.status === 1" class="processing">处理中</span> <!-- 修改了状态文本以区分状态1 -->
<span v-else-if="list.status === 2" class="success">匹配成功</span>
<span v-else-if="list.status === 3" class="completed">已完成</span>
<span v-else class="unknown">未知状态</span>
</p>
<div v-if="list.status === 0 || list.status === 1">
<button class="action-button" @click="goToMatchDetail(orderId)"></button>
<button class="action-button" @click="goToDemandMatched(orderId)"></button>
<button class="action-button cancel-button" @click="cancelTrip(orderId)"></button>
</div>
<div v-if="list.status === 2">
<button class="action-button cancel-button" @click="cancel(orderId)"></button>
<button class="action-button complete-button" @click="over(orderId)"></button>
</div>
<div v-if="list.status === 3">
<button class="action-button" @click="goToEvaluateTrip(orderId)"></button>
<button class="action-button cancel-button" @click="deleteOrder(orderId)"></button>
</div>
</div>
</form>
</div>
</Layout>
</template>
<style scoped>
/* 基本布局和间距 */
.content-section {
display: flex;
flex-direction: column;
align-items: flex-start;
border: 1px solid #ddd;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
line-height: 1.6;
}
.trip-info {
margin-bottom: 15px;
}
/* 标题和图标样式 */
h1 {
font-size: 36px; /* or any size you prefer */
}
/* 按钮样式 */
.action-button {
background-color: #007bff;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.3s;
}
.action-button:hover {
background-color: #0056b3;
}
.cancel-button, .delete-button {
background-color: #dc3545;
}
.cancel-button:hover, .delete-button:hover {
background-color: #c82333;
}
.complete-button {
background-color: #28a745;
}
.complete-button:hover {
background-color: #218838;
}
/* 状态文本样式 */
.status-info span {
margin-right: 15px;
padding: 5px 10px;
border-radius: 4px;
}
.matching {
background-color: #ffc107;
color: #212529;
}
.processing {
background-color: #007bff;
color: white;
}
.success {
background-color: #28a745;
color: white;
}
.completed {
background-color: #17a2b8;
color: white;
}
.unknown {
background-color: #6c757d;
color: white;
}
/* 放大字体 */
.content-section, .trip-info, .status-info span, .action-button {
font-size: 18px;
}
.content-section {
display: flex;
flex-direction: column;
justify-content: flex-start; /* align items at the start (top) */
align-items: center;
min-height: 100vh;
line-height: 1.6;
}
.form-container {
width: 50%;
margin: 0 auto; /* Center the container horizontally */
background-color: #fff; /* White background color */
padding: 20px; /* Add some padding around the form */
}
.order-form {
width: 100%; /* Make the form occupy 100% of the container's width */
}
</style>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
props: ['orderId'],
components: {
Layout,
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
list: [],
title: '订单详情',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
async created() {
//
axios.get(`/serve/SendDemand/demand?did=${this.orderId}`)
.then(response => {
this.list = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
methods: {
goToMatchDetail(orderId) {
this.$router.push({ name: 'MatchDetail', params: { orderId } });
},
goToDemandMatched(orderId) {
this.$router.push({ name: 'DemandMatched', params: { orderId } });
},
goToEvaluateTrip(orderId) {
this.$router.push({ name: 'Evaluation', params: { orderId } });
},
cancel(orderId) {
const did = parseInt(this.orderId, 10);
axios.post(`/serve/DemandMatch/refuse`,{did:did})
.then(response => {
if(response.data == 1){
alert('取消成功');
location.reload();
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
cancelTrip(orderId) {
const did = parseInt(this.orderId, 10);
axios.post(`/serve/demands/delbyid`,{did:did})
.then(response => {
if(response.data == 1){
alert('取消成功');
this.$router.push('/demandlist');
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
over(orderId) {
const did = parseInt(this.orderId, 10);
axios.post(`/serve/DemandMatch/finish`,{did:did})
.then(response => {
if(response.data == 1){
location.reload();
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
deleteOrder(orderId) {
const did = parseInt(this.orderId, 10);
axios.post(`/serve/DemandMatch/delete`,{did:did})
.then(response => {
if(response.data == 1){
alert('删除成功');
this.$router.push('/demandlist');
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
returnList() {
this.$router.push('/demandlist');
}
}
};
</script>

@ -1,220 +0,0 @@
<template>
<Layout :title="title" class="title" :links="computedLinks">
<div class="container">
<div class="form-group">
<label for="experience">有无相关经历:</label>
<!-- 单选按钮组使用flex布局在同一行显示并居中 -->
<div class="radio-group">
<div class="radio-label">
<input type="radio" id="has-experience-yes" value="true" v-model="registerToGuide.re" required>
<label for="has-experience-yes"></label>
</div>
<div class="radio-label">
<input type="radio" id="has-experience-no" value="false" v-model="registerToGuide.re">
<label for="has-experience-no"></label>
</div>
</div>
</div>
<div class="form-group">
<label for="rsd">居住地区:</label>
<input type="text" id="rsd" v-model="registerToGuide.rsd">
</div>
<div class="form-group">
<label for="familiar-area">熟悉区域:</label>
<textarea id="familiar-area" v-model="registerToGuide.fa"></textarea>
</div>
<div class="form-group">
<label for="syns">个人简介:</label>
<textarea id="syns" v-model="registerToGuide.syns"></textarea>
</div>
<button @click="Submit()"></button>
</div>
</Layout>
</template>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue'
export default {
name: 'ApplyGuide',
data() {
return {
phone: sessionStorage.getItem('phone') || '',
title: '导游资格申请',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' }, { name: '历史出行', path: '/demandList' }],
user: {
role: 'member',
},
registerToGuide: {
uid: 0,
re: '',
rsd: '',
fa: '',
syns: '',
},
};
},
computed: {
computedLinks() {
return this.user.role === 'admin'
? this.links.concat([{ name: '服务发布', path: '/addServe' }, { name: '导游记录', path: '/serveList' }])
: this.links.concat([{ name: '注册导游', path: '/registerGuide' }]);
},
},
mounted() {
this.fetchUser(this.phone);
},
methods: {
fetchUser(phone) {
axios.get(`/serve/users/getByPhone?phone=${phone}`)
.then(response => {
this.user = response.data;
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
Submit() {
axios.get(`/serve/users/getUid?phone=${this.phone}`)
.then(response => {
this.registerToGuide.uid = response.data;
axios.post(`/serve/users/registerToGuide`, { registerToGuide: this.registerToGuide })
.then(response => {
if (response.data == 1) {
alert("申请成功!");
this.$router.push('/addServe');
} else {
alert("申请未通过!");
}
})
.catch(error => {
console.error('Error posting registration:', error);
});
})
.catch(error => {
console.error('Error fetching user UID:', error);
});
},
},
components: {
Layout,
},
};
</script>
<style scoped>
.container {
background-color: rgba(255, 255, 255, 0.2);
}
/* 页面基础样式 */
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
color: #333;
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* 表单容器样式 */
form {
width: 100%;
height: 90vh;
padding: 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
}
/* 表单组样式 */
.form-group {
width: 100%;
margin-bottom: 20px;
}
/* 单选按钮组样式 */
.radio-group {
display: flex;
align-items: center;
justify-content: space-between; /* 使得单选按钮平均分布在父元素中 */
width: 10%;
margin: 0 auto;
}
/* 单选按钮样式 */
.radio-label {
display: flex;
align-items: center;
margin-right: 15px; /* 单选按钮之间的间距 */
}
input[type="radio"] {
margin-right: 8px;
}
/* 输入框、文本区域样式 */
input[type="text"],
textarea {
width: 60%;
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
margin-top: 5px; /* 调整输入框与标题的间距 */
}
/* 按钮样式 */
button {
width: 30%;
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
font-size: 18px;
cursor: pointer;
transition: background-color 0.3s ease;
margin-top: 20px;
background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);
}
button:hover {
background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);
}
label {
font-weight: bold; /* 标题加粗 */
font-size: 18px; /* 放大标题字体 */
margin-bottom: 10px; /* 标题与输入框之间的间距 */
}
/* 表单组样式调整 */
.form-group {
display: flex;
flex-direction: column;/* 标题和输入框左对齐 */
align-items: center;
width: 100%;
margin-bottom: 20px;
}
/* 单选按钮组样式调整 */
.radio-group {
width: 40%; /* 根据需要调整宽度 */
justify-content: space-around; /* 单选按钮均匀分布 */
}
/* 悬停效果、选中效果和错误信息样式保持不变 */
</style>

@ -1,74 +0,0 @@
<script>
import Return from '../components/return.vue'
export default {
name: 'SearchPage',
components: {
Return
},
}
</script>
<template>
<div class="home-container">
<div>
<Return></Return>
</div>
<div class="search-container">
<input type="text" class="search-input" placeholder="世界这么大出去看看吧">
<button class="search-button" @click="search"></button>
</div>
</div>
</template>
<style scoped>
.search-container {
/* 定义搜索框容器的样式 */
text-align: center;
/* 使用margin-top来确保搜索框在返回按钮下方20px */
margin-top: 50px; /* 假设返回按钮的高度是30px10px padding * 2 + 10px height再加上20px的间距 */
margin-bottom: 20px; /* 根据需要添加一些底部间距 */
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中(如果不需要完全居中,可以去掉这个)*/
}
.search-input {
/* 定义搜索框的样式 */
flex: 1; /* 占据剩余空间 */
padding: 15px;
border-radius: 5px;
border: 1px solid #ccc;
}
.search-button {
margin-left: 10px; /* 与搜索框之间的间距 */
padding: 10px 20px;
border: none;
border-radius: 5px;
background-color: #ccc;
color: #333;
cursor: pointer;
}
.search-button:hover {
/* 搜索按钮点击时的样式 */
background-color: #bbb;
}
.footer-nav button {
/* 定义按钮的样式 */
flex: 1;
border: none;
padding: 10px;
background-color: #ccc;
color: #333;
cursor: pointer;
}
.footer-nav button:hover {
/* 按钮点击时的样式 */
background-color: #bbb;
}
</style>

@ -1,153 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<h1>订单</h1>
<div class="server-details">
<h2>订单详情</h2>
<p>目的地: {{ list.city }}</p>
<p>开始时间: {{ list.departureDate }}</p>
<p>结束时间: {{ list.endDate }}</p>
<p>创建时间: {{ list.createTime }}</p>
<p>备注: {{ list.message }}</p>
<p>当前状态:
<span v-if="list.status === 0"></span>
<span v-else-if="list.status === 1">匹配中</span>
<span v-else-if="list.status === 2">匹配成功</span>
<span v-else-if="list.status === 3">已完成</span>
<span v-else></span>
</p>
<div>
<button v-if="list.status === 0" @click="goToServerMatch(serverId)"></button>
<button v-if="list.status === 1" @click="goToServerMatch(serverId)"></button>
</div>
<div>
<button v-if="list.status === 0" @click="goToServerMatched(serverId)"></button>
<button v-if="list.status === 1" @click="goToServerMatched(serverId)"></button>
</div>
<div>
<button v-if="list.status === 0" @click="cancelTrip(serverId)"></button>
<button v-if="list.status === 1" @click="cancelTrip(serverId)"></button>
</div>
<div>
<button v-if="list.status === 2" @click="cancel(serverId)"></button>
</div>
<div>
<button v-if="list.status === 3" @click="deleteOrder(serverId)"></button>
</div>
</div>
</Layout>
</template>
<style scoped>
.returnList {
/* 定义返回按钮的样式 */
position: fixed; /* 使按钮位置固定 */
top: 10px;
left: 10px;
margin: 0;
padding: 10px 20px;
border: none;
border-radius: 5px;
background-color: #ccc;
color: #333;
cursor: pointer;
}
.returnList:hover {
background-color: #aaaaaa;
}
</style>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue'
export default {
props: ['serverId'],
components: {
Layout,
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
list: [],
title: '订单详情',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
async created() {
//
axios.get(`/serve/users/getByPhone?phone=${this.phone}`)
.then(response => {
this.user = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
axios.get(`/serve/guideService/findbyid?gid=${this.serverId}`)
.then(response => {
this.list = response.data
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
methods: {
goToServerMatch(serverId) {
this.$router.push({ name: 'ServerMatch', params: { serverId } });
},
goToServerMatched(serverId) {
this.$router.push({ name: 'ServerMatched', params: { serverId } });
},
cancel(serverId) {
const gid = parseInt(this.serverId, 10);
axios.post(`/serve/GuideMatch/refuse`,{gid:gid})
.then(response => {
if(response.data == 1){
alert('取消成功');
location.reload();
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
cancelTrip(serverId) {
const gid = parseInt(this.serverId, 10);
axios.post(`/serve/guideService/delbyid`,{gid:gid})
.then(response => {
if(response.data == 1){
alert('取消成功');
this.$router.push('/serverList')
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
deleteOrder(serverId) {
const gid = parseInt(this.serverId, 10);
axios.post(`/serve/GuideMatch/delete`,{gid:gid})
.then(response => {
if(response.data == 1){
alert('删除成功');
this.$router.push('/serverList')
}
})
.catch(error => {
console.error('Error fetching user:', error);
});
},
}
};
</script>

@ -1,128 +0,0 @@
<template>
<Layout :title="title" :links="computedLinks">
<div class="order-container">
<div
v-for="(list, index) in lists"
:key="list.gid"
class="order-card"
@click="goToServerDetails(list.gid)"
>
<div class="order-header">
<h3>{{ list.city }}</h3>
</div>
<div class="order-body">
<p>开始时间: {{ list.departureDate }}</p>
<p>结束时间: {{ list.endDate }}</p>
</div>
</div>
</div>
</Layout>
</template>
<script>
import axios from 'axios';
import Layout from '../components/Layout.vue';
export default {
components: {
Layout
},
data() {
return {
phone: sessionStorage.getItem('phone') || '',
lists: [],
title: '导游记录',
links: [{ name: '首页', path: '/home' }, { name: '个人信息', path: '/mine' }, { name: '添加出行', path: '/addDemandPage' },{ name: '历史出行', path: '/demandList' }],
user: {
},
};
},
async created() {
//
try {
const response = await axios.get(`/serve/SendGuideService/sendAllGuideService?phone=${this.phone}`);
this.lists = response.data;
} catch (error) {
console.error('Error fetching guide services:', error.response || error.message);
}
try {
const response = await axios.get(`/serve/users/getByPhone?phone=${this.phone}`);
this.user = response.data;
} catch (error) {
console.error('Error fetching user data:', error.response || error.message);
}
},
computed: {
computedLinks() {
//
return this.user.membertype === true
? this.links.concat([{ name: '服务发布', path: '/addServe' },{ name: '导游记录', path: '/serverList' }])
: this.links.concat([{name:'注册导游',path:'/registerGuide'}]);
}
},
methods: {
goToServerDetails(serverId) {
this.$router.push({ name: 'ServerDetail', params: { serverId } });
}
}
};
</script>
<style scoped>
.trip-info p {
margin: 8px 0;
font-size: 16px;
color: #333;
}
/* 订单容器样式 */
.order-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 20px;
}
/* 订单卡片样式 */
.order-card {
border: 1px solid #eaeaea;
border-radius: 10px;
margin: 10px;
padding: 20px;
background-color: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: calc(33% - 40px);
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
}
.order-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
/* 订单头部和内容样式 */
.order-header h3 {
margin: 0 0 10px;
font-size: 20px;
color: #007BFF;
}
.order-body {
font-size: 14px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.order-card {
width: calc(50% - 40px);
}
}
@media (max-width: 480px) {
.order-card {
width: 100%;
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save