|
|
@@ -14,17 +14,18 @@
|
|
|
|
|
|
**验收标准(输入表单):**
|
|
|
|
|
|
-1. 输入页面包含:姓名(选填)、出生年份(4位数字)、月份(1-12)、日期(1-31)
|
|
|
+1. 输入页面包含:**被咨询者姓名**(选填,即命盘主人姓名)、出生年份(4位数字)、月份(1-12)、日期(1-31)
|
|
|
2. 月份和日期支持数字键盘输入,也有下拉选择器
|
|
|
3. 验证:年份必须为 1900-当前年份、月份 1-12、日期根据月份合法性验证
|
|
|
4. 输入无效时显示具体错误提示(如"请输入正确的出生日期")
|
|
|
5. "想了解的问题" 输入框限制 100 字以内(输入时实时显示剩余字数)
|
|
|
6. 点击"开始咨询"后,调用后端 `POST /api/consultation/start` 发起咨询
|
|
|
+7. **已登录用户自动填入自己生日**(用户注册时已填 `birth_date`),但允许修改(能量师可输入客户生日)
|
|
|
|
|
|
**验收标准(咨询会话管理):**
|
|
|
|
|
|
7. 后端按照 **userId + birthday** 唯一确定一条咨询记录(同用户+同生日始终返回同一条记录)
|
|
|
-8. 同一用户对同一生日重复点击"开始咨询",后端直接返回已有的咨询记录 + 完整聊天历史,**不创建新记录**
|
|
|
+8. 同一用户对同一生日重复点击"开始咨询",后端直接返回已有的咨询记录 + 完整聊天历史,**不创建新记录**;前端 toast 提示"已找到您之前的咨询记录"
|
|
|
9. 输入的生日是**全新**生日时,前端弹出确认对话框:"此生日将开启全新的命盘咨询,确认吗?"
|
|
|
10. 用户确认后,后端计算完整的数字命盘(24个位置),创建新咨询记录,并返回结果
|
|
|
11. 用户取消确认,停留在首页,不跳转、不创建
|
|
|
@@ -169,12 +170,33 @@
|
|
|
**我希望** 点击三角形中的每个数字可以查看该位置的含义和能量解读
|
|
|
**以便** 快速向客户解释命盘
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(交互):**
|
|
|
+
|
|
|
+1. 点击三角形中任一数字卡片(A-X 任一位置),从屏幕底部弹出该位置的详细面板
|
|
|
+2. 点击效果分为两层:
|
|
|
+ - 轻点数字卡片 → 弹出解释面板
|
|
|
+ - 面板弹出时,数字卡片高亮状态(边框发光 + 放大 1.1 倍)
|
|
|
+3. 打开新面板时自动关闭前一个面板
|
|
|
+4. 关闭方式:点击面板外部遮罩区 / 点击关闭图标 / 再次点击同一数字
|
|
|
+5. 关闭面板后高亮状态取消
|
|
|
+
|
|
|
+**验收标准(面板内容):**
|
|
|
+
|
|
|
+6. 面板标题区域显示位置名称(如"主性格")、字母编号(如 O)、对应数字
|
|
|
+7. 面板内容按 Tab 切换展示:
|
|
|
+ - **Tab 1 - 含义**:该位置的核心能量含义(如"主性格:代表一个人与生俱来的天赋和性格特质")
|
|
|
+ - **Tab 2 - 特征**:该数字在该位置的具体性格/运势描述(如"O=7 代表分析力强、追求真理")
|
|
|
+ - **Tab 3 - 建议**:该位置该数字的注意事项和提升建议
|
|
|
+8. 面板底部显示数字的能量强弱 / 吉凶指示(如"吉数 ★★★★☆")
|
|
|
+9. 若该位置数字与相邻位置形成特定组合,面板顶部提示"该数字与 X 形成 XX 组合",可点击查看组合含义
|
|
|
+10. 面板内容中的"组合"和"特征"描述,后续可通过管理后台配置
|
|
|
|
|
|
-1. 点击三角形中的任一数字卡片,底部弹出该位置的解释面板
|
|
|
-2. 解释面板显示:位置名称(如"主性格")、数字、性格特质描述
|
|
|
-3. 再次点击或点击空白区域关闭面板
|
|
|
-4. 5区位置的描述文字可配置(后续通过后台修改)
|
|
|
+**验收标准(交互细节):**
|
|
|
+
|
|
|
+11. 面板高度不超过屏幕 60%,内容可滚动
|
|
|
+12. 面板弹出动画:从底部平滑滑入(300ms ease-out)
|
|
|
+13. 连续快速点击不同数字时,面板内容直接替换,不重复弹入动画
|
|
|
+14. 面板支持手势下滑关闭(drag-to-dismiss)
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -186,13 +208,41 @@
|
|
|
**我希望** 将命盘生成为一张精美的图片,分享到微信或保存到相册
|
|
|
**以便** 发给客户或在朋友圈展示
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(入口与权限):**
|
|
|
+
|
|
|
+1. 分享按钮位于命盘展示页底部,始终可见
|
|
|
+2. 点击分享按钮,底部弹出分享方式选择菜单:
|
|
|
+ - "保存到相册"
|
|
|
+ - "分享给微信好友"
|
|
|
+ - "分享到朋友圈"
|
|
|
+3. 免费用户每日限制分享 1 次,点击后显示剩余次数(如"今日还剩 1 次")
|
|
|
+4. 免费用户用完今日次数后,按钮置灰,提示"升级能量师享无限次分享"
|
|
|
+5. 已付费用户不限次数,不显示剩余次数
|
|
|
+
|
|
|
+**验收标准(分享卡片生成):**
|
|
|
|
|
|
-1. 分享按钮位于命盘展示页下方
|
|
|
-2. 点击"分享"按钮,生成包含命盘图+姓名+生日的分享卡片
|
|
|
-3. 分享卡片支持:保存到相册 / 分享给微信好友 / 分享到朋友圈
|
|
|
-4. 分享卡片设计精美,带有品牌水印(可选)
|
|
|
-5. 免费用户每日限制 1 次分享,已付费用户不限
|
|
|
+6. 分享卡片在客户端生成(使用 canvas 绘图),不依赖后端
|
|
|
+7. 卡片内容包含:
|
|
|
+ - 顶部:品牌 Logo + "数字能量命理分析" 标题
|
|
|
+ - 中部:三角命盘图(颜色和样式与 app 内一致)
|
|
|
+ - 底部:用户姓名 + 出生日期 + 生成日期
|
|
|
+ - 右下角:小字水印(平台名称/二维码)
|
|
|
+8. 卡片设计使用样式指南中的品牌色系统(主色 #B8860B / 金色系)
|
|
|
+9. 横向卡片比例 4:3,宽度适配主流手机屏幕(建议 1080px 基准)
|
|
|
+
|
|
|
+**验收标准(保存与分享):**
|
|
|
+
|
|
|
+10. 保存到相册:调用 `uni.saveImageToPhotosAlbum`,保存成功后 toast 提示"已保存到相册"
|
|
|
+11. 分享给微信好友:调用 `uni.share`(或小程序原生转发),携带卡片图片和默认文案"看看你的数字能量命盘"
|
|
|
+12. 分享到朋友圈:调用小程序端朋友圈分享 API(走官方渠道)
|
|
|
+13. 分享后返回 app 时,若为免费用户则扣除当日次数,显示更新后的剩余次数
|
|
|
+
|
|
|
+**验收标准(限制与风控):**
|
|
|
+
|
|
|
+14. 免费用户每日分享**到微信/朋友圈**的次数在服务端记录,防止客户端篡改
|
|
|
+15. 分享次数限制仅对"分享到微信/朋友圈"生效;**保存到相册**不限制次数(客户端canvas生成无法强控)
|
|
|
+16. 每日 0 点重置次数,后端接口 `POST /api/user/share-quota` 返回当日剩余次数
|
|
|
+17. 分享卡片不得包含用户微信号、手机号等敏感信息
|
|
|
|
|
|
### US-2.2 命盘PDF导出
|
|
|
|
|
|
@@ -200,13 +250,39 @@
|
|
|
**我希望** 将命盘导出为 PDF 文件,可以直接打印或微信发送
|
|
|
**以便** 客户获得正式的纸质/电子版报告
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(权限与入口):**
|
|
|
+
|
|
|
+1. "导出 PDF" 按钮位于命盘展示页顶部操作栏(仅已付费用户可见)
|
|
|
+2. 未付费用户点击不可见或置灰 + 提示"升级能量师可导出 PDF 报告"
|
|
|
+3. 点击后出现加载指示器(loading + 进度百分比),防止重复点击
|
|
|
+4. 生成过程不超过 5 秒,超过 5 秒则显示"生成较慢,请稍候…"
|
|
|
+
|
|
|
+**验收标准(PDF 内容与排版):**
|
|
|
|
|
|
-1. PDF 按钮位于命盘展示页(仅已付费用户可见)
|
|
|
-2. 点击后生成包含命盘三角形+姓名+生日+日期的 PDF
|
|
|
-3. PDF 使用 A4 竖版排版,适合打印
|
|
|
-4. 生成过程不超过 5 秒
|
|
|
-5. 生成后自动进入微信文件预览,支持转发给微信好友
|
|
|
+5. PDF 采用 A4 竖版(210mm × 297mm),页边距上下 15mm、左右 12mm
|
|
|
+6. 第一页内容按以下布局:
|
|
|
+ - 头部:品牌 Logo + "数字能量命理分析报告" 标题(居中)
|
|
|
+ - 副标题:生成日期 + 报告编号(格式:YYYYMMDD-XXXXX)
|
|
|
+ - 用户信息区:姓名 / 出生日期 / 主性格数字
|
|
|
+ - 三角命盘图:占页面 40% 高度,清晰可辨各位置数字
|
|
|
+ - 表格区:24 个位置的字母编号、数字值、位置名称三列展示
|
|
|
+ - 左中右三区标注:左侧(21-40 岁)/ 顶部(41-60 岁)/ 右侧(61+ 岁)
|
|
|
+7. PDF 使用品牌色系(金色 #B8860B 为标题色,深棕色 #4A3728 为正文字体)
|
|
|
+8. PDF 支持中文显示,字体嵌入(或使用系统黑体/宋体)
|
|
|
+9. 如有命盘批注内容(US-7.1),在 PDF 第二页以附录形式呈现
|
|
|
+
|
|
|
+**验收标准(导出流程):**
|
|
|
+
|
|
|
+10. PDF 由后端生成(通过 iText 或 Apache PDFBox 库),前端仅发起请求
|
|
|
+11. 前端调用 `POST /api/export/pdf` 传入 `chartId`,后端返回 PDF 文件流
|
|
|
+12. 前端接收文件流后,使用 `uni.openDocument` 打开微信文件预览
|
|
|
+13. 微信文件预览界面支持:转发给好友 / 保存到本地 / 发送到电脑
|
|
|
+14. 导出记录保存在数据库 `export_logs` 表,便于统计
|
|
|
+
|
|
|
+**验收标准(限制):**
|
|
|
+
|
|
|
+15. 已付费用户导出 PDF **不限制次数**
|
|
|
+16. 同一命盘重复导出不重新生成,直接返回已缓存的文件(缓存有效期 7 天)
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -221,18 +297,19 @@
|
|
|
**验收标准:**
|
|
|
|
|
|
1. 命盘展示页底部有"查看AI解读"按钮,点击跳转到AI解读页
|
|
|
-2. 解读内容由LLM生成,通过后端API调用,首次加载等待时间 < 5秒
|
|
|
-3. 加载过程中显示骨架屏或loading动画,避免用户以为卡死
|
|
|
-4. 解读内容至少包含以下章节:
|
|
|
+2. 解读内容通过 **Dify Workflow**(工作流)生成,技术架构详见**附录B**
|
|
|
+3. 前端调用后端 `POST /api/chart/interpret`,后端转发至 Dify Workflow API(`POST /v1/workflows/run`)
|
|
|
+4. 首次加载等待时间 < 10 秒(含 Dify Workflow 执行时间);超过 8 秒显示"AI 正在深度分析中,请稍候…"
|
|
|
+5. 加载过程中显示骨架屏或loading动画,避免用户以为卡死
|
|
|
+6. 解读内容至少包含以下章节:
|
|
|
- **主性格解读**:顶端数字的核心特质、性格描述、代表人物
|
|
|
- - **左区(0-20岁)**:早年运势、成长环境
|
|
|
- - **中区(20-40岁)**:中年事业、人际关系
|
|
|
- - **右区(40-60岁)**:晚年成就、财运趋势
|
|
|
- - **父源区**:父亲遗传、先天能量
|
|
|
- - **母源区**:母亲遗传、后天影响
|
|
|
-5. 每个章节独立卡片展示,可折叠展开
|
|
|
-6. 解读内容基于命盘的实际数字,同一数字对不同命盘解读不同(位置差异)
|
|
|
-7. 页面底部显示"本解读由AI生成,仅供参考"的免责声明
|
|
|
+ - **左区(21-40岁)**:早年运势、成长环境(对应 P/Q/R 位置)
|
|
|
+ - **顶部(41-60岁)**:中年事业、人际关系(对应 V/W/X 位置)
|
|
|
+ - **右区(61+岁)**:晚年成就、财运趋势(对应 S/T/U 位置)
|
|
|
+7. 每个章节独立卡片展示,可折叠展开
|
|
|
+8. 解读内容基于命盘的实际数字,同一数字对不同命盘解读不同(位置差异)
|
|
|
+9. 页面底部显示"本解读由AI生成,仅供参考"的免责声明
|
|
|
+10. Dify Workflow 输出解析:后端收到 Dify 返回的 `data.outputs` JSON 后,原样或稍作格式化后返回前端
|
|
|
|
|
|
### US-3.2 AI 解读的免费/付费控制
|
|
|
|
|
|
@@ -243,7 +320,7 @@
|
|
|
**验收标准:**
|
|
|
|
|
|
1. 未付费用户点击"查看AI解读"时,仅显示**主性格概要**(1段文字)
|
|
|
-2. 未付费用户每日可查看主性格概要 1 次
|
|
|
+2. 未付费用户每日可查看主性格概要 1 次(**此配额与 US-3.4 的 3 轮 AI 问答独立计数,互不消耗**)
|
|
|
3. 五区完整解读仅在已付费后可用(C端¥131或能量师¥1,314+)
|
|
|
4. 解读页底部显示"¥131 开通完整解读"引导卡片(免费用户可见)
|
|
|
5. 已付费用户可无限次查看完整解读
|
|
|
@@ -255,7 +332,7 @@
|
|
|
**我希望** 控制AI问答互动功能的免费次数,且限定在同一个命盘上
|
|
|
**以便** 防止用户通过切换生日绕过每日限制,同时保证体验清晰可预期
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(配额控制):**
|
|
|
|
|
|
1. 未付费用户每日可进行 3 轮 AI 问答互动(每日配额全局统一,不按命盘拆分)
|
|
|
2. 此 3 轮互动**绑定到当前咨询的命盘上**,用户不能通过创建多个生日命盘来获得额外免费次数
|
|
|
@@ -268,6 +345,16 @@
|
|
|
6. 超出每日次数后,AI 输入框和快捷问题按钮隐藏,显示引导卡片:"今日 AI 解读次数已用完,开通会员享无限次"
|
|
|
7. 每日次数在 `lastQuotaDate` 跨日时自动归零
|
|
|
|
|
|
+**验收标准(Dify Chatflow 集成):**
|
|
|
+
|
|
|
+8. 问答交互通过 **Dify Chatflow**(对话工作流)实现,详见**附录B**
|
|
|
+9. 前端调用 `POST /api/chat/send` 发送用户消息,传入 `{ chartId, message }`
|
|
|
+10. 后端 `ChatService` 将消息转发至 Dify Chatflow API(`POST /v1/chat-messages`)
|
|
|
+11. Chatflow 保持多轮对话上下文(通过 Dify 的 `conversation_id`),无需后端自行维护会话历史
|
|
|
+12. 后端在首次向 Dify 发送消息时,将命盘 24 个数字(A-X)作为 Chatflow 的 `inputs` 传入,后续轮次无需重复传入
|
|
|
+13. Dify Chatflow 返回的答案中,如果包含数字能量学专业术语,后端不做二次处理,直接透传
|
|
|
+14. 后端每次问答调用前检查用户配额(未付费用户当日≤3轮),超限则不调用 Dify,直接返回错误码
|
|
|
+
|
|
|
### US-3.3 解读内容缓存
|
|
|
|
|
|
**作为** 系统
|
|
|
@@ -278,8 +365,9 @@
|
|
|
|
|
|
1. 首次生成解读后,将解读内容与命盘ID绑定存储到数据库
|
|
|
2. 后续同一命盘再次查看解读时,直接从数据库读取,不调用LLM
|
|
|
-3. 用户自行重新生成解读时,覆盖旧的缓存内容
|
|
|
+3. 用户可在AI解读页右上角菜单中点击"重新生成解读",覆盖旧的缓存内容(重新调用 Dify Workflow)
|
|
|
4. 解读缓存永久保留,不自动过期
|
|
|
+5. 重新生成时弹出确认框:"重新生成将覆盖已有解读内容,确定吗?"
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -335,28 +423,131 @@
|
|
|
4. 续费操作按**标准价**执行(种子价仅限首次,不限能量师或C端)
|
|
|
5. 续费成功后有效期在原到期日基础上延长1年
|
|
|
|
|
|
+### US-4.4 年费升级能量师(升级定价与流程)
|
|
|
+
|
|
|
+**作为** C端年费用户
|
|
|
+**我希望** 从年费升级为能量师时,按已付年费的剩余价值抵扣差价
|
|
|
+**以便** 不需要重复支付已经买过的部分
|
|
|
+
|
|
|
+**验收标准(升级定价):**
|
|
|
+
|
|
|
+1. 用户现有 `vipType='annual'` 且 `vipEndTime > now`,可在个人中心点击"升级能量师"
|
|
|
+2. 升级价格由后端计算,公式:
|
|
|
+
|
|
|
+```
|
|
|
+已付年费金额 = 该用户最近一笔 annual 订单的 amount(默认 ¥131)
|
|
|
+已用天数 = 从 annual 支付成功日到当前日的天数
|
|
|
+剩余价值 = 已付年费金额 × (365 - 已用天数) / 365
|
|
|
+升级价格 = 当前能量师定价(种子/标准)− 剩余价值
|
|
|
+```
|
|
|
+
|
|
|
+3. 计算示例:用户 B 在 1月1日付 ¥131,第100天升级(种子价 ¥1,314):
|
|
|
+
|
|
|
+```
|
|
|
+剩余价值 = ¥131 × (365-100)/365 = ¥95.11
|
|
|
+升级价格 = ¥1,314 − ¥95.11 = ¥1,218.89
|
|
|
+```
|
|
|
+
|
|
|
+4. 升级价格 < 0(理论极限)→ 按 ¥0.01 收取
|
|
|
+5. 升级后 `vipType` 从 `'annual'` 变更为 `'practitioner'`
|
|
|
+6. 升级后 `vipEndTime` 按能量师续费规则处理(在原能量师到期日 +365天,不叠加年费剩余天数)
|
|
|
+7. 升级不享受种子价(种子价仅限首次购买 practitioner,见 US-4.2)
|
|
|
+8. 升级后推广码不变(如之前已有推广码)
|
|
|
+
|
|
|
+**验收标准(前端流程):**
|
|
|
+
|
|
|
+9. 个人中心 → 升级能量师 → 展示升级详情卡片:
|
|
|
+ - 原年费支付金额:¥131
|
|
|
+ - 年费剩余价值:¥95.11("已使用 100/365 天")
|
|
|
+ - 能量师当前定价:¥1,314
|
|
|
+ - 应付差价:¥1,218.89
|
|
|
+ - 支付按钮:"支付 ¥1,218.89"
|
|
|
+10. 升级详情卡片下方附带**权益对比**(精简表格),说明能量师相比年费额外获得的能力:推广能量师赚固定佣金(¥500+¥100)、客户批注与标签管理等
|
|
|
+11. 点击支付 → 调 `POST /api/pay/create` 传 `{ productType: 'practitioner', isUpgrade: true, previousOrderId: xxx }`
|
|
|
+12. 支付成功后调 `paySuccess()` → `vipType` 更新 + 佣金结算(见 US-6.3 升级场景)
|
|
|
+
|
|
|
+**验收标准(接口):**
|
|
|
+
|
|
|
+13. `POST /api/pricing/upgrade` 新增接口:传入 `userId`,返回升级价格详情
|
|
|
+14. `POST /api/pay/create` 新增字段:
|
|
|
+ - `isUpgrade: boolean`
|
|
|
+ - `previousOrderId: Long`(原年费订单ID,用于佣金补差)
|
|
|
+
|
|
|
---
|
|
|
|
|
|
-## EPIC 5:用户与历史(P1)
|
|
|
+## EPIC 5:用户注册与资料(P1)
|
|
|
|
|
|
-### US-5.1 微信一键登录
|
|
|
+### US-5.1 微信登录 + 注册信息完善
|
|
|
|
|
|
-**作为** 能量师
|
|
|
-**我希望** 使用微信一键登录
|
|
|
-**以便** 不需要注册账号,降低使用门槛
|
|
|
+**作为** 用户
|
|
|
+**我希望** 通过微信授权一键登录,随后补充生日和性别完成注册
|
|
|
+**以便** 使用命盘分析和未来的能量匹配社交功能
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(微信授权登录):**
|
|
|
+
|
|
|
+1. 首次使用点击登录按钮时,弹出微信授权(`uni.login` 获取 code)
|
|
|
+2. 授权后自动获取微信昵称和头像(`uni.getUserProfile`),用户可修改
|
|
|
+3. 用户拒绝授权昵称/头像时,仍然可以使用 code 登录,昵称默认为"微信用户"
|
|
|
+4. 后续使用自动登录(token 未过期时跳过授权)
|
|
|
+5. 首次登录后端返回 `{ token, isNewUser: true, profileIncomplete: true }`
|
|
|
+6. 老用户登录返回 `{ token, isNewUser: false, profileIncomplete: false }`
|
|
|
+7. 老用户(旧版未填生日/性别的)返回 `{ token, profileIncomplete: true }`,引导补全资料
|
|
|
+
|
|
|
+**验收标准(注册信息完善页):**
|
|
|
+
|
|
|
+8. 新用户或资料不全的用户,微信授权后自动跳转到**注册完善页**(非首页)
|
|
|
+9. 注册完善页表单包含以下字段:
|
|
|
|
|
|
-1. 首次使用点击"生成命盘"时弹出微信授权
|
|
|
-2. 授权后自动完成注册,无需填写额外信息
|
|
|
-3. 后续使用自动登录
|
|
|
-4. 用户信息存储在数据库中
|
|
|
+| 字段 | 必填 | 预填 | 说明 |
|
|
|
+|------|------|------|------|
|
|
|
+| 头像 | 是 | 微信头像 | 可点击更换(从相册选择) |
|
|
|
+| 昵称 | 是 | 微信昵称 | 1-20 字 |
|
|
|
+| 性别 | 是 | 空 | 男 / 女,radio 选择 |
|
|
|
+| 出生日期 | 是 | 空 | 年月日选择器,同命盘生日 |
|
|
|
+| 个人简介 | 否 | 空 | 限 100 字,用于社交展示 |
|
|
|
+| 所在城市 | 否 | 空 | 微信定位或手动选择 |
|
|
|
+| 兴趣标签 | 否 | 空 | 多选:读书/运动/音乐/旅行/禅修/创业/心理学/玄学 |
|
|
|
+| 想认识 | 否 | 空 | 单选:不限 / 朋友 / 导师 / 同修 |
|
|
|
+
|
|
|
+10. 点击"提交"调用 `POST /api/profile/complete` 保存所有资料
|
|
|
+11. 提交后标记用户 `profile_complete = true`
|
|
|
+12. 提交成功后跳转到首页,进入正常使用流程
|
|
|
+13. 资料不完整的用户在个人中心显示引导 banner:"请完善个人资料,开启能量匹配"
|
|
|
+14. 用户可随时在个人中心 → 编辑资料 修改所有字段
|
|
|
+
|
|
|
+**验收标准(后端与数据库变更):**
|
|
|
+
|
|
|
+15. `users` 表新增字段:
|
|
|
+
|
|
|
+| 字段 | 类型 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| `gender` | `TINYINT` | 0=未知, 1=男, 2=女 |
|
|
|
+| `birth_date` | `DATE` | 出生日期(用于命盘+社交) |
|
|
|
+| `bio` | `VARCHAR(200)` | 个人简介 |
|
|
|
+| `city` | `VARCHAR(50)` | 所在城市 |
|
|
|
+| `tags` | `VARCHAR(200)` | 兴趣标签,逗号分隔 |
|
|
|
+| `looking_for` | `TINYINT` | 0=不限, 1=朋友, 2=导师, 3=同修 |
|
|
|
+| `profile_complete` | `TINYINT(1)` | 0=资料未完善, 1=资料已完善 |
|
|
|
+| `birth_year` | `INT` | 出生年份(冗余,从 birth_date 提取) |
|
|
|
+| `birth_month` | `INT` | 出生月份(冗余) |
|
|
|
+| `birth_day` | `INT` | 出生日期(冗余) |
|
|
|
+
|
|
|
+16. `POST /api/auth/login` 响应增加 `profileIncomplete` 字段
|
|
|
+17. 新增 `POST /api/profile/complete` 接口,接收所有注册字段
|
|
|
+18. 新增 `POST /api/profile/update` 接口,允许修改任意字段
|
|
|
+19. `POST /api/profile/info` 响应增加全部新字段
|
|
|
+
|
|
|
+**验收标准(老用户兼容):**
|
|
|
+
|
|
|
+20. 已注册的老用户登录时,如果 `profile_complete = false`,登录后显示完善引导
|
|
|
+21. 老用户不强制立即完善,可以正常使用命盘功能
|
|
|
+22. 老用户在个人中心中看到"完善资料"入口和引导
|
|
|
|
|
|
### US-5.2 历史咨询记录
|
|
|
|
|
|
**作为** 能量师
|
|
|
**我希望** 查看我过去的所有咨询记录
|
|
|
-**以便** 回顾和继续之前的咨询
|
|
|
+**以便** 回顾和继续之前的咨询
|
|
|
|
|
|
**验收标准:**
|
|
|
|
|
|
@@ -368,6 +559,23 @@
|
|
|
6. 同一用户+同一生日永远返回同一条咨询记录(`(userId, birthday)` 联合唯一)
|
|
|
7. 免费用户仅能看到近 7 天记录,已付费用户可见全部
|
|
|
|
|
|
+### US-5.3 个人资料编辑(为陌生社交准备)
|
|
|
+
|
|
|
+**作为** 用户
|
|
|
+**我希望** 在个人中心编辑我的昵称、头像、简介、标签、城市等资料
|
|
|
+**以便** 未来通过能量匹配结识志同道合的朋友
|
|
|
+
|
|
|
+**验收标准:**
|
|
|
+
|
|
|
+1. 个人中心新增"编辑资料"入口
|
|
|
+2. 编辑页包含:头像、昵称、性别、生日、简介、城市、兴趣标签、想认识
|
|
|
+3. 资料字段定义同 US-5.1 注册完善页
|
|
|
+4. 修改后调用 `POST /api/profile/update`
|
|
|
+5. 修改成功后本地更新并提示"保存成功"
|
|
|
+6. **陌生社交广场和能量匹配功能不属于 Phase 1,此处仅预留用户资料字段**
|
|
|
+
|
|
|
+注:能量匹配社交将根据用户的命盘主性格数(O)、外部三组数(R/U/X)等计算能量兼容度,推荐匹配用户。此功能在 Phase 2 规划。
|
|
|
+
|
|
|
---
|
|
|
|
|
|
## EPIC 6:分销推广与佣金(P0-P1)
|
|
|
@@ -405,7 +613,7 @@
|
|
|
**前端缓存策略:**
|
|
|
3. 用户通过链接打开小程序时:
|
|
|
- `onLaunch(options)` 读取 `options.query.ref`,转为大写后写入缓存 `pending_referrer`
|
|
|
- - 不覆盖已有 `pending_referrer`,以用户**最后一次点击的链接**为准
|
|
|
+ - **每次点击新链接都覆盖**已有值,以用户**最后一次点击的链接**为准(新点击意图覆盖旧的)
|
|
|
4. `pending_referrer` **永不过期**,直到注册成功后才清除
|
|
|
5. 用户注册(微信授权登录)时,从缓存读取 `pending_referrer` 传入注册接口
|
|
|
|
|
|
@@ -437,32 +645,89 @@
|
|
|
**验收标准:**
|
|
|
|
|
|
**触发条件:**
|
|
|
+
|
|
|
1. 订单 `productType = "practitioner"` 且支付成功 → 进入 B端佣金结算流程
|
|
|
2. 订单 `productType = "annual"` → 走 US-6.4 C端佣金(互斥分支)
|
|
|
|
|
|
-**佣金计算:**
|
|
|
-3. 一级佣金(L1,直接上级):**固定金额**,从 `sys_config` 读取 `commission.practitioner.l1`(默认 ¥500 = 50000分)
|
|
|
-4. 二级佣金(L2,上上级):**固定金额**,从 `sys_config` 读取 `commission.practitioner.l2`(默认 ¥100 = 10000分)
|
|
|
-5. 佣金单位为**分**(避免浮点精度问题)
|
|
|
+**佣金计算——按推荐人身份分两种情况:**
|
|
|
+
|
|
|
+3. **推荐人 A 是能量师(`vipType='practitioner'`)** → 按标准固定金额:
|
|
|
+
|
|
|
+| 级别 | 默认值 | 配置键 |
|
|
|
+|------|--------|--------|
|
|
|
+| L1(直接上级) | ¥500 | `commission.practitioner.l1` |
|
|
|
+| L2(上上级) | ¥100 | `commission.practitioner.l2` |
|
|
|
+
|
|
|
+4. **推荐人 A 是 C端年费用户(`vipType='annual'`)** → L1 拿半额:
|
|
|
+
|
|
|
+| 级别 | 默认值 | 配置键 |
|
|
|
+|------|--------|--------|
|
|
|
+| L1(直接上级) | ¥200 | `commission.practitioner.l1_cend` |
|
|
|
+| L2(上上级) | ¥100(不变) | `commission.practitioner.l2` |
|
|
|
+
|
|
|
+5. 推荐人 A 既不是能量师也不是 C端年费(`vipType=null` 等异常情况)→ L1/L2 不创建佣金
|
|
|
+6. 佣金单位为**分**(避免浮点精度问题)
|
|
|
+
|
|
|
+**升级场景佣金补差(`isUpgrade=true`):**
|
|
|
+
|
|
|
+7. 当订单标记 `isUpgrade=true`(从年费升级到能量师),L1/L2 佣金需**扣除**已支付过的年费佣金:
|
|
|
+
|
|
|
+```
|
|
|
+应发佣金 = 本次应发金额 − 该买家此前 annual 订单已支付给同一收款人的佣金总额
|
|
|
+```
|
|
|
+
|
|
|
+8. 计算逻辑:
|
|
|
+ - 查询 `commissions` 表中,同一 `buyer_id` + 同一 `收款人` 且 `product_type='annual'` 的所有佣金之和
|
|
|
+ - 从本次 practitioner 佣金中减去该金额
|
|
|
+ - 若差值 ≤ 0(理论情况),则本条佣金不创建
|
|
|
+
|
|
|
+9. 示例——首次直接购买能量师(非升级,对比参考):
|
|
|
+
|
|
|
+```
|
|
|
+用户C为新用户(无年费记录),通过上级A(能量师)链接直接购买能量师 ¥1,314
|
|
|
+isUpgrade = false → 全额发放:L1 = ¥500,L2 = ¥100
|
|
|
+无年费佣金可扣除
|
|
|
+```
|
|
|
+
|
|
|
+10. 示例——年费升级补差:
|
|
|
+
|
|
|
+```
|
|
|
+用户B第1天付¥131(annual),上级A获¥52.40(40%)
|
|
|
+用户B第100天升级能量师(种子价¥1,314),上级A是能量师→应发¥500
|
|
|
+实际发放:¥500 − ¥52.40 = ¥447.60
|
|
|
+```
|
|
|
+
|
|
|
+10. 示例——C端推荐人升级补差:
|
|
|
+
|
|
|
+```
|
|
|
+用户B第1天付¥131(annual),上级A(C端)获¥52.40(40%)
|
|
|
+用户B第100天升级能量师,上级A是C端→应发半额¥200
|
|
|
+实际发放:¥200 − ¥52.40 = ¥147.60
|
|
|
+```
|
|
|
|
|
|
**收款人资格:**
|
|
|
-6. L1:`buyer.invitedBy` 对应的上级存在 → 创建佣金(不需要校验VIP是否有效)
|
|
|
-7. L2:上级的 `invitedBy` 对应的上上级存在 → 创建佣金
|
|
|
-8. 收款人不存在时 → 静默跳过,不报错
|
|
|
+
|
|
|
+11. L1:`buyer.invitedBy` 对应的上级存在 → 按上述规则计算
|
|
|
+12. L2:上级的 `invitedBy` 对应的上上级存在 → 按上述规则计算(L2 不因身份打折,仅 L1 打折)
|
|
|
+13. 收款人不存在时 → 静默跳过,不报错
|
|
|
|
|
|
**状态与幂等:**
|
|
|
-9. 佣金 `status` 直接写入 `"settled"`(即时到账,无 pending 冷静期)
|
|
|
-10. 同一 `outTradeNo` 重复回调 → 幂等处理,不创建重复佣金
|
|
|
-11. 佣金金额固定的另一层含义:**不受种子价/标准价差异影响**,¥500/¥100 固定不变
|
|
|
+
|
|
|
+14. 佣金 `status` 直接写入 `"settled"`(即时到账,无 pending 冷静期)
|
|
|
+15. 同一 `outTradeNo` 重复回调 → 幂等处理,不创建重复佣金
|
|
|
+16. 佣金固定金额不受种子价/标准价差异影响(C端半额同样固定)
|
|
|
|
|
|
**统计更新:**
|
|
|
-12. L1 创建时:`inviter.directCount += 1`,`inviter.convertedCount += 1`
|
|
|
-13. L2 创建时:`inviter2.indirectCount += 1`
|
|
|
+
|
|
|
+17. L1 创建时:`inviter.directCount += 1`,`inviter.convertedCount += 1`
|
|
|
+18. L2 创建时:`inviter2.indirectCount += 1`
|
|
|
|
|
|
**配置项(后台可配):**
|
|
|
+
|
|
|
| 配置键 | 默认值 | 说明 |
|
|
|
|--------|--------|------|
|
|
|
-| `commission.practitioner.l1` | `50000` | B端一级佣金(分) |
|
|
|
+| `commission.practitioner.l1` | `50000` | B端一级佣金—能量师推荐(分) |
|
|
|
+| `commission.practitioner.l1_cend` | `20000` | B端一级佣金—C端推荐(分) |
|
|
|
| `commission.practitioner.l2` | `10000` | B端二级佣金(分) |
|
|
|
|
|
|
---
|
|
|
@@ -483,6 +748,9 @@
|
|
|
3. 上级佣金(L2):`totalFee × upstreamRate / 10000`,从 `sys_config` 读取 `commission.annual.upstream_rate`(默认 `500` = 5%)
|
|
|
4. 金额计算使用**整数截断**(非四舍五入),剩余零头归平台
|
|
|
|
|
|
+> **注意**:年费佣金在后续用户升级能量师时可能被部分抵扣(见 US-6.3 升级补差逻辑)。`paySuccess()` 记录原始佣金(用于后续补差计算),补差逻辑在升级时执行。<br>
|
|
|
+> 因此 C端佣金的 `status` 仍直接写入 `"settled"`,不需要等待升级再结算。若后续升级,再由 US-6.3 扣除已付金额。
|
|
|
+
|
|
|
**收款人资格(与 B端不同):**
|
|
|
5. L1:`buyer.invitedBy` 对应的上级**必须已付费**(`referralCode != null`),才创建佣金
|
|
|
6. L2:上级的 `invitedBy` 对应的上上级**必须已付费**(`referralCode != null`),才创建佣金
|
|
|
@@ -533,7 +801,7 @@
|
|
|
|
|
|
**② 收益统计卡片(三列等宽):**
|
|
|
7. 总收益:累计所有佣金总额(`status = settled`)
|
|
|
-8. 可提现:当前可提现金额(与总收益相同,Phase 1 不做提现扣除)
|
|
|
+8. **累计收益**:当前总收益金额(Phase 1 不提现,故不称"可提现"以免误解;页面加注"提现功能即将开放")
|
|
|
9. 今日新增:当日 00:00 至今产生的佣金总额
|
|
|
10. 金额以元为单位,保留两位小数(后端存储分,前端 `/100`)
|
|
|
|
|
|
@@ -602,9 +870,7 @@
|
|
|
**后端适应:**
|
|
|
12. Order 新增 `productType` 字段(`"annual"` | `"practitioner"`)
|
|
|
13. User 新增 `vipType` 字段(`"annual"` | `"practitioner"` | `null`)
|
|
|
-14. `paySuccess()` 按 `productType` 分支佣金逻辑:
|
|
|
- - `practitioner` → US-6.3 固定金额
|
|
|
- - `annual` → US-6.4 比例分成
|
|
|
+14. `paySuccess()` 佣金结算按 `productType` 分支:`annual` → US-6.4;`practitioner` → US-6.3(含推荐人身份判断 + isUpgrade 补差),详见 US-6.3 验收标准
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -616,13 +882,48 @@
|
|
|
**我希望** 在命盘图上添加文字批注或标记
|
|
|
**以便** 为每个客户记录个性化的解读要点
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(入口与权限):**
|
|
|
|
|
|
-1. 在命盘展示页添加"编辑批注"按钮(仅已付费用户可见)
|
|
|
-2. 点击后进入批注模式,可添加自由文本
|
|
|
-3. 批注内容保存后,下次查看该命盘时依然可见
|
|
|
-4. 批注支持简单的富文本(分段、加粗等)
|
|
|
-5. 导出的 PDF 中可包含批注内容
|
|
|
+1. "编辑批注"按钮位于命盘展示页右上角菜单中(仅已付费用户可见)
|
|
|
+2. 未付费用户看不到该按钮
|
|
|
+3. **批注模式建议方案(开发选其一):**
|
|
|
+ - **方案A(推荐)**:在命盘页面底部展开批注编辑面板,命盘操作和数字点击互不干扰,无需切换模式。用户点击数字后可快速插入 `【位置X】` 标签到批注文本
|
|
|
+ - **方案B(备选)**:点击"编辑批注"进入专用模式,命盘页面其他操作暂时禁用,底部显示批注编辑区域
|
|
|
+4. 批注内容支持富文本(加粗、斜体、分段、列表),最大 2000 字
|
|
|
+5. 批注内容与 `chartId` 绑定,不同命盘各自独立
|
|
|
+6. 批注支持按命盘位置打标签,格式示例:`【主性格O】天生领导者,数字1能量突出`
|
|
|
+7. 同一位置的多条批注自动折叠,点击展开
|
|
|
+8. 保存批注调用 `POST /api/chart/annotation/save`,传入 `chartId` + `content`
|
|
|
+9. 保存成功后 toast 提示"批注已保存",编辑区域收起
|
|
|
+10. 取消编辑时,若有未保存内容,弹出确认框"有未保存的内容,确定放弃?"
|
|
|
+
|
|
|
+**验收标准(批注展示):**
|
|
|
+
|
|
|
+11. 已有批注的命盘,在数字卡片上方显示小黄点标记(🟡)
|
|
|
+12. 退出批注模式后,命盘页底部显示批注摘要区域(展开/折叠),显示最近 3 条批注
|
|
|
+13. 点击"查看全部批注"跳到批注完整列表页
|
|
|
+14. 批注列表页按位置分组,按创建时间倒序排列
|
|
|
+15. 导出的 PDF(US-2.2)第二页包含批注内容
|
|
|
+16. 批注支持删除(长按批注 → 确认删除)
|
|
|
+
|
|
|
+**验收标准(后端与存储):**
|
|
|
+
|
|
|
+17. 新增 `chart_annotations` 表:
|
|
|
+
|
|
|
+| 字段 | 类型 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| `id` | `BIGINT PK` | 主键 |
|
|
|
+| `chart_id` | `BIGINT` | 关联命盘记录 |
|
|
|
+| `user_id` | `BIGINT` | 批注人(能量师) |
|
|
|
+| `position` | `VARCHAR(2)` | 关联位置字母(A-X),可为 null |
|
|
|
+| `content` | `TEXT` | 批注内容(富文本 HTML) |
|
|
|
+| `created_at` | `DATETIME` | 创建时间 |
|
|
|
+| `updated_at` | `DATETIME` | 最后修改时间 |
|
|
|
+
|
|
|
+18. 新增接口:
|
|
|
+ - `POST /api/annotation/save` — 保存/更新批注
|
|
|
+ - `POST /api/annotation/list` — 获取命盘批注列表(按 chartId)
|
|
|
+ - `POST /api/annotation/delete` — 删除单条批注
|
|
|
|
|
|
### US-7.2 客户标签分组
|
|
|
|
|
|
@@ -630,12 +931,60 @@
|
|
|
**我希望** 为命盘记录添加简单的标签或分组
|
|
|
**以便** 对客户进行分类管理
|
|
|
|
|
|
-**验收标准:**
|
|
|
+**验收标准(标签创建与选择):**
|
|
|
+
|
|
|
+1. 发起咨询时(生日输入页确认弹窗中)显示"添加标签(选填)"区域
|
|
|
+2. 标签区域包含:标签输入框 + "新建"按钮 + 已创建的标签列表(可点击选择)
|
|
|
+3. 新建标签:输入 2-8 字,自动分配随机颜色,点击确定后存入用户标签库
|
|
|
+4. 已有标签以胶囊样式展示:`[🟢 老客户]` `[🟠 朋友推荐]` `[🔵 线上引流]`
|
|
|
+5. 一个命盘最多绑 3 个标签,超出提示"最多选择 3 个标签"
|
|
|
+
|
|
|
+**验收标准(标签展示与筛选):**
|
|
|
+
|
|
|
+6. 命盘列表中,每条记录右侧展示标签胶囊
|
|
|
+7. 历史列表顶部增加标签筛选栏,可选择一个或多个标签组合筛选:
|
|
|
+ - 未选择任何标签时:显示所有记录
|
|
|
+ - 选择标签时:AND 逻辑(同时包含所有选中标签的记录)
|
|
|
+ - 支持"全部"按钮一键清除筛选
|
|
|
+8. 已打标签的命盘记录,在列表中有标签标识,方便快速识别
|
|
|
+
|
|
|
+**验收标准(标签管理):**
|
|
|
+
|
|
|
+9. 个人中心 → 我的标签:展示该能量师创建的所有标签
|
|
|
+10. 标签管理操作:
|
|
|
+ - 编辑标签名称
|
|
|
+ - 修改标签颜色(从预设 8 色中选择)
|
|
|
+ - 删除标签(删除后将移除所有关联命盘上的该标签)
|
|
|
+11. 删除标签时弹出确认:"删除后,所有关联命盘上的该标签将被移除,确定?"
|
|
|
+
|
|
|
+**验收标准(后端与存储):**
|
|
|
+
|
|
|
+12. 新增 `user_labels` 表:
|
|
|
|
|
|
-1. 创建命盘时可选择已有标签或新建标签
|
|
|
-2. 标签以颜色 + 文字形式展示
|
|
|
-3. 历史列表支持按标签筛选
|
|
|
-4. 标签管理:新增、编辑、删除
|
|
|
+| 字段 | 类型 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| `id` | `BIGINT PK` | 主键 |
|
|
|
+| `user_id` | `BIGINT` | 能量师 ID |
|
|
|
+| `name` | `VARCHAR(20)` | 标签名称 |
|
|
|
+| `color` | `VARCHAR(7)` | 颜色值(如 #4CAF50) |
|
|
|
+| `created_at` | `DATETIME` | 创建时间 |
|
|
|
+
|
|
|
+13. 新建关联表 `chart_labels`(命盘-标签多对多):
|
|
|
+
|
|
|
+| 字段 | 类型 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| `id` | `BIGINT PK` | 主键 |
|
|
|
+| `chart_id` | `BIGINT` | 命盘记录 ID |
|
|
|
+| `label_id` | `BIGINT` | 标签 ID |
|
|
|
+| `created_at` | `DATETIME` | 关联时间 |
|
|
|
+
|
|
|
+14. 新增接口:
|
|
|
+ - `POST /api/label/create` — 新建标签
|
|
|
+ - `POST /api/label/list` — 获取标签列表
|
|
|
+ - `POST /api/label/update` — 编辑标签名称/颜色
|
|
|
+ - `POST /api/label/delete` — 删除标签
|
|
|
+ - `POST /api/chart/label/set` — 为命盘设置标签
|
|
|
+ - `POST /api/chart/label/list` — 获取命盘标签列表(按 chartId)
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -703,7 +1052,9 @@ CREATE TABLE `sys_config` (
|
|
|
|
|
|
**管理后台页面(`src/views/settings/index.vue`):**
|
|
|
11. 左侧菜单新增"系统配置"入口,路由 `/settings`,图标 ⚙️
|
|
|
-12. 页面分为三个卡片区域,每个卡片顶部有"恢复默认值"按钮(仅重置单个卡片内的字段)
|
|
|
+12. 页面分为三个卡片区域,每个卡片顶部有"恢复初始值"按钮(仅重置单个卡片内的字段为种子数据):
|
|
|
+ - hover 时 tooltip 显示具体初始值(如"恢复为 ¥500")
|
|
|
+ - 点击后弹出确认框:"将恢复本卡片内所有字段为初始值,确定吗?"
|
|
|
|
|
|
**定价配置卡片:**
|
|
|
13. 四个输入项:能量师种子价、标准价、种子价名额上限、C端年费
|
|
|
@@ -712,10 +1063,14 @@ CREATE TABLE `sys_config` (
|
|
|
16. 修改数量时,"已使用"比例随之动态变化
|
|
|
|
|
|
**B端佣金配置卡片:**
|
|
|
-17. 两个输入项:L1 佣金(¥500)、L2 佣金(¥100)
|
|
|
+17. **三个输入项**:
|
|
|
+ - L1 佣金—能量师推荐(¥500)
|
|
|
+ - L1 佣金—C端推荐(¥200,新增)
|
|
|
+ - L2 佣金(¥100,不限推荐人身份)
|
|
|
18. 输入单位为元(整数),提交时 ×100 转为分
|
|
|
-19. 下方实时显示比例计算:
|
|
|
- - "L1 ¥500 = 种子价 38.1% / 标准价 25.2%"
|
|
|
+19. 每个输入项下方实时显示比例计算:
|
|
|
+ - "L1(能量师推荐)¥500 = 种子价 38.1% / 标准价 25.2%"
|
|
|
+ - "L1(C端推荐)¥200 = 种子价 15.2% / 标准价 10.1%"
|
|
|
- "L2 ¥100 = 种子价 7.6% / 标准价 5.0%"
|
|
|
20. 比例随定价或佣金值的修改**实时联动更新**
|
|
|
|
|
|
@@ -865,7 +1220,8 @@ settings/index.vue
|
|
|
│ ├── el-form-item: 种子价名额上限 → el-input-number(min=1, max=99999, step=50)
|
|
|
│ └── el-form-item: C端年费 → el-input-number(...)
|
|
|
├── el-card (B端佣金配置)
|
|
|
-│ ├── el-form-item: L1 佣金 → el-input-number
|
|
|
+│ ├── el-form-item: L1 佣金(能量师推荐)→ el-input-number
|
|
|
+│ ├── el-form-item: L1 佣金(C端推荐)→ el-input-number
|
|
|
│ ├── el-form-item: L2 佣金 → el-input-number
|
|
|
│ └── 实时比例显示
|
|
|
└── el-card (C端佣金配置)
|
|
|
@@ -892,7 +1248,8 @@ INSERT INTO `sys_config` (`config_key`, `config_value`, `description`, `value_ty
|
|
|
('pricing.practitioner.standard', '198600', '能量师标准价(分)', 'price'),
|
|
|
('pricing.practitioner.seed_limit', '300', '种子价名额上限', 'int'),
|
|
|
('pricing.annual', '13100', 'C端年费(分)', 'price'),
|
|
|
-('commission.practitioner.l1', '50000', 'B端一级佣金(分)', 'price'),
|
|
|
+('commission.practitioner.l1', '50000', 'B端一级佣金-能量师推荐(分)', 'price'),
|
|
|
+('commission.practitioner.l1_cend', '20000', 'B端一级佣金-C端推荐(分)', 'price'),
|
|
|
('commission.practitioner.l2', '10000', 'B端二级佣金(分)', 'price'),
|
|
|
('commission.annual.direct_rate', '4000', 'C端直接佣金比例(万分比)', 'percent'),
|
|
|
('commission.annual.upstream_rate', '500', 'C端上级佣金比例(万分比)', 'percent');
|
|
|
@@ -904,7 +1261,7 @@ INSERT INTO `sys_config` (`config_key`, `config_value`, `description`, `value_ty
|
|
|
|
|
|
| # | 场景 | 步骤 | 预期 |
|
|
|
|---|------|------|------|
|
|
|
-| 1 | 初始加载 | 打开系统配置页 | 8个字段显示正确的默认值 |
|
|
|
+| 1 | 初始加载 | 打开系统配置页 | 9个字段显示正确的默认值 |
|
|
|
| 2 | 修改定价 | 种子价改为 ¥2,000 → 保存 | 下次 `POST /api/pricing/current` 返回 seedPrice=200000 |
|
|
|
| 3 | 修改佣金 | L1 改为 ¥600 → 保存 | 新订单的佣金 amount=60000 |
|
|
|
| 4 | 比例联动 | 直接佣金改为 50% | 下方显示"每笔¥131:直接¥65.50 / 上级¥6.55 / 平台¥58.95" |
|
|
|
@@ -1093,18 +1450,20 @@ INSERT INTO `sys_config` (`config_key`, `config_value`, `description`, `value_ty
|
|
|
| US-1.4 数字点击查看含义 | P2 | 1天 | US-1.2 |
|
|
|
| US-2.1 分享图片 | P0 | 2天 | US-1.2 |
|
|
|
| US-2.2 PDF导出 | P0 | 2天 | US-1.2 |
|
|
|
-| US-3.1 AI解读展示 | P0 | 3天 | US-1.1 + LLM API接入 |
|
|
|
+| US-3.1 AI解读展示 | P0 | 2天 | US-1.1 + Dify Workflow配置(附录B) |
|
|
|
| US-3.2 AI解读免费/付费控制 | P0 | 1天 | US-3.1 |
|
|
|
| US-3.3 解读内容缓存 | P0 | 1天 | US-3.1 |
|
|
|
-| US-3.4 AI交互问答(免费/付费控制) | P0 | 1天 | US-1.1 |
|
|
|
+| US-3.4 AI交互问答(免费/付费控制) | P0 | 2天 | US-1.1 + Dify Chatflow配置(附录B) |
|
|
|
| US-4.1 能量师付费订阅 | P0 | 2天 | US-5.1 |
|
|
|
| US-4.2 种子价自动判断 | P0 | 1天 | US-8.1 |
|
|
|
| US-4.3 订阅状态与续费 | P0 | 1天 | US-4.1 |
|
|
|
-| US-5.1 微信登录 | P1 | 2天 | 无 |
|
|
|
+| US-4.4 年费升级能量师(升级定价) | P1 | 1.5天 | US-4.1 + US-4.2 |
|
|
|
+| US-5.1 微信登录+注册信息完善 | P1 | 3天 | 无 |
|
|
|
| US-5.2 历史咨询记录 | P1 | 2天 | US-5.1 |
|
|
|
+| US-5.3 个人资料编辑(社交预留) | P2 | 1天 | US-5.1 |
|
|
|
| US-6.1 推广码生成 | P0 | 1天 | US-4.1 |
|
|
|
| US-6.2 分享带参注册与上下级绑定 | P0 | 2天 | US-5.1 |
|
|
|
-| US-6.3 B端佣金结算 | P0 | 2天 | US-4.1 + US-6.2 + US-8.1 |
|
|
|
+| US-6.3 B端佣金结算(含升级补差+C端半额) | P0 | 3天 | US-4.1 + US-6.2 + US-4.4 + US-8.1 |
|
|
|
| US-6.4 C端佣金结算 | P0 | 1天 | US-6.6 + US-6.3 + US-8.1 |
|
|
|
| US-6.5 分销面板 | P1 | 2天 | US-6.1 + US-6.3 |
|
|
|
| US-6.6 C端年费订阅入口 | P0 | 1.5天 | US-3.2 + US-4.1 |
|
|
|
@@ -1163,13 +1522,18 @@ US-6.5 分销面板(前端展示所有数据)
|
|
|
|
|
|
| 周次 | 交付内容 |
|
|
|
|------|---------|
|
|
|
-| **Week 1** | US-8.1 系统配置 → US-4.2 种子价 → US-4.1 能量师付费 |
|
|
|
-| **Week 2** | US-6.2 带参注册 → US-6.1 推广码 → US-6.3 B端佣金 |
|
|
|
-| **Week 3** | US-6.6 C端订阅入口 → US-6.4 C端佣金 → US-6.5 分销面板 |
|
|
|
-| **Week 4** | 联调测试 + 管理后台补全(US-8.2 / US-8.3)+ BUG修复 |
|
|
|
-
|
|
|
-> **Phase 1 分销核心 P0 合计:约 10天(2周)**
|
|
|
-> 加上命盘、AI解读、支付等已有模块联调,总计约 4周。
|
|
|
+| **Week 1** | US-5.1 登录+注册完善 → US-8.1 系统配置(独立基础设施) |
|
|
|
+| **Week 2** | US-1.1 咨询发起(依赖US-5.1登录) → US-1.2 三角可视化 → US-1.3 计算规则实现(附录A Step 1-6) |
|
|
|
+| **Week 3** | US-3.1 AI解读 + Dify Workflow配置(附录B) → US-3.3 缓存 → US-3.2 免费/付费控制 |
|
|
|
+| **Week 4** | US-3.4 AI问答 + Dify Chatflow配置(附录B) → US-2.1 分享图片 → US-2.2 PDF导出 |
|
|
|
+| **Week 5** | US-4.1 能量师付费 + US-4.2 种子价 + US-6.6 C端订阅入口 |
|
|
|
+| **Week 6** | US-6.2 带参注册 → US-6.1 推广码 → US-6.3 B端佣金(含升级补差) |
|
|
|
+| **Week 7** | US-6.4 C端佣金 → US-6.5 分销面板 + US-8.2 订单管理 |
|
|
|
+| **Week 8** | 联调测试 + US-8.3 佣金查看 + US-4.3 订阅状态/续费 + US-4.4 升级能量师 + BUG修复 |
|
|
|
+
|
|
|
+> **Phase 1 总预估:约 8 周(含联调测试)**
|
|
|
+> 排期原则:先做核心流程(登录→命盘→AI),再做支付分销。US-8.1(配置系统)作为基础设施优先完成,保障后续所有定价依赖。
|
|
|
+> P2 功能(US-1.4 数字点击含义 / US-5.3 资料编辑 / US-7.x 批注与标签)可在 Phase 1 后期或 Phase 2 迭代。
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -1183,11 +1547,13 @@ US-6.5 分销面板(前端展示所有数据)
|
|
|
|------|---------|---------|
|
|
|
| `CalculatorService.java` | 重写 | 内部7位从 `F,G,H,I,M,N,O` → `I,J,K,L,M,N,O`;新增外部9位 `P,Q,R,S,T,U,V,W,X` 的独立计算;新增 `calculateFullTriangle()` 返回全部24个位置 |
|
|
|
| `ChartService.java` | 改造 | 新增 `startConsultation(userId, birthday, name, questions)` 方法,含:①查 userId+birthday 是否已有记录;②已有则直接返回+聊天历史;③无则服务器端调 `CalculatorService` 计算+创建记录+可选首次AI解读 |
|
|
|
-| `ChartController.java` | 改造 | 保留 `/api/chart/create`(兼容旧版);新增 `POST /api/chart/start` → 调 `startConsultation()` |
|
|
|
+| `ChartController.java` | 改造 | 保留 `/api/chart/create`(兼容旧版);**新增 `POST /api/consultation/start` → 调 `ChartService.startConsultation()`** |
|
|
|
| `ChartRecord.java` | 微调 | 新增 `lastInteractionAt` 字段(`LocalDateTime`,用于列表排序);加 `@Table(uniqueConstraints=...)` 定义 `(userId, birthday)` 联合唯一 |
|
|
|
| `ChartRecordRepository.java` | 新增 | `Optional<ChartRecord> findByUserIdAndBirthday(Long userId, String birthday)` |
|
|
|
| `UserService.java` | 微调 | `checkDailyQuota()` 和 `consumeQuota()` 已有逻辑不变(3次/天全局计数),但新增注释明确"非VIP每日3次绑定当前命盘,切换生日不重置" |
|
|
|
| `ProfileController.java` | 微调 | 咨询列表接口按 `lastInteractionAt` 倒序 |
|
|
|
+| `DifyService.java` | **新增** | Dify API 客户端,封装 `POST /v1/workflows/run`(命盘解读)和 `POST /v1/chat-messages`(AI问答)两个接口;含签名、错误重试、超时处理,详见**附录B** |
|
|
|
+| `ChatService.java` | 改造 | 原直调 LLM 逻辑改为调 `DifyService`;解读生成走 `DifyService.runWorkflow()`;问答走 `DifyService.sendChatMessage()`;在调用前检查配额(US-3.4) |
|
|
|
|
|
|
### A.2 前端 Vue / JS
|
|
|
|
|
|
@@ -1196,8 +1562,8 @@ US-6.5 分销面板(前端展示所有数据)
|
|
|
| `client/utils/calculator.js` | 废弃/降级 | `calculateTriangle()` 保留为离线兜底,不再作为主路径调用;内部命名改为 `I,J,K,L,M,N,O`;新增 `calculateFullTriangle()` 含外部 P-X;主入口加注释 `@deprecated 请使用后端计算` |
|
|
|
| `client/stores/chart.js` | 改造 | `computeChart()` 不再调 `calculateTriangle()`,改为调 `consultationApi.start()`;返回数据中的 `positions` 直接写入 `currentChart`;不再调 `analyzeTriangle()`(由后端返回) |
|
|
|
| `client/components/TriangleChart.vue` | 重写 matrix() | `innerBottom` 从 `[d.F,d.G,d.H,d.I]` → `[d.I,d.J,d.K,d.L]`;`outerLeft` 从 `{main:d.M, sub:[d.F,d.G]}` → `{main:d.R, sub:[d.P,d.Q]}`;`outerRight` 从 `{main:d.N, sub:[d.H,d.I]}` → `{main:d.U, sub:[d.S,d.T]}`;`outerTop` 从 `{main:d.O, sub:[d.M,d.N]}` → `{main:d.X, sub:[d.V,d.W]}` |
|
|
|
-| `client/pages/index/index.vue` | 改造 | `onAnalyze()` 改为:①调 `POST /api/chart/start`(传 birthday + name + questions);②若返回 `isNew=true` 且 `requireConfirmation=true` 则弹确认框;③确认后再次请求;④成功后跳转 `chart/index`;⑤"想了解的问题"加 `maxlength=100` + 实时字数显示 |
|
|
|
-| `client/utils/api.js` | 新增 | `consultationApi`:`start(data)` → `POST /api/chart/start`;`detail(id)` → `POST /api/chart/detail` |
|
|
|
+| `client/pages/index/index.vue` | 改造 | `onAnalyze()` 改为:①调 `POST /api/consultation/start`(传 birthday + name + questions);②若返回 `isNew=true` 且 `requireConfirmation=true` 则弹确认框;③确认后再次请求;④成功后跳转 `chart/index`;⑤"想了解的问题"加 `maxlength=100` + 实时字数显示 |
|
|
|
+| `client/utils/api.js` | 新增 | `consultationApi`:`start(data)` → `POST /api/consultation/start`;`detail(id)` → `POST /api/consultation/detail` |
|
|
|
| `client/pages/chart/index.vue` | 微调 | 适配新的 API 返回结构(`chartData.positions` 含全部 I-X);`onMounted` 加载历史消息逻辑不变 |
|
|
|
| `client/pages/records/index.vue` | 微调 | 列表按 `lastInteractionAt` 排序;详情页恢复聊天历史逻辑不变 |
|
|
|
|
|
|
@@ -1216,8 +1582,516 @@ Step 1: US-1.3(本对照表)→ 开发团队通读,确保理解命名对
|
|
|
Step 2: 数据库迁移 → 加索引+字段
|
|
|
Step 3: CalculatorService.java → 重写为新命名+外部计算
|
|
|
Step 4: ChartService.java + ChartController.java → 新增 startConsultation()
|
|
|
-Step 5: stores/chart.js + api.js → 前端调后端新接口
|
|
|
+Step 5: stores/chart.js + api.js → 前端调后端新接口(主路径走后端;后端不可用时 calculator.js 降级兜底,仅展示离线计算版命盘,不提供AI解读和咨询记录)
|
|
|
Step 6: TriangleChart.vue → matrix() 改用新命名+独立外部值
|
|
|
Step 7: pages/index/index.vue → 确认弹窗 + 100字限制
|
|
|
-Step 8: 联调 → 前后端打通 end-to-end
|
|
|
+Step 8: Dify 配置 →
|
|
|
+ 8a. 在 Dify 平台创建 Workflow(命盘解读)和 Chatflow(AI问答)
|
|
|
+ 8b. 上传知识库文档(数字能量学语料)
|
|
|
+ 8c. 发布工作流,获取 API Key
|
|
|
+Step 9: DifyService.java + ChatService.java → 集成 Dify API
|
|
|
+Step 10: 联调 → 前后端打通 end-to-end,含 Dify 工作流调试验收
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录B:Dify AI 架构设计
|
|
|
+
|
|
|
+> Dify 是开源 LLM 应用开发平台,提供可视化工作流编排、RAG 知识库、模型管理等能力。
|
|
|
+> 本项目使用 Dify 的两个应用类型:**Workflow**(命盘解读生成)和 **Chatflow**(AI交互问答)。
|
|
|
+
|
|
|
+### B.1 整体架构
|
|
|
+
|
|
|
+```
|
|
|
+┌─────────────────────────────────────────────────────────┐
|
|
|
+│ 微信小程序前端 │
|
|
|
+│ POST /api/chart/interpret POST /api/chat/send │
|
|
|
+└────────────────────┬─────────────────────┬──────────────┘
|
|
|
+ │ │
|
|
|
+┌────────────────────▼─────────────────────▼──────────────┐
|
|
|
+│ Java 后端 (Spring Boot) │
|
|
|
+│ │
|
|
|
+│ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
|
+│ │ChatController│ │ChartController│ │ChatService │ │
|
|
|
+│ └──────┬──────┘ └──────┬───────┘ └──────┬───────┘ │
|
|
|
+│ │ │ │ │
|
|
|
+│ └──────────┬──────┘ │ │
|
|
|
+│ │ │ │
|
|
|
+│ ┌──────────▼──────────┐ ┌───────────▼────────┐ │
|
|
|
+│ │ DifyService.java │ │ DifyService.java │ │
|
|
|
+│ │ runWorkflow() │ │ sendChatMessage() │ │
|
|
|
+│ └──────────┬──────────┘ └───────────┬─────────┘ │
|
|
|
+└────────────────────┼─────────────────────────┼───────────┘
|
|
|
+ │ │
|
|
|
+┌────────────────────▼─────────────────────────▼───────────┐
|
|
|
+│ Dify API (自建部署 / SaaS) │
|
|
|
+│ │
|
|
|
+│ ┌──────────────────┐ ┌──────────────────────┐ │
|
|
|
+│ │ Workflow(解读) │ │ Chatflow(问答) │ │
|
|
|
+│ │ │ │ │ │
|
|
|
+│ │ 开始 → 知识检索 │ │ 开始 → 接收消息 │ │
|
|
|
+│ │ → LLM生成解读 │ │ → 知识检索 → LLM回答 │ │
|
|
|
+│ │ → 格式化输出 │ │ → 返回答案 │ │
|
|
|
+│ └────────┬─────────┘ └──────────┬───────────┘ │
|
|
|
+│ │ │ │
|
|
|
+│ └──────────┬───────────────┘ │
|
|
|
+│ │ │
|
|
|
+│ ┌──────────▼──────────┐ │
|
|
|
+│ │ 知识库(RAG) │ │
|
|
|
+│ │ ├─ 主性格含义库 │ │
|
|
|
+│ │ ├─ 组合数字含义库 │ │
|
|
|
+│ │ ├─ 三区年龄解读库 │ │
|
|
|
+│ │ └─ 常见命盘案例库 │ │
|
|
|
+│ └─────────────────────┘ │
|
|
|
+└──────────────────────────────────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+**关键原则:**
|
|
|
+
|
|
|
+- Java 后端是**最薄的一层**,只做:参数校验 → 配额检查 → 调用 Dify API → 透传结果
|
|
|
+- 所有 AI 逻辑(prompt 设计、知识检索策略、输出格式)都在 Dify 工作流中配置
|
|
|
+- 修改解读模板或知识内容不需要改 Java 代码,只需要在 Dify 平台更新工作流
|
|
|
+
|
|
|
+### B.2 Dify Workflow(命盘解读)—— 一次性解读生成
|
|
|
+
|
|
|
+**用途:** US-3.1 AI解读展示
|
|
|
+
|
|
|
+**Dify 应用类型:** **Workflow(工作流)**——单轮执行,无需维护对话历史
|
|
|
+
|
|
|
+**触发方式:** API 调用,blocking 模式
|
|
|
+
|
|
|
+**输入变量:**
|
|
|
+
|
|
|
+| 变量名 | 类型 | 说明 |
|
|
|
+|--------|------|------|
|
|
|
+| `chart` | `object` | 24个命盘位置的值 `{ A:8, B:1, ..., X:5 }` |
|
|
|
+| `name` | `string` | 用户姓名 |
|
|
|
+| `birthday` | `string` | 出生日期 `YYYY-MM-DD` |
|
|
|
+
|
|
|
+**工作流节点编排:**
|
|
|
+
|
|
|
```
|
|
|
+[开始节点]
|
|
|
+ ↓
|
|
|
+[知识检索 1] 查主性格(O)含义
|
|
|
+ ↓
|
|
|
+[知识检索 2] 查左区(P,R)21-40岁解读
|
|
|
+ ↓
|
|
|
+[知识检索 3] 查顶部(V,X)41-60岁解读
|
|
|
+ ↓
|
|
|
+[知识检索 4] 查右区(S,U)61+岁解读
|
|
|
+ ↓
|
|
|
+[知识检索 5] 查特殊组合(如 I+J=11, M+O 等)
|
|
|
+ ↓
|
|
|
+[LLM 节点]
|
|
|
+ 系统提示词:
|
|
|
+ "你是一个专业的数字能量学分析师。
|
|
|
+ 根据以下命盘数据和检索到的知识,生成完整的命盘解读。
|
|
|
+ 必须严格按照以下结构输出..."
|
|
|
+ ↓
|
|
|
+[代码节点 / 输出解析]:确保输出 JSON 结构正确
|
|
|
+ ↓
|
|
|
+[结束节点] → 输出 `{ sections: [...], summary: "..." }`
|
|
|
+```
|
|
|
+
|
|
|
+**输出格式(`data.outputs`):**
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "sections": [
|
|
|
+ {
|
|
|
+ "title": "主性格解读",
|
|
|
+ "position": "O",
|
|
|
+ "value": 6,
|
|
|
+ "content": "主性格数字 6 代表…",
|
|
|
+ "keywords": ["责任心", "家庭", "关爱"]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "title": "左区(21-40岁)",
|
|
|
+ "positions": ["P", "Q", "R"],
|
|
|
+ "values": [8, 3, 2],
|
|
|
+ "content": "左区数字组合 8-3-2 代表…"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "title": "顶部(41-60岁)",
|
|
|
+ "positions": ["V", "W", "X"],
|
|
|
+ "values": [4, 1, 5],
|
|
|
+ "content": "顶部数字组合 4-1-5 代表…"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "title": "右区(61+岁)",
|
|
|
+ "positions": ["S", "T", "U"],
|
|
|
+ "values": [6, 8, 5],
|
|
|
+ "content": "右区数字组合 6-8-5 代表…"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "summary": "整体命盘评价…",
|
|
|
+ "combination_notes": ["数字 I(4)+J(3)=7,形成…", "M(7)+O(6)=13→4,形成…"]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### B.3 Dify Chatflow(AI交互问答)—— 多轮对话
|
|
|
+
|
|
|
+**用途:** US-3.4 AI交互问答
|
|
|
+
|
|
|
+**Dify 应用类型:** **Chatflow(对话工作流)**——多轮对话,自动维护 `conversation_id`
|
|
|
+
|
|
|
+**触发方式:** API 调用,streaming 模式(打字机效果)
|
|
|
+
|
|
|
+**第一轮消息传入的上下文变量:**
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "inputs": {
|
|
|
+ "chart": { "A":8, "B":1, "C":9, "D":6, "E":3, "F":0, "G":1, "H":4,
|
|
|
+ "I":4, "J":3, "K":6, "L":5, "M":7, "N":2, "O":6,
|
|
|
+ "P":8, "Q":3, "R":2, "S":6, "T":8, "U":5, "V":4, "W":1, "X":5 },
|
|
|
+ "user_name": "张三",
|
|
|
+ "birthday": "1996-03-14"
|
|
|
+ },
|
|
|
+ "query": "我的主性格数字6代表什么?",
|
|
|
+ "user": "uid_123",
|
|
|
+ "response_mode": "streaming"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**后续轮次:** 只传 `query` + `conversation_id`,无需重复传入命盘数据
|
|
|
+
|
|
|
+**Chatflow 节点编排:**
|
|
|
+
|
|
|
+```
|
|
|
+[开始节点]
|
|
|
+ ↓
|
|
|
+[问题分类节点]
|
|
|
+ ├─ 问数字含义 → [知识检索] → [LLM 回答]
|
|
|
+ ├─ 问运势建议 → [知识检索] → [LLM 回答]
|
|
|
+ └─ 其他问题 → [LLM 直接回答]
|
|
|
+ ↓
|
|
|
+[LLM 节点]
|
|
|
+ 系统提示词:
|
|
|
+ "你是一个数字能量学咨询助手。
|
|
|
+ 用户的命盘数据已作为上下文变量传入。
|
|
|
+ 请基于用户的命盘数据和知识库内容回答问题。
|
|
|
+ 如果问题涉及具体数字,请引用该数字在命盘中的位置和含义。"
|
|
|
+ ↓
|
|
|
+[结束节点] → 输出答案文本
|
|
|
+```
|
|
|
+
|
|
|
+### B.4 知识库设计
|
|
|
+
|
|
|
+需要在 Dify 平台创建的知识库文档:
|
|
|
+
|
|
|
+| 文档名称 | 内容 | 用途 |
|
|
|
+|----------|------|------|
|
|
|
+| **数字能量学基础** | 数字 1-9 的基础能量含义、吉凶属性 | LLM 基础理解 |
|
|
|
+| **主性格数字解读** | 每个主性格数字(1-9)的详细性格特质、优缺点、代表人物 | 主性格解读 |
|
|
|
+| **位置含义对照表** | 每个位置(A-X)代表的人生领域和能量属性 | 各章节解读 |
|
|
|
+| **组合数字解读** | 常见数字组合(如11/22/33/13/14等)的特殊含义 | 组合分析 |
|
|
|
+| **三区年龄段解读** | 21-40 / 41-60 / 61+ 三个年龄段的典型命理模式 | 三区解读 |
|
|
|
+| **常见命盘案例** | 典型命盘 + 完整解读示例(Few-shot 示例) | 提升解读质量 |
|
|
|
+
|
|
|
+**文档格式建议:**
|
|
|
+
|
|
|
+- 每个文档的结构化程度越高越好,推荐 Markdown 表格 + 标题层级
|
|
|
+- 示例格式:
|
|
|
+
|
|
|
+```markdown
|
|
|
+# 主性格数字 7
|
|
|
+
|
|
|
+## 核心特质
|
|
|
+- 关键词:分析力、哲学思维、追求真理
|
|
|
+- 能量属性:精神导向,向内探索
|
|
|
+
|
|
|
+## 性格描述
|
|
|
+主性格数字7的人天生具有强烈的分析能力和探索精神…
|
|
|
+
|
|
|
+## 优势
|
|
|
+- 逻辑思维强
|
|
|
+- 善于发现规律
|
|
|
+- 独立自主
|
|
|
+
|
|
|
+## 劣势
|
|
|
+- 容易多疑
|
|
|
+- 社交上偏孤僻
|
|
|
+- 过度分析导致行动迟缓
|
|
|
+
|
|
|
+## 代表人物
|
|
|
+- 爱因斯坦、达芬奇
|
|
|
+```
|
|
|
+
|
|
|
+### B.5 Java 后端集成
|
|
|
+
|
|
|
+**`DifyService.java` 核心接口:**
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class DifyService {
|
|
|
+
|
|
|
+ // 配置(从 application.yml 读取)
|
|
|
+ @Value("${dify.api-base}")
|
|
|
+ private String apiBase; // e.g. "https://api.dify.ai/v1"
|
|
|
+ @Value("${dify.workflow-api-key}")
|
|
|
+ private String workflowApiKey; // 命盘解读 Workflow 密钥
|
|
|
+ @Value("${dify.chatflow-api-key}")
|
|
|
+ private String chatflowApiKey; // AI问答 Chatflow 密钥
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用 Dify Workflow 生成命盘解读(US-3.1)
|
|
|
+ * @param chartData 24个数字的 Map
|
|
|
+ * @param userName 用户姓名
|
|
|
+ * @param birthday 出生日期
|
|
|
+ * @return 结构化解读结果(sections + summary)
|
|
|
+ */
|
|
|
+ public InterpretationResult runInterpretation(
|
|
|
+ Map<String, Integer> chartData, String userName, String birthday
|
|
|
+ ) {
|
|
|
+ // 1. 构造 inputs
|
|
|
+ // 2. POST /v1/workflows/run (blocking)
|
|
|
+ // 3. 解析 data.outputs 为 InterpretationResult
|
|
|
+ // 4. 超时 15s,重试 1 次
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用 Dify Chatflow 发送消息(US-3.4)
|
|
|
+ * @param chartData 24个数字(仅首轮传入)
|
|
|
+ * @param conversationId 已有会话ID(后续轮次)
|
|
|
+ * @param query 用户问题
|
|
|
+ * @param userId 用户标识
|
|
|
+ * @param isFirstRound 是否首轮
|
|
|
+ * @return Dify 流式响应或阻塞响应
|
|
|
+ */
|
|
|
+ public ChatResponse sendChatMessage(
|
|
|
+ Map<String, Integer> chartData,
|
|
|
+ String conversationId,
|
|
|
+ String query,
|
|
|
+ String userId,
|
|
|
+ boolean isFirstRound
|
|
|
+ ) {
|
|
|
+ // 1. 首轮时传入 inputs(chart 数据)
|
|
|
+ // 2. POST /v1/chat-messages (streaming)
|
|
|
+ // 3. 返回 SSE 流或阻塞结果
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**`ChatService.java` 改造要点:**
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class ChatService {
|
|
|
+
|
|
|
+ public ChatResponse sendMessage(Long userId, Long chartId, String message) {
|
|
|
+ // 1. 检查用户配额(US-3.4)
|
|
|
+ if (!isVip(userId) && getTodayQuota(userId) >= 3) {
|
|
|
+ throw new BusinessException("今日AI问答次数已用完");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取命盘数据
|
|
|
+ ChartRecord record = chartRecordRepository.findById(chartId);
|
|
|
+ Map<String, Integer> chartData = record.getChartData();
|
|
|
+
|
|
|
+ // 3. 调用 Dify(Chatflow)
|
|
|
+ String conversationId = record.getDifyConversationId();
|
|
|
+ boolean isFirstRound = (conversationId == null);
|
|
|
+ ChatResponse response = difyService.sendChatMessage(
|
|
|
+ chartData, conversationId, message, userId.toString(), isFirstRound
|
|
|
+ );
|
|
|
+
|
|
|
+ // 4. 首次对话保存 conversationId
|
|
|
+ if (isFirstRound) {
|
|
|
+ record.setDifyConversationId(response.getConversationId());
|
|
|
+ chartRecordRepository.save(record);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 消耗配额
|
|
|
+ consumeQuota(userId);
|
|
|
+
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**`application.yml` 新增配置:**
|
|
|
+
|
|
|
+```yaml
|
|
|
+dify:
|
|
|
+ api-base: https://api.dify.ai/v1
|
|
|
+ workflow-api-key: app-xxxxx # 命盘解读 Workflow
|
|
|
+ chatflow-api-key: app-yyyyy # AI问答 Chatflow
|
|
|
+ timeout: 15000 # 单次调用超时 15s
|
|
|
+```
|
|
|
+
|
|
|
+### B.6 Dify 部署模式建议
|
|
|
+
|
|
|
+| 模式 | 适用阶段 | 说明 |
|
|
|
+|------|---------|------|
|
|
|
+| **Dify SaaS(cloud.dify.ai)** | 开发/测试 | 快速上手,无需自建,有免费额度 |
|
|
|
+| **自建部署(Docker)** | 生产 | 数据不出域,可控成本,建议生产环境使用 |
|
|
|
+
|
|
|
+自建部署参考:`https://github.com/langgenius/dify`
|
|
|
+
|
|
|
+### B.7 开发流程建议
|
|
|
+
|
|
|
+1. **先配知识库**:在 Dify 平台创建知识库,上传数字能量学语料文档
|
|
|
+2. **再搭 Workflow**:创建命盘解读工作流,配置节点链,用测试数据调通
|
|
|
+3. **再搭 Chatflow**:创建 AI 问答对话工作流,测试多轮对话
|
|
|
+4. **Java 集成**:开发 `DifyService.java`,调通 Workflow 和 Chatflow 两个 API
|
|
|
+5. **联调验收**:前端通过后端调用 Dify,验证解读质量和问答效果
|
|
|
+
|
|
|
+### B.8 与现有 US 的对应关系
|
|
|
+
|
|
|
+| Dify 组件 | 对应 US | 备注 |
|
|
|
+|-----------|---------|------|
|
|
|
+| Workflow(命盘解读) | US-3.1 AI解读展示、US-3.2 付费控制 | Workflow 输出由 UC-3.2 决定是否全文展示 |
|
|
|
+| Chatflow(AI问答) | US-3.4 AI交互问答 | 配额控制在 Java 后端,不经过 Dify |
|
|
|
+| 知识库 | US-3.1、US-3.4 | 两个工作流共用同一套知识库 |
|
|
|
+| 无(纯后端) | US-3.3 解读内容缓存 | 缓存逻辑在 Java 后端,不涉及 Dify |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录C:三类用户角色权限对照表
|
|
|
+
|
|
|
+> 覆盖系统所有功能的权限边界,按角色逐一对比。
|
|
|
+
|
|
|
+### C.1 概览
|
|
|
+
|
|
|
+| | 普通用户 | C端年费用户 | 能量师用户 |
|
|
|
+|--|---------|------------|-----------|
|
|
|
+| **年费** | ¥0 | ¥131 | ¥1,314(种子)/ ¥1,986(标准) |
|
|
|
+| **数据库标记** | `vipType=NULL` | `vipType='annual'` | `vipType='practitioner'` |
|
|
|
+| **到期降级** | — | → 普通用户 | → 普通用户 |
|
|
|
+| **续费价格** | — | 标准价 ¥131 | 标准价 ¥1,986(种子价仅限首次) |
|
|
|
+| **定位** | 浏览体验 | 给自己看,轻度社交 | 给客户看,商业工具 |
|
|
|
+
|
|
|
+### C.2 功能权限总表
|
|
|
+
|
|
|
+```
|
|
|
+能力 普通用户 C端¥131 能量师¥1,314+
|
|
|
+───────────────────────── ────────── ────────── ──────────────
|
|
|
+生成命盘 ✅ ✅ ✅
|
|
|
+查看命盘可视化 ✅ ✅ ✅
|
|
|
+数字点击查看含义 ✅ ✅ ✅
|
|
|
+
|
|
|
+AI解读·主性格概要 1次/天 不限 不限
|
|
|
+AI解读·完整五区 ❌ ✅ ✅
|
|
|
+AI问答互动 3轮/天 不限 不限
|
|
|
+
|
|
|
+分享图片到微信 1次/天 不限 不限
|
|
|
+导出PDF报告 ❌ 不限 不限
|
|
|
+
|
|
|
+历史记录查看 近7天 全部 全部
|
|
|
+推广码+分销面板 ❌ ✅ ✅
|
|
|
+推广C端年费得佣金 ❌ 40%+5%分成 40%+5%分成
|
|
|
+推广能量师年费得佣金 ❌ ❌ ¥500 + ¥100
|
|
|
+命盘批注(P2) ❌ ✅ ✅
|
|
|
+客户标签分组(P2) ❌ ❌ ✅
|
|
|
+个人资料编辑 ✅ ✅ ✅
|
|
|
+
|
|
|
+个人中心标签 "普通用户" "C端会员" "能量师"
|
|
|
+订阅引导卡片 可见 不可见 不可见
|
|
|
+续费提醒 — 到期前7天 到期前7天
|
|
|
+```
|
|
|
+
|
|
|
+### C.3 按场景的用户体验流程
|
|
|
+
|
|
|
+#### 场景 1:首次进入
|
|
|
+
|
|
|
+```
|
|
|
+所有用户
|
|
|
+ │
|
|
|
+ ├─ 微信登录 → 完善资料(昵称/头像/生日/性别)
|
|
|
+ │
|
|
|
+ └─ 输入生日 → 生成命盘 → 查看命盘图 → 查看主性格概要(免费1次)
|
|
|
+ │
|
|
|
+ ├─ 遇到付费墙(完整解读/PDF/无限问答)
|
|
|
+ │ └─ 看到 ¥131 开通引导卡片
|
|
|
+ │
|
|
|
+ └─ 保持免费用户,每日 3 轮问答 + 1 次分享
|
|
|
+```
|
|
|
+
|
|
|
+#### 场景 2:升级为 C端年费(¥131)
|
|
|
+
|
|
|
+```
|
|
|
+普通用户点击"开通 ¥131"
|
|
|
+ │
|
|
|
+ ├─ 微信支付 ¥131
|
|
|
+ ├─ vipType → 'annual', vipEndTime → +365天
|
|
|
+ ├─ 推广码自动生成
|
|
|
+ │
|
|
|
+ └─ 解锁能力:
|
|
|
+ ├─ AI完整解读(无限次)
|
|
|
+ ├─ AI问答(不限轮数)
|
|
|
+ ├─ 分享图片(不限次)
|
|
|
+ ├─ PDF导出(不限次)
|
|
|
+ ├─ 历史记录(全部)
|
|
|
+ ├─ 分销面板可见
|
|
|
+ └─ 推广C端年费赚 40% + 5%
|
|
|
+```
|
|
|
+
|
|
|
+#### 场景 3:升级为能量师(¥1,314 / ¥1,986)
|
|
|
+
|
|
|
+```
|
|
|
+普通用户点击"开通能量师"
|
|
|
+ │
|
|
|
+ ├─ 微信支付 ¥1,314(种子价)/ ¥1,986(标准价)
|
|
|
+ ├─ vipType → 'practitioner', vipEndTime → +365天
|
|
|
+ ├─ 推广码自动生成(若首次付费)
|
|
|
+ │
|
|
|
+ └─ 解锁能力(在C端基础上增加):
|
|
|
+ ├─ 推广能量师年费赚 ¥500 + ¥100
|
|
|
+ ├─ 客户标签分组(P2)
|
|
|
+ └─ 命盘批注(P2,C端也有但用途不同)
|
|
|
+```
|
|
|
+
|
|
|
+### C.4 关键决策点
|
|
|
+
|
|
|
+**能量师 vs C端——AI能力完全一致。**
|
|
|
+两者在AI解读和问答上没有任何区别(都不限次、完整内容),差异只在于:
|
|
|
+
|
|
|
+| 维度 | C端¥131 | 能量师¥1,314+ |
|
|
|
+|------|---------|--------------|
|
|
|
+| 分销产品 | 仅 C端年费 | C端年费 + 能量师年费 |
|
|
|
+| 佣金模式 | 比例(40%+5%) | 比例 + 固定(¥500+¥100) |
|
|
|
+| 客户管理 | ❌ 不需要 | ✅ 批注+标签 |
|
|
|
+| 使用场景 | 自己看命理 | 为客户解读 |
|
|
|
+
|
|
|
+这意味着如果能量师**不打算做推广**,¥1,314+相比¥131的额外价值只有批注和标签(P2功能)。这可能影响高客单价转化策略——需要在能量师权益中强化"商业工具"的价值感知。
|
|
|
+
|
|
|
+**普通用户的命盘创建无限。**
|
|
|
+目前仅限制了AI问答3轮/天和AI解读1次/天,但普通用户可创建任意数量的命盘。每个命盘可获得一次免费主性格概要,理论上可通过不停创建新命盘获取多次概要。此场景消耗成本较低(1段文本),暂不设限。
|
|
|
+
|
|
|
+### C.5 数据库字段
|
|
|
+
|
|
|
+```sql
|
|
|
+-- users 表相关字段
|
|
|
+vipType: NULL 'annual' 'practitioner'
|
|
|
+vipEndTime: NULL 2027-05-29 2027-05-29
|
|
|
+referralCode: NULL 'A3X7K9' 'B2Y4M8'
|
|
|
+profile_complete: true/false true/false true/false
|
|
|
+
|
|
|
+-- 关联表
|
|
|
+┌─ orders ─────────────────────┐
|
|
|
+│ user_id, product_type, │
|
|
|
+│ amount, status, invited_by │
|
|
|
+└──────────────────────────────┘
|
|
|
+
|
|
|
+┌─ commissions ────────────────┐
|
|
|
+│ order_id, level, amount, │
|
|
|
+│ status (pending/settled) │
|
|
|
+└──────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+### C.6 与 US 映射
|
|
|
+
|
|
|
+| 约束规则 | 所在用户故事 |
|
|
|
+|---------|------------|
|
|
|
+| AI解读:普通用户仅主性格概要1次/天 | US-3.2 |
|
|
|
+| AI问答:普通用户3轮/天全局计数 | US-3.4 |
|
|
|
+| 分享图片:普通用户1次/天 | US-2.1 |
|
|
|
+| PDF导出:仅付费用户可用,不限次 | US-2.2 |
|
|
|
+| 历史记录:普通用户仅7天 | US-5.2 |
|
|
|
+| 推广码:仅付费后生成 | US-6.1 |
|
|
|
+| 分销面板:仅付费用户可见 | US-6.5 |
|
|
|
+| C端佣金:上级须已付费才结算 | US-6.4 |
|
|
|
+| 批注:仅已付费用户 | US-7.1 |
|
|
|
+| 标签:仅能量师(practitioner)可用 | US-7.2 |
|