Files
pingxiangcard/docs/superpowers/specs/2026-06-13-hunan12301-design.md

338 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 湖南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/` 目录结构预留,不在第一迭代实现