|
|
@@ -0,0 +1,252 @@
|
|
|
+# 浠艾福小程序改版:需求驱动 · 逐步解锁
|
|
|
+
|
|
|
+> 阶段:实施计划 v1.0 | 分支:cfclub | 产品决策已确认(2026-08-13)
|
|
|
+
|
|
|
+## 一、背景与目标
|
|
|
+
|
|
|
+现状:小程序首页对所有用户一视同仁地堆内容(商品/活动/文章/任务),未区分用户需求深度,转化链路不清晰。
|
|
|
+
|
|
|
+改版核心:**从用户需求出发,先识别用户类型,按需求深度逐步解锁内容与功能,无关内容不展示。**
|
|
|
+
|
|
|
+三类用户:
|
|
|
+- **A类 目标明确型**:已接受平台理念,直接买 DAN测评 / 菌群检测 → 上传报告 → 出方案 → 生成任务 → 执行(方案任务需会员)
|
|
|
+- **B类 观望型**:登录看看 → 轻问卷 → 按答案开放相关科普内容
|
|
|
+- **C类 问题导向型**:带具体问题来(减肥/睡眠/便秘)→ 服务流程介绍 → 专项调研 → 匹配推荐套餐 → 购买 → 试剂盒寄送/样本寄回 → 报告完成系统通知 → 方案确认 → 任务分解执行 → 全部完成奖励 CF 值
|
|
|
+
|
|
|
+已确认决策:
|
|
|
+1. 入口呈现:**首次登录强制选择**;已登录但从未选过的用户,下次进入也要弹出选择
|
|
|
+2. 问题域首版:**减肥 / 睡眠 / 便秘** 三个
|
|
|
+3. 会员任务边界:**仅"方案生成"的任务需会员**;未缴费用户可以自己创建任务自己完成(免费)
|
|
|
+4. 完成回馈奖励:**主要奖励 CF 值**(复用 PlatformPointsService)
|
|
|
+5. 实施优先级:**C类优先 → A类会员任务解锁 → B类问卷引流**
|
|
|
+
|
|
|
+## 二、现状摸底结论(已核实)
|
|
|
+
|
|
|
+| 模块 | 现状 | 结论 |
|
|
|
+|------|------|------|
|
|
|
+| 首页分流 | `pages/index-home/index.vue` 内嵌登录/游客两态,游客看商品+活动+文章,登录看沙盘+动态+会员入口+快捷功能+任务+挑战+推荐 | 需重构为"旅程状态驱动" |
|
|
|
+| 测评链路 | `DanAssessmentController`: order/create→pay→appointment→record→result→report 全链路已有 | ★★★ 直接复用 |
|
|
|
+| 报告解析 | `DanReportController`: upload→edit→confirm→complete-analysis | ★★★ 直接复用 |
|
|
|
+| 菌群检测 | `BeijingNutritionController`: bacteria/save + analysis + recommend;送会员走 `TrialMembership` | ★★★ 直接复用 |
|
|
|
+| 会员 | `FamilyMembership`(FREE/BASIC/PROFESSIONAL/ENTERPRISE) + `MembershipController`(upgrade/trial/my/can-use/benefits) | ★★★ 直接复用 |
|
|
|
+| 问卷 | `SurveyTemplate`(questionsJson 题目JSON) + `SurveyRecord`(answersJson) + `ReportSurveyController`(create/submit/status);前端 `pages/health/survey-questionnaire.vue` 通用渲染页已有 | ★★ 扩展(题目JSON 加 resultMapping) |
|
|
|
+| 套餐 | `GuidePackage`(price/validityDays) + `TaskTemplatePackage`(cycleDays/category/price) + `AssessmentProduct`(single/bundle) | ★★ 需补"套餐→检测→任务模板"关联 |
|
|
|
+| 任务 | `Task` 有 sourceType/sourceId/dimensionCode,**无会员字段** | ★ 需加 `member_only` |
|
|
|
+| CF值 | `PlatformPointsService.earn/spend/freeze/unfreeze` + 家庭池 `FamilyPlatformPointsService`;`UnlockGateService` 已实现关卡奖励发 CF 值(幂等) | ★★★ 复用 earn() 发奖励 |
|
|
|
+| 优惠券 | `Coupon`/`UserCoupon`/`CouponController`(exchange/claim) | ★★★ 备用 |
|
|
|
+| 通知 | `NoticeController` 仅 `/list`(GET,且不合规),无主动通知 | ★ 需新建通知表+写入+列表接口 |
|
|
|
+
|
|
|
+## 三、数据模型设计
|
|
|
+
|
|
|
+### 3.1 新增 `problem_domains`(问题域表)
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS problem_domains (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ code VARCHAR(50) NOT NULL COMMENT '唯一编码: weight_loss/sleep/constipation',
|
|
|
+ name VARCHAR(50) NOT NULL COMMENT '名称: 减肥/睡眠/便秘',
|
|
|
+ icon VARCHAR(255) DEFAULT '' COMMENT '图标',
|
|
|
+ description VARCHAR(500) DEFAULT '' COMMENT '一句话描述',
|
|
|
+ flow_intro_json TEXT COMMENT '服务流程介绍(7步) JSON',
|
|
|
+ survey_template_id BIGINT DEFAULT NULL COMMENT '专项调研问卷模板ID(SurveyTemplate.id)',
|
|
|
+ content_tags VARCHAR(500) DEFAULT '' COMMENT '内容标签,逗号分隔(过滤文章/知识库)',
|
|
|
+ recommended_product_ids VARCHAR(500) DEFAULT '' COMMENT '推荐产品ID,逗号分隔(Product.id)',
|
|
|
+ task_template_package_ids VARCHAR(500) DEFAULT '' COMMENT '套餐绑定的任务模板包ID(TaskTemplatePackage.id)',
|
|
|
+ reward_cf_value INT DEFAULT 0 COMMENT '全部完成奖励CF值',
|
|
|
+ status TINYINT DEFAULT 1 COMMENT '1启用 0停用',
|
|
|
+ sort_order INT DEFAULT 0,
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_code (code)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问题域定义(改版v1)';
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 新增 `user_intents`(用户意图/旅程表)
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS user_intents (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ user_id BIGINT NOT NULL COMMENT '用户ID',
|
|
|
+ intent_type VARCHAR(20) DEFAULT '' COMMENT 'A/B/C 用户类型',
|
|
|
+ problem_domain_code VARCHAR(50) DEFAULT '' COMMENT '问题域编码(仅C类)',
|
|
|
+ journey_stage INT DEFAULT 0 COMMENT '旅程阶段 0-7,语义见下方状态机',
|
|
|
+ stage_updated_at DATETIME DEFAULT NULL COMMENT '最近阶段变化时间',
|
|
|
+ survey_template_id BIGINT DEFAULT NULL COMMENT '最近作答问卷模板ID',
|
|
|
+ survey_submitted_at DATETIME DEFAULT NULL COMMENT '最近问卷提交时间',
|
|
|
+ survey_result_json TEXT COMMENT '问卷答案→推荐结果快照',
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_user (user_id)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户意图与服务旅程(改版v1)';
|
|
|
+```
|
|
|
+
|
|
|
+**journey_stage 状态机(C类,0-7)**:
|
|
|
+| stage | 语义 | 进入条件 | 推进动作 |
|
|
|
+|-------|------|----------|----------|
|
|
|
+| 0 | 已选择问题域,未看流程 | 用户选择 C 类+问题域 | 打开流程介绍页 |
|
|
|
+| 1 | 已看流程介绍 | 流程介绍页曝光完成 | 提交调研 |
|
|
|
+| 2 | 调研已提交 | 调研提交成功 | 购买套餐 |
|
|
|
+| 3 | 已购买 | 支付回调成功 | 管理员发货 |
|
|
|
+| 4 | 试剂盒已发/样本已收 | 物流状态更新 | 报告生成 |
|
|
|
+| 5 | 报告已出 | completeAnalysis 完成 | 用户确认方案 |
|
|
|
+| 6 | 方案已确认,任务已生成 | 方案确认接口 | 任务全部完成 |
|
|
|
+| 7 | 任务完成,CF奖励已发 | 奖励发放成功 | —(终态,展示回馈) |
|
|
|
+
|
|
|
+A类简化:0=已选A类,1=已购测评/检测,2=报告已出,3=方案确认,4=任务完成。B类简化:0=已选B类,1=问卷已答(此后首页按结果定向展示内容)。
|
|
|
+
|
|
|
+### 3.2b 通知表与既有 `notices` 的边界
|
|
|
+
|
|
|
+- `notices`(`Notice.java`, @TableName("notices")):**平台级公告**,管理员发布(platform/activity/promotion),全员可见,`NoticeController` 仅 GET /list(遗留不合规,不动)。
|
|
|
+- `user_notifications`(新增):**用户级主动通知**,按 user_id 定向(报告完成/奖励到账/物流变化),带 ref_type/ref_id 可跳转。二者并存不冲突。
|
|
|
+
|
|
|
+### 3.3 Task 表加会员字段
|
|
|
+
|
|
|
+```sql
|
|
|
+ALTER TABLE task ADD COLUMN member_only TINYINT DEFAULT 0 COMMENT '1=会员任务(方案生成),执行需会员';
|
|
|
+```
|
|
|
+
|
|
|
+### 3.4 新增 `user_notifications`(站内通知表)
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS user_notifications (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ user_id BIGINT NOT NULL COMMENT '接收用户ID',
|
|
|
+ type VARCHAR(30) DEFAULT 'report_ready' COMMENT 'report_ready/reward_granted/system',
|
|
|
+ title VARCHAR(200) NOT NULL,
|
|
|
+ content VARCHAR(1000) DEFAULT '',
|
|
|
+ ref_type VARCHAR(30) DEFAULT '' COMMENT '关联对象类型: report/package/task',
|
|
|
+ ref_id BIGINT DEFAULT NULL COMMENT '关联对象ID',
|
|
|
+ is_read TINYINT DEFAULT 0,
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ INDEX idx_user_read (user_id, is_read)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='站内通知(改版v1)';
|
|
|
+```
|
|
|
+
|
|
|
+### 3.5 套餐/物流状态扩展(复用 PackageOrder / ProductOrder)
|
|
|
+
|
|
|
+- `package_orders` 表(`entity/PackageOrder.java` 已存在,含 userId/familyId/packageId/contactName/contactPhone/contactAddress)加:
|
|
|
+ - `logistics_status VARCHAR(20) DEFAULT 'none'`(none/kit_shipped/kit_received/sample_shipped/sample_received)
|
|
|
+ - `tracking_no VARCHAR(100) DEFAULT ''`
|
|
|
+
|
|
|
+### 3.6 调研问卷 → 推荐结果映射
|
|
|
+
|
|
|
+`SurveyTemplate.questionsJson` 题目结构扩展:每题的 option 支持 `resultTags`:
|
|
|
+
|
|
|
+```json
|
|
|
+[
|
|
|
+ {"text": "您的睡眠问题持续多久了?", "options": [
|
|
|
+ {"text": "1-3个月", "resultTags": "短期,轻中度"},
|
|
|
+ {"text": "半年以上", "resultTags": "长期,重度"}
|
|
|
+ ]}
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+后端提交问卷时汇总所有选中 option 的 resultTags + 问题域 code,返回推荐产品列表快照,存入 `user_intents.survey_result_json`。
|
|
|
+
|
|
|
+## 四、后端改动清单(cfc-backend)
|
|
|
+
|
|
|
+### 阶段1:C类问题导向型闭环(优先交付)
|
|
|
+
|
|
|
+| # | 文件 | 改动 | 验证 |
|
|
|
+|---|------|------|------|
|
|
|
+| B1 | `entity/ProblemDomain.java` | 新实体(§3.1) | compile |
|
|
|
+| B2 | `mapper/ProblemDomainMapper.java` | 新 Mapper | compile |
|
|
|
+| B3 | `entity/UserIntent.java` | 新实体(§3.2) | compile |
|
|
|
+| B4 | `mapper/UserIntentMapper.java` | 新 Mapper | compile |
|
|
|
+| B5 | `entity/UserNotification.java` | 新实体(§3.4) | compile |
|
|
|
+| B6 | `mapper/UserNotificationMapper.java` | 新 Mapper | compile |
|
|
|
+| B7 | `entity/Task.java` | 加 `memberOnly` 字段 | compile |
|
|
|
+| B8 | `config/DatabaseInitializer.java` | 迁移:3 张新表 + task.member_only + package_order 物流字段 | compile |
|
|
|
+| B9 | `resources/schema.sql` | 同步建表语句 | — |
|
|
|
+| B10 | `controller/ProblemDomainController.java` | 接口:`POST /api/problem-domain/list`(启用中,含问卷模板+推荐产品+任务模板) | compile |
|
|
|
+| B11 | `controller/UserIntentController.java` | 接口:`POST /api/user-intent/get`(当前意图) / `POST /api/user-intent/choose`(首次选择A/B/C) / `POST /api/user-intent/update-stage`(旅程推进) | compile |
|
|
|
+| B12 | `controller/UserNotificationController.java` | 接口:`POST /api/notification/list` / `POST /api/notification/read` | compile |
|
|
|
+| B13 | `controller/ProblemSurveyController.java` | 接口:`POST /api/problem-survey/submit`(提交调研→汇总resultTags→查推荐产品→存快照→返回推荐列表) | compile |
|
|
|
+| B14 | `controller/ProblemPackageController.java` | 接口:`POST /api/problem-package/detail`(套餐详情:介绍/使用方式/包含检测/任务模板/奖励说明) | compile |
|
|
|
+| B15 | `controller/TaskController.java` | 补会员校验:`/{id}/complete`、`/accept` 时若 `task.memberOnly==1` 且非会员 → 拒绝(提示开通会员) | compile |
|
|
|
+| B16 | `service/DanReportService.completeAnalysis`(报告确认处) | 报告完成解析后:写 `user_notifications`(report_ready) + 更新 `user_intents.journey_stage`=5 | compile |
|
|
|
+| B17 | `service/ProblemCompletionService.java` | 新 Service:任务全部完成后发放 CF 值。**奖励对象:家庭池(FamilyPlatformPointsService.earn,familyId 维度)**,金额=问题域配置 reward_cf_value;幂等:按 (familyId, problemDomainCode, 'completion') 查唯一发放记录;写通知(reward_granted) + 更新旅程 stage=7 | compile |
|
|
|
+| B18 | `entity/PackageOrder.java` | 加 `logisticsStatus` / `trackingNo`(表 package_orders) | compile |
|
|
|
+| B19 | `controller/LogisticsController.java` | 接口:`POST /api/logistics/update`(管理端发货/收样) / `POST /api/logistics/my`(用户查状态) | compile |
|
|
|
+
|
|
|
+### 阶段2:A类会员任务解锁
|
|
|
+
|
|
|
+| # | 文件 | 改动 |
|
|
|
+|---|------|------|
|
|
|
+| B20 | `service/TaskPlanService`(任务实例生成处)+ `TaskService.createSingleTask` | 方案/套餐确认生成任务实例时标记 `memberOnly=1`;`createSingleTask` 从 DTO 透传 memberOnly |
|
|
|
+| B21 | `service/RepeatTaskGenerator` | 重复任务复制模板时**透传 memberOnly 字段**(否则方案任务实例的会员标记丢失) |
|
|
|
+| B22 | `TaskController.create` | 未缴费用户自建任务:`memberOnly=0`,不校验会员(确认现有 create 已放行) |
|
|
|
+
|
|
|
+### 阶段3:B类问卷引流
|
|
|
+
|
|
|
+| # | 文件 | 改动 |
|
|
|
+|---|------|------|
|
|
|
+| B23 | `SurveyTemplate` 扩展 | questionsJson 支持 resultTags;`getActiveTemplates` 支持按问题域过滤 |
|
|
|
+| B24 | `controller/ContentFilterController.java` | 接口:`POST /api/content/by-tags`(按 resultTags + 问题域 code 过滤文章/知识库/饮食推荐) |
|
|
|
+
|
|
|
+## 五、前端改动清单(cfc-frontend)
|
|
|
+
|
|
|
+### 阶段1:C类闭环
|
|
|
+
|
|
|
+| # | 文件 | 改动 |
|
|
|
+|---|------|------|
|
|
|
+| F1 | `pages/index-home/index.vue` | **首页重构**:登录后顶部"旅程状态卡"(进度+下一步);未选择过意图的用户弹"首次选择"层(A直达/B问卷/C问题域) |
|
|
|
+| F2 | `components/intent-picker.vue`(新) | 首次选择弹层:三个入口卡片 |
|
|
|
+| F3 | `components/journey-card.vue`(新) | 旅程进度条 + 下一步动作按钮(按 user_intents 渲染) |
|
|
|
+| F4 | `pages/problem/domain-list.vue`(新) | 问题域列表页(3个卡片) |
|
|
|
+| F5 | `pages/problem/flow-intro.vue`(新) | 服务流程介绍页(7步,来自 flow_intro_json) |
|
|
|
+| F6 | `pages/problem/survey.vue`(新) | 专项调研页(复用 survey-questionnaire 模式,提交走 problem-survey/submit) |
|
|
|
+| F7 | `pages/problem/package-match.vue`(新) | 调研结果→推荐套餐列表(只显示相关) |
|
|
|
+| F8 | `pages/problem/package-detail.vue`(新) | 套餐详情(介绍/使用方式/包含检测/任务模板/奖励)→ 购买按钮 |
|
|
|
+| F9 | `pages/problem/logistics.vue`(新) | 试剂盒寄送/样本寄回状态 |
|
|
|
+| F10 | `pages/problem/plan-confirm.vue`(新) | 报告出来后查看方案 → 确认 → 生成任务 |
|
|
|
+| F11 | `pages/notification/index.vue`(新) | 站内通知列表(报告完成/奖励到账) |
|
|
|
+| F12 | `pages/tasks/tasks.vue` | 会员任务角标(memberOnly 显示🔒,点击提示开通会员) |
|
|
|
+| F13 | `utils/api.js` | 新接口封装(problem-domain/user-intent/notification/problem-survey/problem-package/logistics) |
|
|
|
+
|
|
|
+### 阶段2:A类
|
|
|
+
|
|
|
+| # | 文件 | 改动 |
|
|
|
+|---|------|------|
|
|
|
+| F14 | `pages/index-home/index.vue` | 入口A直达"测评/检测选购页" |
|
|
|
+| F15 | 方案确认页复用 F10 | A类报告出方案→确认→生成任务(带 memberOnly) |
|
|
|
+
|
|
|
+### 阶段3:B类
|
|
|
+
|
|
|
+| # | 文件 | 改动 |
|
|
|
+|---|------|------|
|
|
|
+| F16 | `pages/problem/quick-survey.vue`(新) | 5-8题轻问卷 |
|
|
|
+| F17 | `pages/index-home/index.vue` | 按调研结果定向展示科普内容模块 |
|
|
|
+
|
|
|
+## 六、管理端改动清单(cfc-web)
|
|
|
+
|
|
|
+| # | 文件 | 改动 |
|
|
|
+|---|------|------|
|
|
|
+| W1 | `views/admin/ProblemDomainManage.vue`(新) | 问题域 CRUD:编码/名称/图标/描述/流程介绍(7步编辑)/绑定问卷模板/内容标签/推荐产品/任务模板包/奖励CF值 |
|
|
|
+| W2 | 套餐管理增强 | 绑定检测项目、任务模板包、完成奖励CF值 |
|
|
|
+| W3 | 通知模板管理 | report_ready / reward_granted 文案配置(可选) |
|
|
|
+| W4 | 物流管理 | 试剂盒发货/样本签收状态更新(可选,后端接口已备) |
|
|
|
+
|
|
|
+## 七、实施顺序(里程碑)
|
|
|
+
|
|
|
+| 里程碑 | 内容 | 验收标准 |
|
|
|
+|--------|------|----------|
|
|
|
+| M1 数据层 | B1-B9 | mvn clean compile 通过;3 张新表 + task.member_only 迁移幂等 |
|
|
|
+| M2 C类后端接口 | B10-B19 | compile 通过;关键接口(survey submit→推荐、报告完成→通知+旅程推进、任务完成→CF奖励)逻辑可测 |
|
|
|
+| M3 C类前端闭环 | F1-F13 + W1 | 用户在开发者工具可走通:选减肥→流程介绍→调研→套餐→购买→物流→通知→方案确认→任务→完成得CF值 |
|
|
|
+| M4 A类会员任务 | B20-B21 + F14-F15 | 方案任务带锁,非会员执行被拦截;自建任务免费可用 |
|
|
|
+| M5 B类问卷引流 | B22-B23 + F16-F17 | 观望用户填问卷后首页只显示相关内容 |
|
|
|
+
|
|
|
+## 八、风险与注意事项
|
|
|
+
|
|
|
+1. **首次选择弹层**:必须在登录后数据加载前弹出一次,且"跳过"不得导致下次不再弹出(storage 标记 `intent_skipped`,弹层关闭时写标记但 user_intents 未创建 → 下次仍弹)。决策1要求"未选过就要弹"。**teacher(规划师)角色不弹**(服务商不是 C 类客户,仅 parent/child 视角弹)。
|
|
|
+2. **memberOnly 校验**:校验点在 TaskController complete/accept,需同时覆盖规划师批量审核路径(GuideFamilyTaskController)与家长代完成路径(complete-parent)。
|
|
|
+3. **CF 奖励幂等 + 归属**:按 (familyId, problemDomainCode, 'completion') 唯一记录防重复发放(参照 UnlockGateService 已实现模式);**奖励进家庭池**(FamilyPlatformPointsService),不落个人池,避免"执行者是孩子、购买者是家长"的归属争议。
|
|
|
+4. **问卷 resultTags**:老模板无 resultTags 时兼容(option 是纯字符串),解析器需双态处理。
|
|
|
+5. **小程序规范**:新页面全部 Options API、禁止可选链、禁止 :key 表达式、日期用 parseDate、路由用 POST。
|
|
|
+6. **通知合规**:`NoticeController` 现有 `/list` 是 GET(不合规遗留),新建的 `UserNotificationController` 一律 POST;不动旧接口。
|
|
|
+7. **问卷模板 JSON 迁移**:现有调研模板数据结构不含 resultTags,提交接口需对"无 resultTags"模板返回空推荐(不报错)。
|
|
|
+8. **物流状态**:已确认 `package_orders` 表存在(`PackageOrder.java`),物流字段加其上;kit_shipped 即"试剂盒已寄出"。
|
|
|
+9. **会员判断复用**:调 `MembershipController.can-use` 或直接查 `FamilyMembership` levelCode != FREE 且未过期。
|
|
|
+10. **C类流程承载物**:流程描述页/套餐详情页写死"菌群检测试剂盒"是错误的——**套餐(TaskTemplatePackage/GuidePackage)是承载物**,flow_intro_json 每步文案可配置,检测项目通过套餐绑定的 assessmentProduct 决定。减肥/睡眠/便秘各自的套餐与检测项在管理端配置,代码不写死。
|
|
|
+11. **新增 Controller 前置检查**:新增 ProblemDomainController/UserIntentController 等前,先跑路由重复检查(AGENTS.md 工作流)与 Bean 名冲突检查。
|