# TourGuide 基础框架 基于 JDK 8、Spring Boot、MyBatis-Plus、MySQL、Redis、JWT、Vue 3 和 Node.js 24.1.0 的旅游平台基础工程。 ## 架构决策 后端采用一个可部署应用,基础设施统一维护,业务接口按客户端边界隔离。这样可以避免早期拆成多个服务造成重复配置,同时保留未来按模块拆分的清晰边界。 | 客户端 | 用户表 | Token 类型 | 接口前缀 | 权限标识 | | --- | --- | --- | --- | --- | | 管理后台 | `sys_admin_user` | `ADMIN` | `/api/admin/**` | `ADMIN` | | 游客小程序 | `mini_user` | `MINI` | `/api/mini/**` | `MINI_USER` | | 导游端 | `guide_user` | `GUIDE` | `/api/guide/**` | `GUIDE_USER` | JWT 包含 `clientType` 声明,Redis 会话 Key 同时包含客户端类型和 Token ID。请求进入过滤器后会先比较接口前缀和 `clientType`,再查询对应用户表;不匹配时直接返回 `401`,不会回退查询其他端用户表。 ## 目录说明 ```text TourGuide/ ├─ backend/ Spring Boot 后端 │ ├─ db/schema.sql tour_guide 数据库初始化脚本 │ └─ src/main/java/ │ ├─ api/admin/ 管理后台接口 │ ├─ api/mini/ 游客小程序接口 │ ├─ api/guide/ 导游端接口 │ ├─ modules/user/ 三端独立用户模型与服务 │ └─ security/ JWT、Redis 会话、分端校验 └─ frontend/ Vue 3 管理后台框架 └─ src/views/ 可替换的原型页面占位 ``` ## 本地启动步骤 ### 1. 初始化数据库 - 目的:创建 `tour_guide` 数据库和三端独立用户表。 - 操作:在 MySQL 8 中执行 `backend/db/schema.sql`。 - 影响范围:创建 `sys_role`、`sys_admin_user`、`mini_user`、`guide_user`;不会删除已有表。 - 验证:执行 `USE tour_guide; SHOW TABLES;`,应显示三端用户表以及后台基础表。 - 注意:默认数据库账号为 `root/root`,可通过环境变量覆盖。 已有 `tour_guide` 数据库时,不要重新执行完整建库脚本。请在备份后执行一次导游管理增量脚本: ```powershell mysql -u root -p < backend/db/upgrade-guide-management.sql ``` 该脚本会扩展 `guide_user` 字段,并创建 `guide_team`、`guide_scenic_config`、`guide_auto_disable_config`,不会删除现有导游数据。脚本仅用于升级一次,重复执行其中的 `ALTER TABLE` 会因字段已存在而失败。 若本机 MySQL 密码与默认配置不同,可运行安全初始化脚本。密码通过隐藏输入读取,不会写入项目文件: ```powershell & "backend/db/init-local.ps1" ``` 已执行过旧版数据库脚本的环境,需依次执行 `backend/db/upgrade-guide-team-management.sql`、`backend/db/upgrade-guide-team-detail.sql` 和 `backend/db/upgrade-order-management.sql`,补充讲解队配置与订单表。 评价管理增量脚本生成于 `2026-07-28 10:02:13 +08:00`: ```powershell mysql -u root -p < backend/db/20260728_100213_upgrade_review_management.sql ``` 执行后可查询迁移版本和首次执行时间,判断当前数据库是否已经升级: ```sql SELECT `version`, `description`, `applied_at` FROM `sys_schema_migration` WHERE `version` = '20260728_100213_REVIEW_MANAGEMENT'; ``` 反馈管理增量脚本同时支持游客反馈与导游反馈,已有数据库执行: ```powershell mysql -u root -p < backend/db/migrations/20260728_120000_create_feedback_management.sql ``` 执行后通过迁移版本 `20260728_120000_FEEDBACK_MANAGEMENT` 验证,并确认 `user_feedback` 表已创建。 订单详情页新增商品快照、支付时间线、服务节点和退款凭证字段,已有数据库需执行一次: ```powershell mysql -u root -p < backend/db/migrations/20260728_140000_upgrade_order_detail.sql ``` 执行后可通过迁移版本 `20260728_140000_ORDER_DETAIL` 验证升级结果。 ### 2. 启动 Redis - 目的:保存登录会话并支持 Token 主动失效。 - 操作:启动本地 Redis,默认地址 `127.0.0.1:6379`,数据库索引为 `0`。 - 影响范围:会写入 `tourguide:auth:session:{客户端类型}:{tokenId}` 格式的 Key。 - 验证:登录后执行 `KEYS tourguide:auth:session:*` 可看到对应端会话。 - 注意:Redis 不可用时登录和鉴权会失败,避免 JWT 在服务端无法主动失效。 ### 3. 启动后端 ```powershell cd "backend" mvn spring-boot:run ``` - 目的:启动三端统一后端应用。 - 操作:应用连接本地 `tour_guide` 和 Redis,并在首次启动时创建管理员。 - 影响范围:默认监听 `8080` 端口。 - 验证:访问 `GET /api/health`,应返回 `status=UP`。 - 注意:默认管理员为 `admin / Admin@123456`,仅用于本地开发;部署前必须修改。 可用环境变量: ```text MYSQL_URL MYSQL_USERNAME MYSQL_PASSWORD REDIS_HOST REDIS_PORT REDIS_PASSWORD REDIS_DATABASE JWT_SECRET BOOTSTRAP_ADMIN_USERNAME BOOTSTRAP_ADMIN_PASSWORD WECHAT_APPID WECHAT_APP_SECRET WECHAT_CONNECT_TIMEOUT_MILLIS WECHAT_READ_TIMEOUT_MILLIS UNIPUSH_ENABLED UNIPUSH_APP_ID UNIPUSH_APP_KEY UNIPUSH_MASTER_SECRET UNIPUSH_SERVICE_REMINDER_MINUTES ``` `JWT_SECRET` 至少使用 32 字节随机字符串。 微信小程序手机号授权登录使用 `WECHAT_APPID` 和 `WECHAT_APP_SECRET`。AppSecret 只能通过后端运行环境注入,禁止写入 `application.yml`、小程序源码或提交到版本库。 PowerShell 本地启动示例: ```powershell $env:WECHAT_APPID='<微信小程序 AppID>' $env:WECHAT_APP_SECRET='<微信小程序 AppSecret>' cd "backend" mvn spring-boot:run ``` 小程序登录接口为 `POST /api/mini/auth/wechat-phone-login`。小程序先通过 `uni.login` 获取 `loginCode`,再将手机号授权事件返回的 `phoneCode` 一并提交后端;后端完成微信身份校验后签发 `MINI` JWT。 微信登录排障: - `WECHAT_APPID`、`WECHAT_APP_SECRET` 必须配置在后端启动进程环境变量中,修改后需要重启 Spring Boot。 - `微信小程序登录配置未完成`:启动进程未读取到环境变量。 - `AppID 或 AppSecret 配置错误`:检查小程序主体、AppID、AppSecret 是否属于同一个小程序,并重新生成已泄露的密钥。 - `微信登录凭证无效`:`uni.login` 返回的 code 已使用或过期,需要重新调用 `uni.login`。 - `微信登录服务暂不可用`:查看后端错误日志中的 `调用微信 GET 接口失败`,确认代理、TLS、DNS 或连接超时原因。 UniPush 导游端推送启用步骤: 1. 在 DCloud 开发者后台为导游端应用 `__UNI__F7E10FB` 开通 UniPush,并在 HBuilderX 云端打包配置中完成 Android/iOS 厂商通道配置。 2. 执行 `backend/db/migrate-local.ps1`,应用迁移 `20260803_100000_INTEGRATE_UNIPUSH`。 3. 后端运行环境配置 `UNIPUSH_ENABLED=true`、`UNIPUSH_APP_ID`、`UNIPUSH_APP_KEY`、`UNIPUSH_MASTER_SECRET`。 4. `UNIPUSH_SERVICE_REMINDER_MINUTES` 控制服务开始前提醒分钟数,默认值为 `10`。 导游登录或应用启动后会调用 `PUT /api/guide/push-device` 上报当前 CID;退出登录或注销账号时调用 `DELETE /api/guide/push-device` 解绑,避免旧设备继续接收订单通知。 ### 后台基础表 `backend/db/schema.sql` 已包含以下后台基础表,并为每张表和每个字段添加中文备注: - `sys_role`:后台角色 - `sys_admin_user`:后台账号 - `sys_dept`:部门组织 - `sys_post`:岗位 - `sys_menu`:菜单与权限标识 - `sys_role_menu`:角色菜单关系 - `sys_admin_user_post`:后台用户岗位关系 - `sys_dict_type`、`sys_dict_data`:系统字典 - `sys_config`:参数配置 - `sys_notice`:通知公告 - `sys_login_log`:登录日志 - `sys_operation_log`:操作日志 脚本内置 `ADMIN` 角色、系统根部门、管理员岗位、系统管理菜单、通用状态字典和基础参数。所有初始化语句均按唯一键或存在性判断设计,可以重复执行,不会主动删除已有数据。 ### 4. 启动前端 ```powershell cd "frontend" npm install npm run dev ``` - 目的:启动 Vue 3 管理后台框架。 - 操作:Vite 使用 `Node.js 24.1.0`,开发服务监听 `5173` 并代理 `/api` 到后端 `8080`。 - 影响范围:后台 Token 仅保存于浏览器 `admin_token`,不会读取其他端 Token。 - 验证:打开 `http://127.0.0.1:5173`,使用初始化管理员登录。 - 注意:现有业务页面是原型占位,后续可以直接替换 `frontend/src/views/` 中对应组件。 ## 已提供接口 ### 管理后台 - `POST /api/admin/auth/login`:后台登录 - `POST /api/admin/auth/logout`:后台退出 - `GET /api/admin/auth/me`:当前后台用户 - `GET/POST/PUT/DELETE /api/admin/users`:后台账号管理 - `GET /api/admin/mini-users`:小程序用户分页 - `PUT /api/admin/mini-users/{id}/status`:停启小程序用户 - `GET/POST /api/admin/guide-users`:导游账号查询和创建 - `PUT /api/admin/guide-users/{id}/status`:停启导游账号 - `GET/POST /api/admin/guide-teams`:讲解队分页查询和新建 - `GET /api/admin/guide-teams/{id}`:查询讲解队详情及景区配置 - `PUT /api/admin/guide-teams/{id}`:编辑讲解队 - `PUT /api/admin/guide-teams/{id}/status`:停启讲解队 - `GET /api/admin/orders`:订单分页查询,支持游客、导游、景区、状态和时间筛选 - `GET /api/admin/reviews`:按订单、游客、导游、评分、景区和时间分页查询评价 - `GET /api/admin/reviews/scenic-options`:查询评价景区筛选项 - `DELETE /api/admin/reviews/{id}`:逻辑删除评价并重新计算导游评分 - `GET /api/admin/orders/{id}`:查询订单详情 - `GET /api/admin/orders/scenic-options`:查询订单景区筛选项 - `PUT /api/admin/orders/{id}/refund`:执行订单退款 ### 游客小程序 - `POST /api/mini/auth/wechat-phone-login`:微信小程序手机号授权登录 - `POST /api/mini/auth/logout`:小程序用户退出 - `DELETE /api/mini/auth/account`:匿名化并逻辑删除当前游客账号,存在未完成订单时拒绝注销 - `GET /api/mini/profile`:回显当前登录游客资料和实名状态 - `PUT /api/mini/profile`:修改当前游客昵称 - `POST /api/mini/profile/avatar`:上传并修改当前游客头像 - `PUT /api/mini/profile/real-name`:填写或更新真实姓名,非空即视为已实名 - `POST /api/mini/reviews`:为本人已完成订单提交评价 ### 逻辑删除规范 - 除技术迁移表 `sys_schema_migration` 外,所有业务表统一使用 `deleted` 字段:`0` 正常、`1` 删除。 - MyBatis-Plus 实体统一启用逻辑删除,`deleteById` 和条件删除只更新删除标识,不执行物理删除。 - 角色权限、景区价格、汇合点和导游景区等关联配置采用“逻辑删除旧配置 + Upsert 恢复或覆盖”,避免唯一键冲突。 - 游客注销会匿名化手机号、OpenID、昵称、头像和实名信息,再逻辑删除账号;历史订单不物理删除。 ### 导游端 - `POST /api/guide/auth/login`:导游登录 - `POST /api/guide/auth/logout`:导游退出 - `GET/PUT /api/guide/profile`:导游本人资料 ## 验证命令 ```powershell cd "backend" mvn test cd "../frontend" npm run build ``` 后端测试包含三类 JWT `clientType` 声明校验;前端构建用于验证路由、组件和请求层可以正常打包。