2026-07-14-family-promotion-redesign.md 13 KB

家庭推广体系重构设计文档

概述

将现有个人级推广/佣金体系重构为家庭级体系,所有二维码改为微信小程序码(wxacode),推广收益归入家庭公共账户,重新设计推广中心前端页面。

1. 二维码体系

1.1 全部改用 wxacode

所有二维码强制使用 WechatService.generateWxacode(),移除 ZXing 兜底。改造现有点:

端点 原有方式 改造后
POST /api/common/qrcode ZXing 普通二维码 wxacode,新注册使用
POST /api/invite/qrcode wxacode + ZXing 降级 仅 wxacode,移除降级
POST /api/family/invite/generate wxacode + ZXing 降级 仅 wxacode,移除降级

1.2 两种二维码类型

类型A:注册推广码

字段
scene ref={referralCode} (referralCode = 6位字母数字)
page pages/invite/join
生成端点 POST /api/common/qrcode → 入参 { type: "register", referralCode: "xxx" }
说明 废弃旧版 { content } 入参,改 type 区分场景;wxacode 失败时返回错误信息(用户可重试),不再降级为 ZXing 普通码

扫码流程:

用户扫码 → 打开小程序 → App.vue handleScene()
  → 解析 scene 中的 ref=xxx → navigateTo /pages/invite/join?refCode=xxx
  → 新用户注册时将 refCode 转为 referrerId 写入 user.referrerId
  → 结算时 referrerId → familyId → 归属到家庭公共账户

类型B:家庭邀请码

字段
scene invite={token} (token = UUID,已有)
page pages/invite/join
生成端点 POST /api/family/invite/generate(已有,不变)

扫码流程(已有,不变):

用户扫码 → 打开小程序 → App.vue handleScene()
  → 解析 scene 中的 invite=token → navigateTo /pages/invite/join?token=xxx
  → 验证 token → 加入家庭

1.3 修复 env_version 硬编码

1.4 wxacode 失败处理

移除 ZXing 降级后,wxacode 生成失败的策略:

失败原因 处理方式
access_token 过期 自动重试一次(重新获取 token)
频率超限(45009) 返回错误码提示用户稍后重试,不降级
其他 API 错误 记录日志,返回错误信息
微信 API 不可达 返回错误,提示用户稍后再试

前端收到错误后显示「生成二维码失败,请稍后重试」,不自动降级。

1.5 修复 env_version 硬编码

@Value("${wechat.env-version:release}")
private String envVersion;

各环境配置: | 环境 | 值 | |------|-----| | dev | development | | test | trial | | prod | release |

2. 推广体系重构

2.1 核心变更:个人 → 家庭

现有体系(个人级):

用户 referralCode → 推荐新用户 → 佣金记到 user 个人

新体系(家庭级):

用户 referralCode → 推荐新用户 → 佣金记到 family 公共账户
                                    ↓
                         个人贡献记录保留(用于展示谁推荐了多少)

2.2 数据模型

新增表:family_earnings(家庭公共账户总账)

