Files
yuyueguahao/docs/superpowers/plans/2026-06-13-yuyueguahao-v2-evolution.md
T
2026-07-05 14:43:34 +08:00

166 lines
10 KiB
Markdown
Raw 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.
# 苏州肛泰中医院 · v2 平台化升级实施计划
> **For agentic workers:** 按 Phase 顺序执行,每个 Phase 都是可独立交付的 milestone,用户可在任意 Phase 完成后暂停/调整方向。
> **执行策略**:Phase 内逐步交付,每个 bite-sized 任务完成后等待用户确认再继续。
**Goal**:把当前"医院小程序 + 后端 + 管理后台"从"能跑"升级到"企业级可维护",覆盖 4 大需求:API 标准化、视觉重塑、问卷增强、模块化重构。
**Architecture**
- 后端:Express + MySQL,新增 Swagger/OpenAPI 自动文档 + Markdown 接口规范 + `/api/leads` 新表 + 业务域 service 拆分
- 前端:Taro 4 + React 18 + TS 5,新增 `modules/lead` 业务域模块 + 全局 design tokens 重塑(低饱和度专业色系)
- 管理后台:原生 SPA 风格不变,新增 leads 客户列表 + 接口版本号展示
**Tech Stack**
- 后端:Express 4 / mysql2 / dayjs / **新增** swagger-ui-express + swagger-jsdoc + apidoc
- 前端:Taro 4.1 / React 18 / TypeScript 5 / Sass / Zustand / **新增** modules/lead 域
- 数据库:MariaDB 10.x,新增 `leads`
---
## Phase 总览
| Phase | 主题 | 涉及文件数 | 估时 | 依赖 |
|---|---|---|---|---|
| **P1** | 业务域 service 拆分(模块化基础) | 14 改 + 6 新增 | 1.5h | 无 |
| **P2** | Swagger + Markdown 接口文档 | 4 改 + 3 新增 | 1h | P1 |
| **P3** | 问卷 / 自主测试 + 用户信息采集 + leads 表 | 1 改 + 2 新增 | 1.5h | P1, P2 |
| **P4** | 全局设计 tokens 重塑 + 主流程 6 页视觉升级 | 1 改 + 6 改 | 1.5h | P1 |
| **P5** | 接口版本控制 / 同步机制 | 2 改 + 1 新增 | 0.5h | P2 |
**总估时**~6h4 个 milestone 验收点,可分多次完成)
---
## Phase 1:业务域 service 拆分(高内聚低耦合)
**目标**:把 `server/src/routes/*` 按业务域重组,添加 README,建立模块化骨架。
### 任务清单
- [ ] **Task 1.1** 新建 `server/src/modules/hospital/` 目录,迁移 `routes/hospital.js``modules/hospital/route.js` + 新增 `modules/hospital/service.js`(查询逻辑)+ `modules/hospital/README.md`
- [ ] **Task 1.2** 同样模式处理 `department` / `doctor` / `appointment` / `expert` / `banner` / `config` 6 个域
- [ ] **Task 1.3** 新建 `server/src/modules/index.js` 统一注册 router
- [ ] **Task 1.4** 修改 `server/src/index.js`:把 `app.use('/api/...', router)` 改为 `app.use('/api/v1/...', router)`**v1 是版本号起点**
- [ ] **Task 1.5**`server/src/modules/README.md`:描述每个模块的 `route.js`HTTP 层)/`service.js`(业务逻辑)/`dto.js`(数据转换)`README.md`(接口说明)规范
- [ ] **Task 1.6** 验证:PM2 重启后 `curl /api/v1/hospitals` 仍返回 `code:0, data:[...]`
**验收标准**
- 每个业务域目录包含 route/service/dto/README 四件套
- 服务启动日志接口列表全部以 `/api/v1` 开头
- 前端 services/*.ts 调用的 URL 由 `/api/...` 改为 `/api/v1/...`(同时**前端 BASE_URL 配置新增版本号**
- 数据库交互全部经过 service.jsroute.js 不再直接写 SQL
---
## Phase 2Swagger UI + Markdown 接口文档
**目标**:自动生成 OpenAPI 3.0 规范 + Markdown 业务说明,浏览器可访问 `/api/docs`
### 任务清单
- [ ] **Task 2.1** 安装依赖:`cd server && npm i swagger-ui-express swagger-jsdoc`
- [ ] **Task 2.2** 新建 `server/src/swagger/spec.js`:配置 swagger-jsdoc,扫描 `modules/*/route.js` 的 JSDoc 注释,生成 OpenAPI 3.0 spec
- [ ] **Task 2.3**`server/src/index.js` 注册 `app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(spec))` + `app.get('/api/docs.json', ...)` 输出原始 spec
- [ ] **Task 2.4** 给 7 个 module 的 route.js 关键接口加 JSDoc`@swagger` 路径,包含 path/method/parameters/responses
- [ ] **Task 2.5** 新建 `docs/api/README.md`:API 总览(基地址、版本、认证、错误码约定)
- [ ] **Task 2.6** 新建 `docs/api/v1/hospital.md``department.md``doctor.md``appointment.md``expert.md``banner.md``config.md``admin-auth.md``lead.md`lead 是 P3 的)
- [ ] **Task 2.7** 新建 `docs/api/CHANGELOG.md`:版本变更记录
**验收标准**
- 浏览器访问 `http://124.221.67.199:3000/api/docs/` 显示完整 API 文档
- 8 个 markdown 文档,每个包含:接口路径 / 方法 / 请求参数表 / 响应示例 / 错误码 / 业务说明
- CHANGELOG 记录 v1.0.0 → v1.1.0 的接口变更
---
## Phase 3:自主问卷用户信息采集 + leads 表
**目标**:问卷底部新增姓名/手机号/症状采集区,前后端校验,提交到 `/api/v1/leads`
### 任务清单
- [ ] **Task 3.1** 数据库:在 `server/src/schema.sql` 末尾追加 `CREATE TABLE leads (...)`id / name / phone / symptom / questionnaire JSON / source / created_at,加唯一索引 `(phone, source)`
- [ ] **Task 3.2** 后端:新建 `server/src/modules/lead/route.js`POST 提交 / GET 列表 / GET 详情)
- [ ] **Task 3.3** 后端:新建 `server/src/modules/lead/service.js`:手机号正则、问卷 JSON 解析、source 枚举校验
- [ ] **Task 3.4** 后端:新建 `server/src/modules/lead/dto.js` + `README.md`
- [ ] **Task 3.5** 前端:新建 `src/modules/lead/types.ts`Lead / LeadForm TS 类型)
- [ ] **Task 3.6** 前端:新建 `src/modules/lead/api.ts`submitLead / fetchLeads
- [ ] **Task 3.7** 前端:修改 `src/pages/self-test/index.tsx`:底部加 `<View className={styles.userInfoSection}>`,包含姓名 Input / 手机 Input / 症状 Textarea"提交问卷结果"按钮
- [ ] **Task 3.8** 前端:表单校验(姓名 1-20 字符 / 手机 `^1[3-9]\d{9}$` / 症状 ≤500 字 / 必填),错误内联展示
- [ ] **Task 3.9** 前端:成功后调 `submitLead`,后端返回 leadId,跳 `/pages/success/index?type=lead&id=...`
- [ ] **Task 3.10** 管理后台:在 `admin/index.html``/admin/leads` 标签页,列表展示姓名/手机/来源/时间/问卷结果 JSON 折叠
- [ ] **Task 3.11** 后端:新增 `GET /api/v1/admin/leads`authRequired)给管理后台用
**验收标准**
- `curl -X POST /api/v1/leads -d '{"name":"...","phone":"...","questionnaire":{...}}'` 返回 200 + leadId
- 手机号不合法 → 后端 400 `{code:400, message:"手机号格式不正确"}`
- 数据库 `SELECT * FROM leads` 看到刚提交的行
- 小程序端提交 → 管理后台 `/admin/leads` 立即看到
---
## Phase 4:设计 tokens 重塑 + 主流程 6 页视觉升级
**目标**:低饱和度专业色系(去掉原 #1f7ae0 高饱蓝),升级 6 个主流程页视觉。
### 任务清单
- [ ] **Task 4.1** 重构 `src/styles/theme.scss`:主色改为 `#0f766e`(低饱和度医绿)或 `#475569`(深石板蓝),辅色 `border-radius` 提升到 12-16rpx,阴影由硬阴影改为柔阴影 `0 2px 8px rgba(15,23,42,.04) → 0 1px 3px rgba(15,23,42,.06), 0 4px 16px rgba(15,23,42,.04)`
- [ ] **Task 4.2** 重构 `src/styles/variables.scss`:间距 8pt 网格(`$spacing-1: 4rpx; $spacing-2: 8rpx; ...`),字号阶梯
- [ ] **Task 4.3** 新建 `src/styles/mixins.scss``@mixin card` / `@mixin btn-primary` / `@mixin section-title`,统一卡片/按钮/章节头样式
- [ ] **Task 4.4** 首页:使用 mixins 重写 `home/index.module.scss`,增大 Hero 留白,专家头像由 64rpx → 80rpx
- [ ] **Task 4.5** 医院页:科室网格由 4 列 → 3 列,卡片高度 220rpx → 240rpx,加 hover 状态
- [ ] **Task 4.6** 预约页:表单分组由密集 → 留白充足,提交按钮加 24rpx 圆角
- [ ] **Task 4.7** 问卷页:题目卡片加大内边距,选项 hover 加 border 高亮
- [ ] **Task 4.8** 成功页:成功图标由 emoji → SVG,结果列表用左侧色条
- [ ] **Task 4.9** 我的页:菜单项由 2 列 → 1 列 + 右侧箭头,更接近企业级
- [ ] **Task 4.10** 全站 6 个页面 `pages.config.json` 标题统一"苏州肛泰中医院 - X"
**验收标准**
- 全站色系用 `<kbd>ColorPick</kbd>` 取色,所有页面主色都从 tokens 派生(无硬编码颜色)
- 阴影统一两层:近阴影(按钮/输入框) + 远阴影(卡片/弹层)
- 6 个页面对比之前截图,整体更"沉稳专业"(非"活泼可爱"
---
## Phase 5:接口版本控制与同步机制
**目标**:建立 `/api/v1` 之后到 `/api/v2` 的兼容/弃用/移除规范。
### 任务清单
- [ ] **Task 5.1** 后端:新增 `server/src/middleware/apiVersion.js`:响应头加 `X-API-Version: v1``Sunset` 头(如果 deprecated
- [ ] **Task 5.2** 后端:新增 `server/src/middleware/changelogBroadcast.js`:每次启动时把当前版本号 + CHANGELOG.md 摘要写入 `server_runtime.log`
- [ ] **Task 5.3** 前端:新增 `src/services/apiVersion.ts`:请求时带 `X-Client-Version` 头,响应时检查 `Sunset` 头并 toast 提示
- [ ] **Task 5.4** 新建 `docs/api/SYNC.md`:描述后端接口变更 → 前端同步流程
1. 后端开发改 route.js + swagger JSDoc
2. `npm run docs:gen` 自动更新 markdown
3.`docs/api/CHANGELOG.md` 加一行
4. 前端 `pnpm sync-api` 拉取 `/api/docs.json` 生成 `types/api/*.d.ts`
5. 前端 IDE 报类型错误 → 定位 + 修改
- [ ] **Task 5.5** 新建 `docs/superpowers/plans/2026-06-13-api-sync-workflow.md`:详细描述开发者日常流程
**验收标准**
- `curl -I /api/v1/hospitals` 响应头包含 `X-API-Version: v1`
- 前端 `apiVersion.ts` 在收到 Sunset 头时 `Taro.showToast({ title: '接口即将停用,请更新 APP', icon: 'none' })`
- docs/api/SYNC.md 描述的工作流可被新开发者 5 分钟内理解
---
## 风险与回滚
| 风险 | 缓解 |
|---|---|
| Phase 4 视觉改坏既有页面 | 保留 theme 旧版 v1 注释,可在 1 行切换 |
| Phase 1 改 URL 前缀 `/api/v1` 影响前端联调 | 同步修改 `src/services/request.ts` 的 BASE_URL 拼接逻辑 |
| Phase 3 leads 表字段缺索引 | `(phone, source)` 加唯一索引 + `created_at` 加普通索引 |
| Phase 5 Sunset 头跨域被浏览器剥 | Nginx/proxy 不应剥自定义响应头,标注到部署文档 |
## 验收里程碑(用户暂停点)
- **M1**Phase 1 完成后,前端 `pnpm dev` + 后端 `npm start` 全栈联通,业务不变
- **M2**Phase 2 完成后,`/api/docs` 可访问,8 个 markdown 文档齐全
- **M3**Phase 3 完成后,问卷可提交 + 管理后台可见
- **M4**Phase 4 完成后,6 页视觉一致、设计 tokens 单点控制
- **M5**:Phase 5 完成后,接口版本与同步流程文档化