chore: 初始化项目 — uni-app + Vue3 + TypeScript 脚手架

This commit is contained in:
jacobxu666
2026-06-14 17:16:18 +08:00
commit 046e84a564
37 changed files with 13763 additions and 0 deletions
@@ -0,0 +1,337 @@
# 湖南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/` 目录结构预留,不在第一迭代实现