CREATE TABLE family_earnings (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    family_id BIGINT NOT NULL UNIQUE COMMENT '家庭ID',
    total_earned BIGINT NOT NULL DEFAULT 0 COMMENT '累计推荐收入(分)',
    available_amount BIGINT NOT NULL DEFAULT 0 COMMENT '当前可支配余额(分)',
    withdrawn_amount BIGINT NOT NULL DEFAULT 0 COMMENT '已提现金额(分)',
    distributed_amount BIGINT NOT NULL DEFAULT 0 COMMENT '已颁发给成员的金额(分)',
    updated_at DATETIME,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_family_id (family_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭公共账户';

新增表:family_earnings_member(成员已获分配余额)

CREATE TABLE family_earnings_member (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    family_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    allocated_amount BIGINT NOT NULL DEFAULT 0 COMMENT '管理员累计分配(分)',
    consumed_amount BIGINT NOT NULL DEFAULT 0 COMMENT '已消费金额(分)',
    available_amount BIGINT NOT NULL DEFAULT 0 COMMENT '可消费余额 = allocated - consumed(分)',
    can_use_family_balance TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否允许使用家庭公共池',
    updated_at DATETIME,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE INDEX idx_family_user (family_id, user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭成员已分配余额';

新增表:family_earnings_record(收支流水)

CREATE TABLE family_earnings_record (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    family_id BIGINT NOT NULL,
    type VARCHAR(20) NOT NULL COMMENT 'earn收入/withdraw提现/distribute颁发/consume消费',
    amount BIGINT NOT NULL COMMENT '金额(分)',
    from_user_id BIGINT COMMENT '操作人',
    to_user_id BIGINT COMMENT '受益人(颁发/消费时填写)',
    note VARCHAR(255) COMMENT '备注',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_family_id (family_id),
    INDEX idx_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭收益收支流水';

修改表:commission_records 加列

ALTER TABLE commission_records ADD COLUMN family_id BIGINT COMMENT '归属家庭ID';

2.3 收益流转

成员推荐新用户 → 新人消费产生订单
         ↓
  CommissionService.settle()
    ├── 写 commission_records(个人级别,+family_id)
    ├── family_earnings.total_earned += 佣金
    ├── family_earnings.available_amount += 佣金
    └── family_earnings_record (type=earn)

2.4 交互流程

管理员提现

管理员发起提现(¥100起)
  → 扣 family_earnings.available_amount
  → 写 family_earnings_record (type=withdraw)
  → 写 withdrawal_requests(新增 family_withdraw 类型,关联 family_id)
  → 平台管理员审核 → 打款到管理员支付宝

管理员颁发给成员

管理员选择成员 + 输入金额
  → 扣 family_earnings.available_amount
  → 加 family_earnings_member.allocated_amount
  → 重算 family_earnings_member.available_amount
  → 写 family_earnings_record (type=distribute)

管理员开关"允许使用家庭余额"

管理员切换某成员的 can_use_family_balance 开关
  → UPDATE family_earnings_member SET can_use_family_balance = ?

成员消费(购物支付)

成员下单结算时,支付选项含「家庭余额」
选择家庭余额 → 按以下顺序扣款:

  ① family_earnings_member.available_amount(个人分配额度)
     ↓ 不够才进下一步
  ② 如果 can_use_family_balance=true 且 family_earnings.available_amount > 0
     从 family_earnings.available_amount 扣差额
     ↓ 还不够
  ③ 微信支付补差

  扣款成功后:
    - 写 family_earnings_record (type=consume)
    - 更新 family_earnings_member.consumed_amount
    - 如果用了公共池,更新 family_earnings.available_amount

3. 推广中心前端重构

3.1 页面结构

推广中心(pages/promotion/index.vue)
├── 头部:家庭总数据卡片
│   ├── 累计推荐人数
│   ├── 家庭总收益(元)
│   └── 可支配余额(元)
│
├── 成员贡献榜
│   ├── 列表:头像 + 昵称 + 推荐人数 + 角色标签
│   └── 当前用户高亮
│
├── 管理员专属面板(仅 isFamilyAdmin 可见)
│   ├── 提现按钮 → 弹窗输入金额
│   ├── 颁发给成员 → 选择成员 + 输入金额
│   └── 成员权限管理 → 开关 can_use_family_balance
│
├── 操作区
│   ├── 生成推广二维码(wxacode)
│   ├── 分享海报
│   └── 复制邀请码
│
├── Tab 导航
│   ├── 推广明细 → 现有 commission.vue 改为显示家庭级
│   ├── 我的团队 → 现有 team.vue 适配家庭模式
│   └── 排行榜 → 现有 leaderboard.vue
│
└── 提现入口 → 现有 withdraw.vue 增加家庭余额提现

3.2 孩子角色可见

  • 孩子可访问推广中心(当前只有 parent/teacher 能看到)
  • 孩子可查看自己的贡献(推荐人数)
  • 孩子可看到家庭总数据(只读)
  • 孩子可生成自己的推广二维码
  • 孩子不可见管理员操作面板

4. 后端 API 变化

4.1 新增 API

方法 端点 说明
POST /api/earnings/family/summary 家庭收益总览(总推荐数、总收益、可用余额)
POST /api/earnings/family/members 各成员贡献列表(推荐人数 + 分配余额)
POST /api/earnings/family/records 家庭收益流水
POST /api/earnings/admin/distribute 管理员颁发给成员
POST /api/earnings/admin/toggle-member 开关成员的家庭余额权限
POST /api/earnings/admin/withdraw 管理员提现(走现有 withdrawal_requests)

4.2 改造 API

端点 改动
POST /api/common/qrcode 改为 wxacode,新增 type=register 支持
POST /api/invite/summary 返回家庭总推荐数 + 个人贡献
POST /api/commission/summary 返回家庭级统计数据
POST /api/family/invite/generate 移除 ZXing 降级,仅用 wxacode

4.3 各订单服务结算改造

6 个调用 settle() 的服务需同步改造:

服务 改动
AssessmentOrderService 结算时取买家 familyId 写入 commission_records 并更新 family_earnings
PaymentService 同上
PackagePaymentService 同上
ProductOrderService 同上
MemberSubscriptionService 同上
MembershipService 同上

5. 注册场景处理

5.1 新用户通过推广码注册

pages/invite/join?refCode=xxx 打开
  → 注册页显示推荐人信息(昵称 + 家庭名)
  → 用户完成注册(微信登录 + 授权)
  → 后端:
      1. 通过 referralCode 查 user
      2. 取 user.familyId
      3. 新用户写入 user.referrerId = 推荐人ID
      4. 更新推荐人的 directCount
      5. 家庭公共账户绑定关系建立
  → 新用户创建自己的家庭(或加入已有家庭)

5.2 App.vue scene 解析

handleScene(options) {
    if (!options || !options.query) return
    var scene = decodeURIComponent(options.query.scene || '')
    if (scene.indexOf('ref=') === 0) {
        var refCode = scene.substring(3)
        uni.navigateTo({ url: '/pages/invite/join?refCode=' + refCode })
    } else if (scene.indexOf('invite=') === 0) {
        var token = scene.substring(7)
        uni.navigateTo({ url: '/pages/invite/join?token=' + token })
    }
}

6. 前端 API 新增

// api.js 新增
export const getFamilyEarningsSummary = () =>
  request('/api/earnings/family/summary', 'POST')

export const getFamilyEarningsMembers = () =>
  request('/api/earnings/family/members', 'POST')

export const getFamilyEarningsRecords = (params) =>
  request('/api/earnings/family/records', 'POST', params)

export const distributeToMember = (userId, amount) =>
  request('/api/earnings/admin/distribute', 'POST', { userId, amount })

export const toggleMemberBalance = (userId, enabled) =>
  request('/api/earnings/admin/toggle-member', 'POST', { userId, enabled })

export const withdrawFamilyEarnings = (amount) =>
  request('/api/earnings/admin/withdraw', 'POST', { amount })

7. 管理员后台

新增页面:家庭收益管理

  • 搜索:按家庭名称/ID
  • 查看:家庭总账、成员分配情况
  • 提现审核:列表显示待审核的家庭提现申请
  • 操作:通过/拒绝家庭提现

8. 忽略/不做的范围

  • ❌ 不重建完整的家庭间分润系统
  • ❌ 不改现有 promotion_tier(R0-R4)等级体系
  • ❌ 不改现有 referral_tree 物化路径表
  • ❌ 不改现有 invite_milestone 里程碑奖励

9. 实施分阶段建议

阶段 内容 涉及
P1 二维码改造:全部切 wxacode + 修复 env_version + 新增 ref= 场景处理 WechatService, CommonController, App.vue
P2 家庭公共账户:建表 + CommissionService 改造 + settle 调用点改造 + 注册绑定 referralCode 3 张新表 + 6 个 order service
P3 前端重构:推广中心重设计 + 成员贡献榜 + 管理员面板 + 消费支付集成 7 个 frontend pages + 支付流程
P4 管理后台:家庭收益管理 + 提现审核 admin panel

每阶段可独立上线,P1 无业务影响(二维码表现不变),P2/P3 为核心功能,P4 为运营配套。