338 lines
12 KiB
Markdown
338 lines
12 KiB
Markdown
# 湖南12301文旅综合平台 — 第一迭代设计文档
|
||
|
||
**文档版本**:v1.0
|
||
**创建日期**:2026-06-13
|
||
**实现方案**:方案 A — 由底向上
|
||
|
||
---
|
||
|
||
## 一、迭代范围
|
||
|
||
第一迭代聚焦 **基础层搭建 + 用户端核心流程**,具体包含:
|
||
|
||
| 阶段 | 内容 |
|
||
|------|------|
|
||
| **Phase 1:基础层** | 分包目录、路由配置、API 层改造、Store 设计、环境配置、共享组件 |
|
||
| **Phase 2:用户端核心页面** | 首页、年卡列表/详情、确认购买、激活年卡、入园码 |
|
||
|
||
**不包含在第一迭代**:
|
||
- 管理端页面(卡管理、景区管理)→ 第二迭代
|
||
- H5 版本登录(OAuth / 手机号)→ 后续扩展
|
||
- 权益查看、景区预约、预约记录、使用记录 → 后续迭代
|
||
- 真实微信支付接入 → 第一版用模拟支付
|
||
|
||
---
|
||
|
||
## 二、项目架构
|
||
|
||
### 2.1 分包目录结构
|
||
|
||
```
|
||
zhy-test/
|
||
├── src/
|
||
│ ├── pages/ # 主包(共享入口)
|
||
│ │ ├── index/index.vue # 入口页(改造:默认跳转用户端首页)
|
||
│ │ └── login/login.vue # 登录页(改造为微信授权登录)
|
||
│ │
|
||
│ ├── packages/
|
||
│ │ ├── user/ # 用户端分包
|
||
│ │ │ └── pages/
|
||
│ │ │ ├── index/index.vue # 用户首页(宫格式)
|
||
│ │ │ ├── card/list.vue # 年卡列表
|
||
│ │ │ ├── card/detail.vue # 年卡详情
|
||
│ │ │ ├── card/buy.vue # 确认购买(模拟支付)
|
||
│ │ │ ├── card/activate.vue # 激活年卡
|
||
│ │ │ ├── card/qrcode.vue # 入园码(卡片式)
|
||
│ │ │ ├── card/bind.vue # 绑定年卡
|
||
│ │ │ └── profile/index.vue # 个人中心
|
||
│ │ │
|
||
│ │ └── admin/ # 管理端分包(第二迭代,暂不实现)
|
||
│ │
|
||
│ ├── api/ # 接口层
|
||
│ │ ├── request.ts # HTTP 封装(改造现有)
|
||
│ │ ├── user.ts # 用户/登录接口(改造)
|
||
│ │ ├── card.ts # 年卡接口(新增)
|
||
│ │ └── order.ts # 订单/支付接口(新增)
|
||
│ │
|
||
│ ├── store/ # Pinia Store
|
||
│ │ ├── user.ts # 用户状态(改造现有)
|
||
│ │ └── card.ts # 年卡状态(新增)
|
||
│ │
|
||
│ ├── components/ # 共享组件(新增)
|
||
│ │ ├── card-item.vue # 年卡卡片组件
|
||
│ │ └── empty-state.vue # 空状态组件
|
||
│ │
|
||
│ ├── config/ # 环境配置(新增)
|
||
│ │ └── index.ts # 根据环境变量切换 baseURL
|
||
│ │
|
||
│ └── utils/ # 工具函数(扩展现有)
|
||
│ └── index.ts
|
||
```
|
||
|
||
### 2.2 pages.json 路由配置
|
||
|
||
主包保留 `pages/index`(入口跳转)和 `pages/login`,用户端页面全部放入 `packages/user` 分包。
|
||
|
||
```json
|
||
{
|
||
"pages": [
|
||
{ "path": "pages/index/index", "style": { "navigationBarTitleText": "湖南12301" } },
|
||
{ "path": "pages/login/login", "style": { "navigationBarTitleText": "登录" } }
|
||
],
|
||
"subPackages": [
|
||
{
|
||
"root": "packages/user",
|
||
"pages": [
|
||
{ "path": "pages/index/index", "style": { "navigationBarTitleText": "文旅专区" } },
|
||
{ "path": "pages/card/list", "style": { "navigationBarTitleText": "年卡列表" } },
|
||
{ "path": "pages/card/detail", "style": { "navigationBarTitleText": "年卡详情" } },
|
||
{ "path": "pages/card/buy", "style": { "navigationBarTitleText": "确认购买" } },
|
||
{ "path": "pages/card/activate", "style": { "navigationBarTitleText": "激活年卡" } },
|
||
{ "path": "pages/card/qrcode", "style": { "navigationBarTitleText": "入园码" } },
|
||
{ "path": "pages/card/bind", "style": { "navigationBarTitleText": "绑定年卡" } },
|
||
{ "path": "pages/profile/index", "style": { "navigationBarTitleText": "个人中心" } }
|
||
]
|
||
}
|
||
],
|
||
"tabBar": {
|
||
"color": "#7A7E83",
|
||
"selectedColor": "#4A90D9",
|
||
"backgroundColor": "#ffffff",
|
||
"list": [
|
||
{ "pagePath": "packages/user/pages/index/index", "text": "首页" },
|
||
{ "pagePath": "packages/user/pages/profile/index", "text": "我的" }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.3 多环境配置
|
||
|
||
| 环境 | baseURL | 触发方式 | 配置文件 |
|
||
|------|---------|----------|----------|
|
||
| 本地开发 | `http://localhost:80` | `pnpm dev:h5` | `.env.local` |
|
||
| 开发环境 | `https://dscp-dev.hn12301.net` | `--mode dev` | `.env.dev` |
|
||
| 预发布 | `https://dscp-uat.hn12301.net` | `--mode uat` | `.env.uat` |
|
||
|
||
通过 `config/index.ts` 统一读取 `import.meta.env.VITE_API_BASE_URL`。
|
||
|
||
---
|
||
|
||
## 三、API 层设计
|
||
|
||
### 3.1 request.ts 改造
|
||
|
||
**改造要点**:
|
||
- `baseURL` 从 `config/index.ts` 读取(替代空字符串)
|
||
- Token 管理保持现有 `uni.getStorageSync` / `uni.setStorageSync` 模式
|
||
- 请求拦截器自动注入 `Authorization: Bearer <token>`
|
||
- 响应拦截器:`code === 200` 成功,`401` 清除 token 并跳转登录页
|
||
- 保留 `get()` / `post()` / `put()` / `del()` 便捷方法
|
||
|
||
### 3.2 接口模块定义
|
||
|
||
```typescript
|
||
// api/user.ts(改造)
|
||
wxLogin(code: string) // POST /manage-api/auth/wx-login → { accessToken, refreshToken, userId }
|
||
getUserInfo() // GET /manage-api/user/info → UserInfo
|
||
|
||
// api/card.ts(新增)
|
||
getCardList(params?) // GET /manage-api/card/list → CardInfo[]
|
||
getCardDetail(id: string) // GET /manage-api/card/detail?id=xxx → CardDetail
|
||
activateCard(cardId, data) // POST /manage-api/card/activate → boolean
|
||
bindCard(cardNo: string) // POST /manage-api/card/bind → boolean
|
||
getMyCards() // GET /manage-api/card/my-list → MyCard[]
|
||
getEntryQrCode(cardId: string) // GET /manage-api/card/qrcode?cardId=xxx → { qrCode, expireTime }
|
||
|
||
// api/order.ts(新增)
|
||
createOrder(data) // POST /manage-api/order/create → OrderInfo
|
||
mockPay(orderId: string) // POST /manage-api/order/mock-pay → { success: true }(模拟支付)
|
||
getOrderList(params?) // GET /manage-api/order/list → OrderInfo[]
|
||
getOrderDetail(id: string) // GET /manage-api/order/detail?id=xxx → OrderDetail
|
||
```
|
||
|
||
> **注意**:接口路径和参数格式需在实现时与后端实际接口对齐。以上为预定义,实现阶段根据后端实际接口调整。
|
||
|
||
---
|
||
|
||
## 四、Store 设计
|
||
|
||
### 4.1 user store(改造现有)
|
||
|
||
```
|
||
State:
|
||
token: string // 访问令牌
|
||
refreshToken: string // 刷新令牌
|
||
userInfo: UserInfo | null // 用户信息
|
||
|
||
Computed:
|
||
isLogin: boolean // !!token
|
||
|
||
Actions:
|
||
wxLogin(): Promise // 调用 wx.login() 获取 code,发送后端换取 token
|
||
logout(): void // 清除状态和 storage
|
||
fetchUserInfo(): Promise // 获取当前用户信息
|
||
```
|
||
|
||
### 4.2 card store(新增)
|
||
|
||
```
|
||
State:
|
||
cardList: CardInfo[] // 年卡列表
|
||
currentCard: CardDetail // 当前查看的年卡详情
|
||
myCards: MyCard[] // 我的年卡列表
|
||
|
||
Actions:
|
||
fetchCardList(params?): Promise // 获取年卡列表
|
||
fetchCardDetail(id): Promise // 获取年卡详情
|
||
fetchMyCards(): Promise // 获取我的年卡
|
||
activateCard(cardId, data): Promise // 激活年卡
|
||
bindCard(cardNo): Promise // 绑定年卡
|
||
getEntryQrCode(cardId): Promise // 获取入园码
|
||
```
|
||
|
||
---
|
||
|
||
## 五、微信登录设计
|
||
|
||
### 5.1 登录流程
|
||
|
||
```
|
||
用户打开小程序
|
||
→ 检查本地是否有 token
|
||
→ 有 token → 直接进入用户端首页
|
||
→ 无 token → 跳转登录页
|
||
→ 用户点击"微信登录"按钮
|
||
→ uni.login() 获取 code
|
||
→ POST /manage-api/auth/wx-login { code }
|
||
→ 后端返回 { accessToken, refreshToken, userId }
|
||
→ 存入 Store + Storage
|
||
→ 跳转用户端首页
|
||
```
|
||
|
||
### 5.2 平台策略
|
||
|
||
| 平台 | 第一迭代 | 后续扩展 |
|
||
|------|----------|----------|
|
||
| 微信小程序 | `wx.login()` 授权登录 | — |
|
||
| H5 | 不支持(提示请在微信小程序中使用) | 微信 OAuth / 手机号登录 |
|
||
|
||
### 5.3 降级方案
|
||
|
||
如果后端微信登录接口尚未就绪,可临时使用现有账号密码登录接口,在 `user store` 的 `wxLogin()` 方法中预留切换点。
|
||
|
||
---
|
||
|
||
## 六、用户端页面设计
|
||
|
||
### 6.1 首页(宫格式)
|
||
|
||
**路由**:`/packages/user/pages/index/index`
|
||
|
||
**布局**:
|
||
- 顶部:标题栏 "湖南12301文旅专区"
|
||
- 中部:2×2 宫格功能入口(购买年卡 / 激活绑定 / 景区预约 / 我的记录)。其中"景区预约"和"我的记录"在第一迭代中点击后弹出"即将上线"提示
|
||
- 下部:推荐年卡列表(卡片式展示)
|
||
- 底部:TabBar(首页 / 我的)— 权益 Tab 在后续迭代中补充
|
||
|
||
### 6.2 年卡列表
|
||
|
||
**路由**:`/packages/user/pages/card/list`
|
||
|
||
**布局**:
|
||
- 顶部搜索栏
|
||
- 分类筛选标签
|
||
- 年卡卡片列表(使用 card-item 组件)
|
||
- 每个卡片:封面图 + 名称 + 价格 + 简要权益
|
||
|
||
### 6.3 年卡详情
|
||
|
||
**路由**:`/packages/user/pages/card/detail`
|
||
|
||
**布局**:
|
||
- 顶部封面大图
|
||
- 年卡名称 + 价格(原价划线)
|
||
- 权益说明列表
|
||
- 权益景区横滑卡片
|
||
- 底部固定按钮:立即购买
|
||
|
||
### 6.4 确认购买(模拟支付)
|
||
|
||
**路由**:`/packages/user/pages/card/buy`
|
||
|
||
**布局**:
|
||
- 订单信息卡片(卡种名称 / 价格 / 有效期)
|
||
- 支付方式选择(第一版仅"模拟支付")
|
||
- 底部按钮:确认支付
|
||
- 支付成功后跳转到激活页面
|
||
|
||
### 6.5 激活年卡
|
||
|
||
**路由**:`/packages/user/pages/card/activate`
|
||
|
||
**布局**:
|
||
- 年卡信息展示
|
||
- 实名信息表单(姓名 / 身份证号 / 手机号)
|
||
- 底部按钮:立即激活
|
||
- 激活成功后跳转到入园码页面
|
||
|
||
### 6.6 入园码(卡片式)
|
||
|
||
**路由**:`/packages/user/pages/card/qrcode`
|
||
|
||
**布局**:
|
||
- 年卡信息卡片(渐变色背景,显示姓名和有效期)
|
||
- 二维码区域(白色卡片,居中显示)
|
||
- 提示文字:"扫码入园 · 每60秒自动刷新"
|
||
- 底部操作按钮:预约景区 / 刷新二维码
|
||
|
||
### 6.7 个人中心
|
||
|
||
**路由**:`/packages/user/pages/profile/index`(TabBar 页面)
|
||
|
||
**布局**:
|
||
- 用户头像 + 昵称卡片
|
||
- 我的年卡入口
|
||
- 订单管理入口
|
||
- 使用记录入口
|
||
- 退出登录按钮
|
||
|
||
---
|
||
|
||
## 七、页面导航流程
|
||
|
||
```
|
||
小程序启动
|
||
→ pages/index/index(入口页,自动跳转)
|
||
→ packages/user/pages/index/index(用户首页)
|
||
|
||
核心购买流程:
|
||
用户首页 → 年卡列表 → 年卡详情 → 确认购买 → 模拟支付 → 激活年卡 → 入园码
|
||
|
||
TabBar 常驻页面:
|
||
首页(packages/user/pages/index/index)
|
||
我的(packages/user/pages/profile/index)
|
||
|
||
非 Tab 页面(navigateTo):
|
||
年卡列表、年卡详情、确认购买、激活年卡、入园码、绑定年卡
|
||
```
|
||
|
||
---
|
||
|
||
## 八、共享组件
|
||
|
||
| 组件 | 路径 | 用途 |
|
||
|------|------|------|
|
||
| `card-item.vue` | `components/card-item.vue` | 年卡卡片展示(封面/名称/价格/权益摘要) |
|
||
| `empty-state.vue` | `components/empty-state.vue` | 空状态提示(图标 + 文案 + 操作按钮) |
|
||
|
||
---
|
||
|
||
## 九、关键约束
|
||
|
||
1. **接口对齐**:API 路径和参数为预定义,实现时需与后端实际接口对齐
|
||
2. **模拟支付**:第一版不接入真实微信支付,使用模拟支付接口跑通流程
|
||
3. **UI 优先级**:功能先行,使用 uni-ui 默认样式,后续迭代美化
|
||
4. **仅小程序**:第一迭代仅支持微信小程序平台,H5 登录后缀扩展
|
||
5. **管理端预留**:`packages/admin/` 目录结构预留,不在第一迭代实现
|