Compare commits

...

153 Commits

Author SHA1 Message Date
zhanglinhao 547b61315e 最终ppt
2 years ago
zhanglinhao b6b7400b9b 更新ppt
2 years ago
zhanglinhao 91c51c5fbd 修改ppt
2 years ago
zhanglinhao bbc5dc4227 更新文档和ppt
2 years ago
zhanglinhao 89c2fba28a 最新后端代码
2 years ago
zhanglinhao bfa49ec0eb 修复后端代码
2 years ago
zhanglinhao 5fdb68fa9c 上传宣传视频
2 years ago
zhanglinhao db3b54eac6 Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zcx bbba1c5420 最新版
2 years ago
zhanglinhao 79b858112b Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zhanglinhao c5a815b054 更新后端代码
2 years ago
zcx 5a799f95c5 设计文档
2 years ago
zhanglinhao bb9bad6335 Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zhanglinhao 02d678f8d8 更新ppt
2 years ago
zcx 92ff810b93 Merge branch 'master' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
zcx 52baa344c5 设计文档
2 years ago
zhanglinhao 1a0d65c725 Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zhanglinhao f72a51e34f 修改ppt
2 years ago
房孝庭 fbadcc2cae Merge branch 'master' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
房孝庭 2ee3d6f894 修改两个自评报告
2 years ago
zhanglinhao 7e6e07eb0e 更新模型
2 years ago
房孝庭 4aebe6d916 修改软件设计规格说明书
2 years ago
zcx 759274239b 自评报告
2 years ago
zcx 2c6cf04da8 Merge branch 'master' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
zcx 5ebd78ff3c 个人自评报告
2 years ago
zhanglinhao 642dceb244 提交ppt
2 years ago
zhanglinhao bf6cbe7dae 改图
2 years ago
zhanglinhao 5ec51aafa9 上传海报
2 years ago
zhanglinhao 5ba00916b6 Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zhanglinhao e2014de19e update
2 years ago
wuyifan 70ce44ad44 后端代码
2 years ago
wuyifan 04bdb19ec9 更新
2 years ago
wuyifan da67fe8884 回退
2 years ago
wuyifan 991b3c3b61 Revert "修改"
2 years ago
wuyifan 346e939e4f 修改
2 years ago
wuyifan 8299139603 代码修改
2 years ago
zhanglinhao 8b7bee7c1d 更新
2 years ago
zhanglinhao 510d8db779 更新自评报告
2 years ago
zhanglinhao f800550ada 更新自评报告
2 years ago
zhanglinhao 383a9111cd Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zhanglinhao a2373dffb3 提交自评报告
2 years ago
房孝庭 d5bdc148e5 Merge branch 'master' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
房孝庭 79475227ad 1
2 years ago
wuyifan 7e69ad3848 后端代码补充
2 years ago
zhanglinhao 8fb4fbcccc 删除多余代码
2 years ago
zhanglinhao 8e77ed74cb Merge branch 'master' of bdgit.educoder.net:mwxbgi697/softegg
2 years ago
zhanglinhao 512de5ad7d 重命名文档
2 years ago
房孝庭 6d63961541 1
2 years ago
a3197878436@163.com 9eb3a3a341 1
2 years ago
a3197878436@163.com 0fa783bd1b 1
2 years ago
a3197878436@163.com 6c75e5562f 1
2 years ago
a3197878436@163.com 3cdd46dd80 1
2 years ago
a3197878436@163.com 28a36bb26c 1
2 years ago
a3197878436@163.com 93177199db 1
2 years ago
a3197878436@163.com 28c47a51ca 1
2 years ago
a3197878436@163.com 7feccda1d0 1
2 years ago
15616168609 1d900ab370 1
2 years ago
15616168609 a6db9c05d6 Merge branch 'master' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
15616168609 2d2aabcbc3 1
2 years ago
mafc2zqui 3420b94b0c ADD file via upload
2 years ago
mafc2zqui 3f53a7e490 ADD file via upload
2 years ago
“fangxiaoting” 830dfe5e4a 前端代码
2 years ago
“fangxiaoting” bef6b8433e Merge branch 'master' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
“fangxiaoting” a6cfa1b58f 1
2 years ago
“fangxiaoting” 11ca1b0560 1
2 years ago
“fangxiaoting” 459b1e2d9d 1
2 years ago
“fangxiaoting” b61e1370f7 1
2 years ago
mafc2zqui aa86338860 Add 前端
2 years ago
“fangxiaoting” 78c8592922 删除原代码
2 years ago
mafc2zqui 6cc844c2d6 ADD file via upload
2 years ago
zhanglinhao 49bf7c57d7 提交张林浩的代码
2 years ago
zhanglinhao ad3e007dfa 删除旧版本代码
2 years ago
zcx 98079dcf40 文档修改
2 years ago
mwxbgi697 80f92e6114 Delete 'src/后端/src/main/java/com/softegg/freetogo/UsersController.java'
2 years ago
mwxbgi697 9f984bcffb Delete 'src/后端/src/main/java/com/softegg/freetogo/Users.java'
2 years ago
mwxbgi697 191c450657 Delete 'src/后端/src/main/java/com/softegg/freetogo/UserServiceImpl.java'
2 years ago
mwxbgi697 fd52484673 Delete 'src/后端/src/main/java/com/softegg/freetogo/UsersRepository.java'
2 years ago
mwxbgi697 c3a76e62be Delete 'src/后端/src/main/java/com/softegg/freetogo/UsersService.java'
2 years ago
mwxbgi697 a35a1f82f7 Delete 'src/后端/src/main/java/com/softegg/freetogo/Login.zip'
2 years ago
mwxbgi697 1d75cfe581 Merge pull request '更新文档' (#7) from develop into master
2 years ago
wyf 72aa962765 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
wyf 1795445995 设计规格说明书修改
2 years ago
mwxbgi697 f9889025cd Merge pull request '提交' (#6) from develop into master
2 years ago
zhanglinhao f7cb3048e2 Merge branch 'develop' of bdgit.educoder.net:mwxbgi697/softegg into develop
2 years ago
wyf a22d5754f6 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zhanglinhao a3776d3f47 Merge branch 'develop' of bdgit.educoder.net:mwxbgi697/softegg into develop
2 years ago
zhanglinhao c185cc9806 Merge remote-tracking branch 'remotes/origin/zhanglinhao_branch' into develop
2 years ago
zhanglinhao db50067cde 删除问题文件
2 years ago
“fangxiaoting” 1939e14ddf Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zhanglinhao b48d0f985f 文档修改
2 years ago
“fangxiaoting” 899117e4e5 Squashed commit of the following:
2 years ago
wyf f923540504 图和文档
2 years ago
zhanglinhao aefca9dbaf 更新代码
2 years ago
zhanglinhao 519f4f348f 上传后端代码
2 years ago
mafc2zqui b9e78fa06c Merge pull request '模型更新' (#5) from fangxiaoting_branch into develop
2 years ago
“fangxiaoting” 3d22404b47 模型更新
2 years ago
“fangxiaoting” b2e827c347 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into fangxiaoting_branch
2 years ago
“fangxiaoting” 0192f950dd 模型更新
2 years ago
zcx 83407bd3ba 修改
2 years ago
zcx 663435a581 修改
2 years ago
zcx 36fbc12d08 需求规格说明书修改
2 years ago
zcx 6bca593ec3 需求规格说明书修改
2 years ago
pq3fnjual 1c6b7d2a67 软件需求构思与描述
2 years ago
zcx 391a963ed1 软件需求规格说明书修改
2 years ago
zcx 980edec786 类图
2 years ago
zcx d94abd4c90 修改
2 years ago
zcx d7d86f5604 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zcx 8854944dea 用例图.png
2 years ago
wyf 333c3cb903 更新了顺序图
2 years ago
wyf 6239de4c68 顺序图更新
2 years ago
wyf 5030bb4164 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg
2 years ago
zcx 07210f5f0d Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zcx 4e53d8a46d 需求规格说明书修改
2 years ago
“fangxiaoting” 5f41da9cdf 添加顺序图
2 years ago
“fangxiaoting” 61157e1f2b Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into fangxiaoting_branch
2 years ago
zcx dd7398cb56 需求构思修改
2 years ago
zcx 2a1529af0a Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zcx 322d81a4b4 用例图.png
2 years ago
张林浩 5cfb29d3ae 新增用户注册分析类图
2 years ago
zcx 8b9957a08d Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zcx 44e573f056 通信系统顺序图修改
2 years ago
张林浩 66da63b0c6 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
wyf d2b8003ab9 顺序图更新
2 years ago
张林浩 8310fee972 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
wyf 0fa06c8a2f Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zcx 098be51ef0 部分修改
2 years ago
wyf c664e208b1 顺序图更新
2 years ago
张林浩 ee6b6ee082 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
张林浩 9088b86c8d 优化顺序图
2 years ago
zcx 7af78b9ccf 顺序图
2 years ago
张林浩 9e760becf3 新增导游方竞价顺序图
2 years ago
张林浩 82dc2d8ec1 优化行程评价顺序图
2 years ago
张林浩 998e72478d 新增行程评价顺序图
2 years ago
wyf cfe5662b2e 更新文档
2 years ago
张林浩 e63d703600 修复文档
2 years ago
张林浩 7517f39178 修复文档
2 years ago
“fangxiaoting” e20883fafc 修改需求规格说明书
2 years ago
“fangxiaoting” 484480fc7e 修改其他软件需求分析
2 years ago
“fangxiaoting” 9861c14130 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into fangxiaoting_branch
2 years ago
“fangxiaoting” e05dcd4a58 修改需求规格说明书
2 years ago
张林浩 7befbb7120 删除文档
2 years ago
zcx 523f1529e8 Squashed commit of the following:
2 years ago
zcx 9d34b69fe9 增加功能描述
2 years ago
zcx bf611d4c36 Merge branch 'develop' of https://bdgit.educoder.net/mwxbgi697/softegg into develop
2 years ago
zcx 7c1d5e4dd5 需求构思文档修改
2 years ago
mwxbgi697 1511bf0564 Merge pull request '部署图' (#2) from wuyifan_branch into develop
2 years ago
wyf b324431d35 新部署图
2 years ago
mwxbgi697 74496a1a04 Delete 'doc/文档模板-软件需求构思及描述模板.docx'
2 years ago
wyf 4ad789c9ce 修改部署图
2 years ago
wyf 465edd4cfe 修改了部署图
2 years ago
wyf 2400de4cfa 部署图更改
2 years ago
mwxbgi697 6c0d76f25e Merge pull request '文档优化' (#1) from zhanglinhao_branch into develop
2 years ago
zcx 56e818d922 Squashed commit of the following:
2 years ago

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

@ -0,0 +1,13 @@
[*]
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

@ -0,0 +1,30 @@
# 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

@ -0,0 +1,29 @@
# 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
```

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

@ -0,0 +1,13 @@
<!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>

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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,27 @@
{
"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.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,17 @@
<!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.

After

Width:  |  Height:  |  Size: 208 KiB

@ -0,0 +1,24 @@
<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>

@ -0,0 +1,11 @@
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)
}

@ -0,0 +1,86 @@
/* 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;
}

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 276 B

@ -0,0 +1,35 @@
@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;
}
}

@ -0,0 +1,16 @@
<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>

@ -0,0 +1,140 @@
<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>

@ -0,0 +1,67 @@
<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>

@ -0,0 +1,118 @@
<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>

@ -0,0 +1,27 @@
<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>

@ -0,0 +1,7 @@
<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>

@ -0,0 +1,7 @@
<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>

@ -0,0 +1,7 @@
<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>

@ -0,0 +1,7 @@
<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>

@ -0,0 +1,19 @@
<!-- 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>

@ -0,0 +1,70 @@
<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>

@ -0,0 +1,126 @@
<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>

@ -0,0 +1,45 @@
<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>

@ -0,0 +1,76 @@
<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>

@ -0,0 +1,6 @@
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.

After

Width:  |  Height:  |  Size: 787 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

@ -0,0 +1,18 @@
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');

@ -0,0 +1,167 @@
<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>

@ -0,0 +1,131 @@
<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>

@ -0,0 +1,112 @@
<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>

@ -0,0 +1,146 @@
<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>

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

@ -0,0 +1,94 @@
<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>

@ -0,0 +1,191 @@
<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>

@ -0,0 +1,158 @@
<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>

@ -0,0 +1,113 @@
<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>

@ -0,0 +1,195 @@
<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>

@ -0,0 +1,116 @@
<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>

@ -0,0 +1,223 @@
<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>

@ -0,0 +1,194 @@
<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>

@ -0,0 +1,131 @@
<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>

@ -0,0 +1,248 @@
<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>

@ -0,0 +1,87 @@
<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>

@ -0,0 +1,146 @@
<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>

@ -0,0 +1,232 @@
<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>

@ -0,0 +1,264 @@
<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>

@ -0,0 +1,220 @@
<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>

@ -0,0 +1,74 @@
<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>

@ -0,0 +1,153 @@
<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>

@ -0,0 +1,128 @@
<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