|
|
@@ -0,0 +1,495 @@
|
|
|
+# 浠艾福·体验会员(BASIC)PRD
|
|
|
+
|
|
|
+> 文档版本:v1.0
|
|
|
+> 创建日期:2026-09-10
|
|
|
+> 状态:PRD 评审中
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 产品背景与目标
|
|
|
+
|
|
|
+### 1.1 背景
|
|
|
+
|
|
|
+浠艾福平台当前会员体系仅有 `FREE → FAMILY → PREMIUM → PROVIDER` 四档,缺乏中间层:
|
|
|
+- 免费用户从未付费,转化路径过长(直接跳到 131.4 元/月)
|
|
|
+- 有尝试付费意愿但价格敏感的用户流失在免费层
|
|
|
+- 无法验证用户是否真正需要 AI 健康顾问、报告解读等高价值功能
|
|
|
+
|
|
|
+### 1.2 目标
|
|
|
+
|
|
|
+新增 **BASIC(体验会员)** 层级,定价 **9.9 元/月**,实现:
|
|
|
+
|
|
|
+| 指标 | 目标值 | 说明 |
|
|
|
+|------|-------|------|
|
|
|
+| 免费→BASIC 付费转化率 | ≥ 3% | 月活用户中完成首单的比例 |
|
|
|
+| BASIC→FAMILY 升级转化率 | ≥ 15% | BASIC 用户在有效期内的升级比例 |
|
|
|
+| BASIC 次月留存率 | ≥ 40% | 首月付费用户次月仍然活跃的比例 |
|
|
|
+| BASIC 月均 AI 对话次数 | ≥ 2.5 次 | 月度配额 3 次中实际使用率 |
|
|
|
+
|
|
|
+### 1.3 核心设计原则
|
|
|
+
|
|
|
+- **不是免费试用**:TrialMembership(7 天免费)已存在,BASIC 是独立付费产品,二者不重叠
|
|
|
+- **限次不是限制,是钩子**:配额制制造"用完还想用"的周期回归动力
|
|
|
+- **数据不消失**:会员到期后成长记录、五维能量曲线等数据保留 30 天,迁移成本高是粘性本质
|
|
|
+- **软引导 > 硬屏蔽**:让用户看到"我本来可以",而非"我被挡在外面"
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 等级体系定位
|
|
|
+
|
|
|
+```
|
|
|
+FREE(免费)
|
|
|
+ │ 9.9元/月
|
|
|
+ ▼
|
|
|
+BASIC(体验会员)← 本 PRD
|
|
|
+ │ 131.4元/月(活动价)
|
|
|
+ ▼
|
|
|
+FAMILY(家庭会员)
|
|
|
+ │
|
|
|
+ ▼
|
|
|
+PREMIUM(尊享会员)
|
|
|
+ │
|
|
|
+ ▼
|
|
|
+PROVIDER(服务商)
|
|
|
+```
|
|
|
+
|
|
|
+### 2.1 BASIC 等级定义
|
|
|
+
|
|
|
+| 字段 | 值 | 说明 |
|
|
|
+|------|---|------|
|
|
|
+| `level_code` | `BASIC` | 数据库新增等级编码 |
|
|
|
+| `level_name` | `体验会员` | 前端展示名 |
|
|
|
+| `price_monthly` | `990`(分)| 9.9 元 |
|
|
|
+| `price_quarterly` | NULL | 不支持季付 |
|
|
|
+| `price_yearly` | NULL | 不支持年付 |
|
|
|
+| `features` | 见 §3.2 | 功能权限 JSON |
|
|
|
+| `max_children` | `3` | 可添加孩子上限(FREE=0, FAMILY=10) |
|
|
|
+| `max_tasks_per_day` | `3` | 孩子每日任务上限 |
|
|
|
+| `ai_review_enabled` | `0` | 不做 AI 审核 |
|
|
|
+| `priority_support` | `0` | 不做 |
|
|
|
+| `teacher_consultation` | `0` | 不做 |
|
|
|
+
|
|
|
+### 2.2 与其他等级的核心差异
|
|
|
+
|
|
|
+| 对比项 | FREE | BASIC | FAMILY |
|
|
|
+|--------|------|-------|--------|
|
|
|
+| 月费 | 0 | 9.9 元 | 131.4 元 |
|
|
|
+| AI 对话 | ❌ | 3 次/月 | 不限 |
|
|
|
+| 报告解读 | ❌ | 1 次/月 | 不限 |
|
|
|
+| 测评预约 | 仅查看 | 1 次/月 | 不限 |
|
|
|
+| 能量沙盘 | 🔒 | ✅ | ✅ |
|
|
|
+| 专属教练 | 🔒 | 🔒 | ✅ 月1次 |
|
|
|
+| 管家分配 | 🔒 | 🔒 | ✅ |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 功能权益矩阵
|
|
|
+
|
|
|
+### 3.1 完整权益表
|
|
|
+
|
|
|
+| 功能模块 | 子功能 | FREE | **BASIC** | FAMILY | PREMIUM | BASIC 限制说明 |
|
|
|
+|---------|--------|:---:|:---:|:---:|:---:|--------------|
|
|
|
+| **五维能量** | 基础能量分 | ✅ | ✅ | ✅ | ✅ | |
|
|
|
+| | 趋势曲线/对比 | 🔒 | ✅ | ✅ | ✅ | 付费解锁深度数据 |
|
|
|
+| | 能量沙盘 | 🔒硬门禁 | ✅ | ✅ | ✅ | 复用 `UnlockGate.MEMBERSHIP` |
|
|
|
+| **AI 服务** | AI 健康顾问 | ❌ | **3次/月** | 不限 | 不限 | `_lite` 后缀配额型 |
|
|
|
+| | 报告 AI 解读 | 🔒 | **1次/月** | 不限 | 深度解读 | `_lite` 后缀配额型 |
|
|
|
+| **成长与测评** | 成长计划 | 创建 | 创建+基础查看 | 完整+模板 | +教练随访 | `_lite` 后缀 |
|
|
|
+| | 测评预约/订单 | 查看 | **1次/月** | 不限 | 不限+优先 | `_lite` 后缀,**硬门禁** |
|
|
|
+| | 成长记录 | 创建 | 创建+查看 | 完整+导出 | 完整+AI生成 | 资产型,不限制 |
|
|
|
+| | 任务/心愿 | 基础模板 | 更多模板 | 全部模板 | +定制 | `_lite` 后缀 |
|
|
|
+| **健康与家庭** | 健康报告上传 | ❌ | **2份/月** | 不限 | 不限+AI解析 | `_lite` 后缀配额型 |
|
|
|
+| | 家庭邀请码 | ❌ | 创建+邀请 | 完整关系图 | 完整 | BASIC 是家庭功能入口 |
|
|
|
+| | 饮食推荐 | 基础 | 基础 | 个性化 | 深度定制 | 引流功能 |
|
|
|
+| **商业与服务** | 积分商城 | 可见 | 可见+购买 | 可见+折扣 | 额外折扣 | |
|
|
|
+| | 优惠券 | ❌ | 平台券 | 会员券 | 专属券 | |
|
|
|
+| | 专属健康教练 | 🔒 | 🔒软引导 | ✅ 月1次 | ✅ 周1次 | FAMILY+ 专属 |
|
|
|
+| | 规划师一对一咨询 | 🔒 | 🔒软引导 | ✅ | ✅ 优先 | 核心变现保留 |
|
|
|
+| | 成长档案导出 | 🔒 | 🔒软引导 | ✅ | ✅ | FAMILY+ 专属 |
|
|
|
+| | 管家分配(butler) | 🔒 | 🔒软引导 | ✅ | ✅ 优先 | FAMILY+ 专属 |
|
|
|
+
|
|
|
+### 3.2 features JSON
|
|
|
+
|
|
|
+```json
|
|
|
+[
|
|
|
+ "free_activities",
|
|
|
+ "free_courses",
|
|
|
+ "discount_purchase",
|
|
|
+ "invite_family",
|
|
|
+ "mascot_ai_lite",
|
|
|
+ "ai_report_reading_lite",
|
|
|
+ "assessment_quota_lite",
|
|
|
+ "health_report_upload_lite",
|
|
|
+ "growth_plan_lite",
|
|
|
+ "task_template_lite"
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+**命名规范**:`_lite` 后缀表示"功能可用,但有月度配额限制",需在配额系统中额外校验。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 配额系统(粘性引擎)
|
|
|
+
|
|
|
+### 4.1 设计决策
|
|
|
+
|
|
|
+> **决策2:配额按 `user_id`(家长账号)独立,不按 family_id 共享。**
|
|
|
+
|
|
|
+**理由**:
|
|
|
+- 一个家庭可能有多个家长账号,各人独立付费各自获得配额更公平
|
|
|
+- 与现有 `User.memberLevel` 语义一致(等级挂在用户级别)
|
|
|
+- 简化逻辑:不需要跨用户分摊配额
|
|
|
+
|
|
|
+### 4.2 月度配额详情
|
|
|
+
|
|
|
+| 配额类型 Code | 配额上限 | 刷新周期 | 超限行为 | 对应 feature |
|
|
|
+|--------------|---------|----------|---------|-------------|
|
|
|
+| `AI_CHAT` | 3 次 | 每月 1 号 00:00 | 软引导:Toast "本月额度已用完,升级 FAMILY 享不限次" | `mascot_ai_lite` |
|
|
|
+| `REPORT_READING` | 1 次 | 每月 1 号 00:00 | 软引导:Toast "本月报告解读额度已用完" | `ai_report_reading_lite` |
|
|
|
+| `ASSESSMENT_QUOTA` | 1 次 | 每月 1 号 00:00 | **硬门禁**:禁止创建预约,弹窗"测评预约为 FAMILY 专属" | `assessment_quota_lite` |
|
|
|
+| `REPORT_UPLOAD` | 2 份 | 每月 1 号 00:00 | 软引导:显示"本月还可上传 X 份" | `health_report_upload_lite` |
|
|
|
+
|
|
|
+### 4.3 配额存储模型
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS basic_quota_usage (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ user_id BIGINT NOT NULL COMMENT '家长用户ID(非family_id)',
|
|
|
+ quota_type VARCHAR(30) NOT NULL COMMENT 'AI_CHAT/REPORT_READING/ASSESSMENT_QUOTA/REPORT_UPLOAD',
|
|
|
+ used_count INT DEFAULT 0 COMMENT '本月已用次数',
|
|
|
+ total_count INT NOT NULL COMMENT '月度总配额',
|
|
|
+ period_start DATE NOT NULL COMMENT '周期开始日期(每月1号)',
|
|
|
+ period_end DATE NOT NULL COMMENT '周期结束日期(月末)',
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_user_type_period (user_id, quota_type, period_start),
|
|
|
+ INDEX idx_user_period (user_id, period_start)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='BASIC会员月度配额使用记录';
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 用户生命周期流转
|
|
|
+
|
|
|
+### 5.1 核心路径
|
|
|
+
|
|
|
+```
|
|
|
+免费用户
|
|
|
+ ↓ 浏览权益页 / 点击"9.9元开通体验"
|
|
|
+支付 9.9 元(微信支付)
|
|
|
+ ↓ 回调成功
|
|
|
+激活 BASIC 等级:
|
|
|
+ - user.memberLevel = "BASIC"
|
|
|
+ - user.memberExpireTime = 30天后
|
|
|
+ - family_memberships 写入 BASIC 记录
|
|
|
+ - basic_quota_usage 初始化 4 类配额(used=0)
|
|
|
+ ↓
|
|
|
+使用期(第 1-30 天):
|
|
|
+ - AI 对话 / 报告解读 / 测评预约 / 报告上传
|
|
|
+ - 每次使用消耗对应配额
|
|
|
+ - 配额接近耗尽时软引导提示
|
|
|
+ ↓
|
|
|
+第 25 天:推送到期提醒("还剩 5 天")
|
|
|
+ ↓
|
|
|
+第 30 天:到期降级为 FREE
|
|
|
+ - user.memberLevel = "FREE"
|
|
|
+ - user.memberExpireTime = null
|
|
|
+ - family_memberships 标记 expired
|
|
|
+ - basic_quota_usage 保留历史,不再刷新
|
|
|
+ ↓
|
|
|
+到期后 30 天内:数据保留,续费可恢复权益
|
|
|
+ ↓ (可选)
|
|
|
+升级 FAMILY:补差价(131.4 - 0 = 131.4 元,按剩余天数折算可选)
|
|
|
+```
|
|
|
+
|
|
|
+### 5.2 关键规则
|
|
|
+
|
|
|
+- **不做自动续费升级**(决策1:A):到期后必须手动选择续费 BASIC 或升级 FAMILY
|
|
|
+- **到期不删数据**:成长记录、五维能量曲线、健康报告保留 30 天
|
|
|
+- **配额不继承**:到期后配额清零,续费/升级后重新分配
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 软引导 vs 硬门禁 UX 规范
|
|
|
+
|
|
|
+### 6.1 规则表
|
|
|
+
|
|
|
+| 类型 | 触发条件 | UI 表现 | 示例文案 |
|
|
|
+|------|---------|---------|---------|
|
|
|
+| **硬门禁** | 测评预约超配额 | 弹窗阻断,仅显示"升级 FAMILY"按钮,禁止关闭后继续操作 | "测评预约为 FAMILY 会员专属权益,升级后即可预约" |
|
|
|
+| **软引导** | AI 对话超限 | 页面内 Toast,可关闭,保留"我知道了"和"了解权益"两个按钮 | "您本月 AI 对话已用完(3/3),升级 FAMILY 享不限次畅聊" |
|
|
|
+| **软引导** | 报告解读超限 | 同上 | "本月报告解读额度已用完,升级 FAMILY 解锁不限次深度解读" |
|
|
|
+| **进度可见** | 配额未用完 | 功能入口上方显示剩余次数进度条 | "本月 AI 对话剩余 2 次" |
|
|
|
+| **软引导** | 报告上传超限 | Toast + 上传按钮置灰 | "本月报告上传额度已用完(2/2),升级 FAMILY 解锁更多" |
|
|
|
+
|
|
|
+### 6.2 弹窗统一组件
|
|
|
+
|
|
|
+新建 `UpgradeGuideModal.vue`(小程序组件),统一处理所有软/硬引导场景:
|
|
|
+- 接收参数:`type`(soft/hard)、`quotaType`、`remaining`、`total`
|
|
|
+- 展示:图标 + 文案 + 行动按钮(硬门禁只有"升级",软引导有"知道了"+"了解详情")
|
|
|
+- 埋点:`basic_upgrade_click` 记录触发来源
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 数据模型变更
|
|
|
+
|
|
|
+### 7.1 `membership_levels` 新增种子数据
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 在 DatabaseInitializer.runMigrations() 中添加:
|
|
|
+
|
|
|
+// 迁移: membership_levels 新增 BASIC 体验会员等级
|
|
|
+try {
|
|
|
+ jdbcTemplate.execute("INSERT IGNORE INTO membership_levels " +
|
|
|
+ "(level_code, level_name, level_desc, price_monthly, features, max_children, max_tasks_per_day) " +
|
|
|
+ "VALUES ('BASIC', '体验会员', " +
|
|
|
+ "'9.9元/月体验版,解锁核心功能,限次使用AI与报告解读', " +
|
|
|
+ "990, " +
|
|
|
+ "'[\"free_activities\",\"free_courses\",\"discount_purchase\",\"invite_family\",\"mascot_ai_lite\",\"ai_report_reading_lite\",\"assessment_quota_lite\",\"health_report_upload_lite\",\"growth_plan_lite\",\"task_template_lite\"]', " +
|
|
|
+ "3, 3)");
|
|
|
+ log.info("已初始化BASIC体验会员等级");
|
|
|
+} catch (Exception e) {
|
|
|
+ // 等级已存在,忽略
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 7.2 `membership_benefits` 新增 BASIC 权益
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 在 DatabaseInitializer.runMigrations() 中添加:
|
|
|
+
|
|
|
+// 迁移: membership_benefits 新增 BASIC 会员权益
|
|
|
+try {
|
|
|
+ jdbcTemplate.execute("INSERT IGNORE INTO membership_benefits " +
|
|
|
+ "(level_code, benefit_code, benefit_name, benefit_desc, icon, bg_color, sort_order) VALUES " +
|
|
|
+ "('BASIC', 'AI_CHAT_LITE', 'AI健康顾问(限3次/月)', '每月3次AI健康顾问问答', '🤖', '#DBEAFE', 1), " +
|
|
|
+ "('BASIC', 'REPORT_READING_LITE', '报告解读(限1次/月)', '每月1次体检/测评报告AI解读', '📊', '#FCE7F3', 4), " +
|
|
|
+ "('BASIC', 'GROWTH_PLAN_LITE', '基础成长计划', '创建成长计划但模板有限', '📋', '#FEF3C7', 3), " +
|
|
|
+ "('BASIC', 'ASSESSMENT_QUOTA_LITE', '测评预约(限1次)', '每月可预约1次测评', '📝', '#E0E7FF', 8), " +
|
|
|
+ "('BASIC', 'REPORT_UPLOAD_LITE', '健康报告上传(限2份/月)', '每月可上传2份健康报告', '📄', '#FEF9C3', 9)");
|
|
|
+ log.info("已初始化BASIC会员权益列表");
|
|
|
+} catch (Exception e) {
|
|
|
+ // 已存在,忽略
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 7.3 新建 `basic_quota_usage` 表
|
|
|
+
|
|
|
+```sql
|
|
|
+CREATE TABLE IF NOT EXISTS basic_quota_usage (
|
|
|
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
|
+ user_id BIGINT NOT NULL COMMENT '家长用户ID(非family_id)',
|
|
|
+ quota_type VARCHAR(30) NOT NULL COMMENT 'AI_CHAT/REPORT_READING/ASSESSMENT_QUOTA/REPORT_UPLOAD',
|
|
|
+ used_count INT DEFAULT 0 COMMENT '本月已用次数',
|
|
|
+ total_count INT NOT NULL COMMENT '月度总配额',
|
|
|
+ period_start DATE NOT NULL COMMENT '周期开始日期(每月1号)',
|
|
|
+ period_end DATE NOT NULL COMMENT '周期结束日期(月末)',
|
|
|
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_user_type_period (user_id, quota_type, period_start),
|
|
|
+ INDEX idx_user_period (user_id, period_start)
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='BASIC会员月度配额使用记录';
|
|
|
+```
|
|
|
+
|
|
|
+### 7.4 schema.sql 同步更新
|
|
|
+
|
|
|
+- 在 `schema.sql` 末尾追加 `basic_quota_usage` 建表语句
|
|
|
+- 在 `membership_levels` INSERT 补充 BASIC 等级 seed 数据
|
|
|
+- 在 `membership_benefits` INSERT 补充 BASIC 权益 seed 数据
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 接口变更清单
|
|
|
+
|
|
|
+### 8.1 后端修改
|
|
|
+
|
|
|
+#### 8.1.1 `MembershipService.canUseFeature()` — 新增 BASIC 分支
|
|
|
+
|
|
|
+```java
|
|
|
+// 在现有 FREE / FAMILY / PREMIUM / PROVIDER 分支之间插入:
|
|
|
+if ("BASIC".equals(level)) {
|
|
|
+ return "free_activities".equals(feature)
|
|
|
+ || "free_courses".equals(feature)
|
|
|
+ || "discount_purchase".equals(feature)
|
|
|
+ || "invite_family".equals(feature)
|
|
|
+ || "mascot_ai_lite".equals(feature)
|
|
|
+ || "ai_report_reading_lite".equals(feature)
|
|
|
+ || "assessment_quota_lite".equals(feature)
|
|
|
+ || "health_report_upload_lite".equals(feature)
|
|
|
+ || "growth_plan_lite".equals(feature)
|
|
|
+ || "task_template_lite".equals(feature);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 8.1.2 `MembershipService.hasPermission()` — 无需改
|
|
|
+
|
|
|
+该接口已通过 features JSON 解析判断,BASIC 写入 features 后即自动支持,无需代码修改。
|
|
|
+
|
|
|
+#### 8.1.3 新增 `BasicQuotaService.java`
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class BasicQuotaService {
|
|
|
+
|
|
|
+ // 查询指定用户指定月份某配额的剩余次数
|
|
|
+ public QuotaStatusDTO getMonthlyQuota(Long userId, String quotaType);
|
|
|
+
|
|
|
+ // 尝试扣减配额,返回是否成功(配额不足返回 false + 提示文案)
|
|
|
+ public QuotaConsumeResult consumeQuota(Long userId, String quotaType);
|
|
|
+
|
|
|
+ // 批量刷新所有 BASIC 用户当月的配额(定时任务调用)
|
|
|
+ public void refreshMonthlyQuota();
|
|
|
+
|
|
|
+ // 检查用户当前是否为有效的 BASIC 会员
|
|
|
+ public boolean isActiveBasicMember(Long userId);
|
|
|
+
|
|
|
+ // 获取 BASIC 用户到期时间
|
|
|
+ public Date getExpireTime(Long userId);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**QuotaStatusDTO**:
|
|
|
+```java
|
|
|
+public class QuotaStatusDTO {
|
|
|
+ private String quotaType; // AI_CHAT / REPORT_READING / ...
|
|
|
+ private int total; // 总配额
|
|
|
+ private int used; // 已用
|
|
|
+ private int remaining; // 剩余
|
|
|
+ private Date periodStart; // 周期开始
|
|
|
+ private Date periodEnd; // 周期结束
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**QuotaConsumeResult**:
|
|
|
+```java
|
|
|
+public class QuotaConsumeResult {
|
|
|
+ private boolean success; // 是否扣减成功
|
|
|
+ private int remaining; // 扣减后剩余
|
|
|
+ private String toastMsg; // 配额不足时的 Toast 文案(可为 null)
|
|
|
+ private String actionUrl; // 跳转升级页面的 URL(可为 null)
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 8.1.4 业务入口集成点
|
|
|
+
|
|
|
+| 入口 Service | 方法 | 集成逻辑 |
|
|
|
+|-------------|------|---------|
|
|
|
+| `AiGateway.chat()` | 对话入口 | 先检查 `isActiveBasicMember(userId)`,若 true 则调用 `consumeQuota(AI_CHAT)`,失败返回 403 + 软引导文案 |
|
|
|
+| `ReportSummaryService.parseReport()` | 报告解读 | 同上,quotaType=`REPORT_READING` |
|
|
|
+| `AssessmentAppointmentService.create()` | 创建测评预约 | 同上,quotaType=`ASSESSMENT_QUOTA`,**硬门禁**,禁止继续 |
|
|
|
+| `DanReportUploadService.upload()` | 报告上传 | 同上,quotaType=`REPORT_UPLOAD`,超限时隐藏上传按钮 + 显示进度提示 |
|
|
|
+
|
|
|
+### 8.2 定时任务
|
|
|
+
|
|
|
+| Task | Cron | 职责 |
|
|
|
+|------|------|------|
|
|
|
+| `BasicQuotaRefreshTask` | `0 0 0 1 * ?` | 每月 1 号 00:00,遍历所有 BASIC 会员,重置 `used_count=0`,更新 `period_start/period_end` 为本月 |
|
|
|
+| `BasicExpiryNoticeTask` | `0 0 10 * * ?` | 每天 10:00,查找 `expireTime` 在 1-5 天内的 BASIC 用户,推送微信模板消息提醒 |
|
|
|
+| `BasicDowngradeExpiredTask` | `0 0 4 * * ?` | 每天 4:00,执行过期降级(复用现有 `MembershipService.downgradeExpiredMembers()`,需确认其支持 BASIC) |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. 前端变更清单
|
|
|
+
|
|
|
+### 9.1 小程序(cfc-frontend)
|
|
|
+
|
|
|
+| 页面/组件 | 变更类型 | 说明 |
|
|
|
+|----------|---------|------|
|
|
|
+| 会员权益页 `pages/profile/membership` | 修改 | 新增 BASIC 卡片,读 `membership_benefits` BASIC 行动态渲染 |
|
|
|
+| 会员开通页 `pages/profile/upgrade` | 修改 | 新增"9.9元/月"选项,仅支持月付,不显示年付/季付 |
|
|
|
+| AI 对话入口 | 修改 | 显示"本月剩余 X/3 次",超限调用 `UpgradeGuideModal(type=soft)` |
|
|
|
+| 测评预约入口 | 修改 | 显示"本月剩余 X/1 次",超限调用 `UpgradeGuideModal(type=hard)` 并禁用按钮 |
|
|
|
+| 报告上传/解读入口 | 修改 | 显示上传/解读剩余次数,超限软引导 |
|
|
|
+| 个人中心-会员状态卡片 | 修改 | 显示"体验会员 · 剩余 X 天",倒计时到期 |
|
|
|
+| 能量沙盘入口 | 无需改 | `UnlockGate.MEMBERSHIP` 已覆盖(`canUseFeature("mascot_ai_lite")` = true) |
|
|
|
+
|
|
|
+### 9.2 新增组件
|
|
|
+
|
|
|
+- **`UpgradeGuideModal.vue`**:统一软/硬引导弹窗,参数化 `type`、`quotaType`、文案
|
|
|
+- **`QuotaProgressBar.vue`**:配额进度条组件,通用展示"已用 X / 总额 Y"
|
|
|
+
|
|
|
+### 9.3 Web 管理端(cfc-web)
|
|
|
+
|
|
|
+| 页面 | 变更类型 | 说明 |
|
|
|
+|------|---------|------|
|
|
|
+| 会员等级管理 | 修改 | 自动显示 BASIC 等级(读 DB) |
|
|
|
+| BASIC 配额看板 | **新增** | 展示本月各配额使用率、BASIC 用户分布、到期提醒列表 |
|
|
|
+| 配额手动重置接口 | **新增** | 运营可手动重置某用户的当月配额(应急用) |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 10. 埋点与数据指标
|
|
|
+
|
|
|
+### 10.1 事件定义
|
|
|
+
|
|
|
+| 事件名 | 触发时机 | 关键属性 |
|
|
|
+|--------|---------|---------|
|
|
|
+| `basic_pay_click` | 点击"9.9元开通"按钮 | `from_page`(会员页/升级页/弹窗) |
|
|
|
+| `basic_pay_success` | 支付回调成功 | `order_no`, `amount`, `family_id` |
|
|
|
+| `basic_quota_consume` | 每次配额扣减 | `quota_type`, `remaining`, `period_start` |
|
|
|
+| `basic_quota_exhausted` | 某类配额归零 | `quota_type`, `family_id`, `user_id` |
|
|
|
+| `basic_upgrade_click` | 点击升级 FAMILY 按钮 | `trigger_type`(quota_exhausted/expiry_near/manual) |
|
|
|
+| `basic_upgrade_success` | 升级支付成功 | `from_level`, `to_level`, `family_id`, `upgrade_amount` |
|
|
|
+| `basic_expire_downgrade` | 到期自动降级 | `user_id`, `days_since_paid`, `has_data_retained` |
|
|
|
+| `basic_renew_success` | 续费 BASIC | `user_id`, `renew_days` |
|
|
|
+
|
|
|
+### 10.2 核心看板指标
|
|
|
+
|
|
|
+- BASIC 付费用户数 / 日(按 `basic_quota_usage` 首次写入 date 统计)
|
|
|
+- BASIC 月度配额使用率(各类型 `used_count / total_count`)
|
|
|
+- BASIC→FAMILY 升级转化漏斗(付费→首次使用→配额耗尽→点击升级→支付成功)
|
|
|
+- BASIC 次月留存曲线(按首次付费月份分层)
|
|
|
+- BASIC 用户 ARPU(含交叉销售:商品、测评等)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 11. 兼容性风险与缓解
|
|
|
+
|
|
|
+| 风险点 | 影响 | 缓解方案 |
|
|
|
+|--------|------|---------|
|
|
|
+| `canUseFeature` 硬编码分支遗漏 BASIC | BASIC 用户调用新功能时报权限拒绝 | 单元测试覆盖所有 featureCode,发布前全量冒烟 |
|
|
|
+| 现有 TrialMembership 与 BASIC 支付流程冲突 | 用户刚结束 7 天试用就被催促付费,体验差 | Trial 结束第 8 天推"9.9 元续享权益"而非"开通会员",文案区分 |
|
|
|
+| 配额刷新定时任务失败导致用户次月无配额 | 用户投诉、信任受损 | 任务幂等(先 DELETE 再 INSERT);增加手动重置接口;监控告警 |
|
|
|
+| `MembershipService.downgradeExpiredMembers()` 不识别 BASIC | BASIC 到期后等级不降级 | 在现有方法中补充 `BASIC` 的判断逻辑 |
|
|
|
+| 前端缓存导致权益页不显示 BASIC | 新用户看不到 9.9 选项 | 版本号机制强制刷新;或在 `MembershipController.getLevels()` 接口中缓存 TTL=5 分钟 |
|
|
|
+| 9.9 元价格过低冲击 FAMILY 定价 | 现有 FAMILY 用户要求退费改买 BASIC | 1) BASIC 不支持年付 2) FAMILY 升级时展示"专属权益对比"价值锚定 3) 运营控制推送人群(仅免费活跃用户) |
|
|
|
+| 多家长同家庭各自持 BASIC 配额 | 配额按 user_id 独立,同一家庭可能有两个 BASIC 用户 | 这是决策2的预期行为,不做限制;但前端展示时统一显示家庭视角的汇总信息 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 12. 发布计划
|
|
|
+
|
|
|
+| 阶段 | 时间 | 交付物 | 验收标准 |
|
|
|
+|------|------|--------|---------|
|
|
|
+| **P0 核心链路** | T+3 天 | DB 迁移 + BASIC 等级 + 支付开通 + 基础权限判断 | 9.9 元支付成功 → BASIC 生效 → 能进沙盘/AI 对话 3 次 |
|
|
|
+| **P1 配额系统** | T+5 天 | `BasicQuotaService` + 4 个业务入口配额扣减 + 定时刷新 | 月度配额正确扣减/刷新,超限软/硬引导生效 |
|
|
|
+| **P2 前端展示** | T+7 天 | 权益页/开通页/配额显示/升级弹窗 | 免费用户可见 BASIC 卡片,付费后正确显示剩余次数 |
|
|
|
+| **P3 运营配套** | T+10 天 | 推送模板 + 埋点 + 管理端配额看板 | 到期提醒/额度耗尽提醒自动发送,看板数据可查 |
|
|
|
+| **灰度/全量** | T+12 天 | 5% → 20% → 100% 流量灰度 | 核心指标无异常波动,全量放开 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 13. 验收用例(关键路径)
|
|
|
+
|
|
|
+| 用例 ID | 场景 | 预期结果 |
|
|
|
+|--------|------|---------|
|
|
|
+| UC-01 | 免费用户支付 9.9 元 | `user.memberLevel=BASIC`、`memberExpireTime=30天后`、`family_memberships` 写入 BASIC 记录、`basic_quota_usage` 初始化 4 类配额(used=0) |
|
|
|
+| UC-02 | BASIC 用户第 1 次 AI 对话 | `canUseFeature(mascot_ai_lite)=true`,配额扣减成功,`remaining=2/3`,返回对话结果 |
|
|
|
+| UC-03 | BASIC 用户第 4 次 AI 对话 | `consumeQuota(AI_CHAT)` 返回 false,前端 Toast "本月额度已用完(3/3),升级 FAMILY 享不限次" |
|
|
|
+| UC-04 | BASIC 用户第 2 次测评预约 | `consumeQuota(ASSESSMENT_QUOTA)` 硬门禁,弹窗阻断,禁止继续操作 |
|
|
|
+| UC-05 | 月初定时任务刷新 | 所有 BASIC 用户 `basic_quota_usage.used_count=0`,`period_start` 更新为本月 1 号 |
|
|
|
+| UC-06 | BASIC 到期自动降级 | `downgradeExpiredMembers()` 跑批,`user.memberLevel=FREE`,`memberExpireTime=null`,配额表保留历史但不刷新 |
|
|
|
+| UC-07 | BASIC 到期前 5 天推送 | 收到微信模板消息"您的体验会员 5 天后到期,还有 X 次 AI 对话未使用" |
|
|
|
+| UC-08 | BASIC 用户升级 FAMILY | 支付差价 → `memberLevel=FAMILY`,配额表停止扣减(FAMILY 走不限逻辑) |
|
|
|
+| UC-09 | 同一家庭两个 BASIC 用户 | 各自配额独立(user_id 维度),互不影响 |
|
|
|
+| UC-10 | Trial 结束当天推荐 BASIC | 第 8 天推送"9.9 元续享权益"(非"开通会员"),文案与 Trial 区分 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 14. 已确认的设计决策
|
|
|
+
|
|
|
+| # | 决策项 | 选择 | 说明 |
|
|
|
+|---|--------|------|------|
|
|
|
+| 1 | 到期后是否自动升级 FAMILY | **A. 否** | 到期必须手动选择续费 BASIC 或升级 FAMILY,不做自动续费 |
|
|
|
+| 2 | 配额按 family_id 还是 user_id 共享 | **B. 按 user_id 独立** | 每个家长账号独立配额,同一家庭多个 BASIC 用户配额互不干扰 |
|
|
|
+| 3 | 是否做阶梯定价(首月 9.9/次月 19.9) | **A. 固定 9.9 元/月** | 价格透明,长期稳定,利于口碑和留存 |
|