|
@@ -0,0 +1,62 @@
|
|
|
|
|
+# 团队邀请功能及流程改造需求变更
|
|
|
|
|
+
|
|
|
|
|
+> 变更编号:INVITE-2026-11-12-V1 | 变更日期:2026-11-12 | 版本:v1.0
|
|
|
|
|
+> 合入:`origin/cfclub` merge commit `9afaa6e46`(parents `8dcdd24bc` + `ac4ba5613`),2026-11-12 10:39
|
|
|
|
|
+
|
|
|
|
|
+## 一、需求原话
|
|
|
|
|
+
|
|
|
|
|
+> 改造团队邀请功能及流程,在我的页面点团队邀请时,不是生成海报,而是直接分享邀请页面,被邀请人直接填服务人员申请表,记在邀请人下。如果还未注册,先完成注册,推荐人也是邀请人
|
|
|
|
|
+
|
|
|
|
|
+## 二、现状核查
|
|
|
|
|
+
|
|
|
|
|
+- **入口**:`pages/profile-main/profile.vue`「+邀请成员」按钮与浮动按钮原 `@click="showShareQr"` 生成分享海报(ContentSharePoster),需用户手动保存/转发,链路长。
|
|
|
|
|
+- **服务人员申请表**:`pages/profile/service-role-apply.vue` → `POST /api/service-role/apply`(`ServiceRoleApplicationDTO`),统一表 `service_role_applications` + 审批回写 `users.*Status`;申请与邀请人**无任何归属关系**(无 inviter 字段)。
|
|
|
|
|
+- **注册与归属链**:`users.referrerId`(推荐人)由 `/api/invite/bind`→`CommissionService.bindReferral` 写入并发分销奖励;另有 `/api/auth/register-with-invite`(`registerByInviteCode`)。
|
|
|
|
|
+- **三套邀请码体系互不相通**:
|
|
|
|
|
+ 1. 佣金/推广码 `users.referral_code`(6位 A-Z/2-9,`/api/invite/code` 生成、`/api/invite/bind` 绑定→写 `users.referrerId`)
|
|
|
|
|
+ 2. 分销码 `distribution_relations.invite_code`(8位,`register-with-invite` 只认这套)
|
|
|
|
|
+ 3. 家庭码 `family.invite_code`(8位 hex,`createJoinRequest` 不写 referrerId)
|
|
|
|
|
+ 团队邀请属「邀请服务人员」,走**第①套佣金/推广码**。
|
|
|
|
|
+
|
|
|
|
|
+## 三、用户裁决口径(4 项,全部锁定)
|
|
|
|
|
+
|
|
|
|
|
+| 裁决项 | 口径 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| 归属 | **两件都做**——记录级 `service_role_applications.inviter_user_id`(申请挂邀请人名下)+ 用户级 `users.referrerId`(推荐人=邀请人)**并存、互不替代** |
|
|
|
|
|
+| 注册判据 | **微信静默授权即算注册**;不引入短信验证码;**明确禁止**用 `/api/auth/register-with-invite` |
|
|
|
|
|
+| 邀请页形态 | **分享直达现有申请表** `service-role-apply`,不新建邀请人展示页、不加邀请人头像/昵称展示 |
|
|
|
|
|
+| 分销副作用 | **归属 + 发分销奖励**——邀请服务人员也算推广,走现有分销绑定、发 CF 值(真实 F24 资产,用户裁决接受) |
|
|
|
|
|
+
|
|
|
|
|
+## 四、需求变更定义
|
|
|
|
|
+
|
|
|
|
|
+| 变更 | 文件 | 内容 |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| S2-1 | `cfc-frontend/pages/profile-main/profile.vue` | 「+邀请成员」「浮动按钮」原生成海报入口改为内嵌透明 `<button open-type="share">`(`.share-overlay-btn`,`opacity:0` 非 `display:none`);新增页面级 `onShareAppMessage` 覆盖 mixin 默认首页分享,`path` 直指 `/pages/profile/service-role-apply?refCode=<码>`;`onShow` 预热 `loadReferralCode()` + 双缓冲;空码兜底 toast「邀请码准备中,请稍候重试」;`showShareQr()` 成死代码、海报不再触发 |
|
|
|
|
|
+| S2-2 | `cfc-frontend/pages/profile/service-role-apply.vue` | `onLoad` 解析 `options.refCode` 存组件字段 `inviteRefCode` + 独立 key `serviceRoleApplyRefCode`(不用会被消费清掉的 `storage.refCode`);无参分支从独立 key 恢复;未登录就地浮层登录后继续;**提交成功后串行执行推荐人绑定**(见 S2-4 资产闸门) |
|
|
|
|
|
+| S2-3 | 后端 `ServiceRoleApplyDTO`(+`refCode` 入参)/ `ServiceRoleApplication` 实体(+`inviterUserId`)/ `ServiceRoleApplicationServiceImpl.submit` / `schema.sql` / `DatabaseInitializer` 迁移467 / `API_REFERENCE.md` §4.44 | 记录级归属:`service_role_applications` 增 `inviter_user_id bigint NULL`(普通索引,存量不回填);`submit` 服务端按 `dto.getRefCode()` 反查 `User::getReferralCode` 写入,**剔除前端直传 inviterUserId(防冒领)**;复用无效码/自邀请拦截;`admin/list` 暴露 `inviterUserId`(`admin/operator` 权限门) |
|
|
|
|
|
+| S2-4 | `service-role-apply.vue` 资产闸门 | 三道防重复发 CF:前端 `userRefBound`/`bindingRef`/串行 await → 后端 `bindReferral:140-142` 抛错式幂等(已绑定在副作用前 throw)→ DB 唯一键 `cf_balance_log.uk_ref_type(member_id,type,ref_type,ref_id)` DuplicateKey 去重。失败留码可重试、失败 modal 不承诺虚假恢复路径 |
|
|
|
|
|
+
|
|
|
|
|
+### 三口径(全部在 `save()` 之前判定,不静默吞)
|
|
|
|
|
+
|
|
|
|
|
+1. 无 `refCode`(个人中心主动进入)→ `inviterUserId=null` 正常受理;
|
|
|
|
|
+2. 带 `refCode` 但无效/自邀请 → `Result.error("邀请码无效或不能邀请自己,请通过邀请人的分享链接进入")` 拒绝落库;
|
|
|
|
|
+3. 有效 `refCode` → 记录级写入 + 用户级走现有 `bindReferral`(发分销 CF)。
|
|
|
|
|
+
|
|
|
|
|
+## 五、资产一致性(发真实 CF 前的强制闸门)
|
|
|
|
|
+
|
|
|
|
|
+`doSubmit` 成功 → 才串行 `bindUserReferral`;清码移入绑定成功分支;绑定源用 `this.inviteRefCode`(两源同源防错配);`userRefBound` 双重幂等防重入;删两处空 catch(用户级失败可见、不静默)。杜绝「申请失败但 CF 已发 / 成功但绑定失败且码已清不可重试」两类错发/少发。
|
|
|
|
|
+
|
|
|
|
|
+## 六、验收与未测项
|
|
|
|
|
+
|
|
|
|
|
+- 验收:分享入口不再出海报、直达申请表带 `refCode`;未注册被邀请人静默授权即注册并继续填表;提交后记录级挂邀请人、用户级绑推荐人;重试绝不重复发 CF;无效码/自邀请拒绝落库。
|
|
|
|
|
+- **未测**(如实):`mvn` 编译(`.m2` 空、CI 兜底);真机/运行时端到端;邀请人查看/审批名下申请(本期明确不做)。
|
|
|
|
|
+- **登记技术债(不阻断)**:
|
|
|
|
|
+ - P2 幂等抛错误报循环:后端已成功但响应丢失→重试被 `bindReferral:140` 抛错→前端误报失败。修法=前端 catch 识别「已绑定推荐人」按成功收敛;**禁改后端**(`/api/invite/bind` 多链路共享)。
|
|
|
|
|
+ - P1 status view 无补绑入口:若加须直连 `bindUserReferral()`、勿接 `doSubmit`;**先 P2 后 P1**。
|
|
|
|
|
+ - 并发双穿应用幂等闸时 `directCount`/排行榜理论 +2(不涉真实资产,DB 唯一键兜住 CF)。
|
|
|
|
|
+
|
|
|
|
|
+## 七、关联记录
|
|
|
|
|
+
|
|
|
|
|
+- 合入实现:merge commit `9afaa6e46`(tree `b785438fa`,parent1 `8dcdd24bc` + parent2 `ac4ba5613`)
|
|
|
|
|
+- 文件清单(8):后端 `ServiceRoleApplyDTO.java`、`ServiceRoleApplication.java`、`ServiceRoleApplicationServiceImpl.java`、`schema.sql`、`DatabaseInitializer.java`;前端 `pages/profile-main/profile.vue`、`pages/profile/service-role-apply.vue`;文档 `docs/superpowers/api/API_REFERENCE.md`(§4.44)
|
|
|
|
|
+- 需求分析台账新增本章;无既有变更覆盖。
|