| New file |
| | |
| | | # 家属卡:两代实现并存,审核通过后家属卡实际不可用 |
| | | |
| | | Status: ready-for-agent |
| | | |
| | | 产出于支付线的只读排查(未修改本业务任何代码/迁移/前端)。移交对象:负责家属卡业务的同事。 |
| | | |
| | | ## 现象 |
| | | |
| | | 1. 小程序提交家属卡申请、后台审核,都能正常完成,**但审核通过后家属卡用不了权益**:核销时直接报 |
| | | `409 亲属附属卡未找到绑定的主卡`。 |
| | | 2. 后台「家属卡申请」页与实际待审数量对不上:页面上有申请,工作台/待办却永远不提醒。 |
| | | |
| | | ## 根因 |
| | | |
| | | 同一件事有**两张表、两套接口**,且迁移没做完: |
| | | |
| | | | | 旧:`dependent_card_apply` | 新:`family_card_application` | |
| | | | --- | --- | --- | |
| | | | 在迁移里 | ❌ 迁移从未创建(V141 才补上) | ✅ 有 | |
| | | | 状态类型 | `tinyint` 0待审/1通过/2驳回/3取消 | 字符串 `待审核`/`已通过`/`已驳回`/`已解绑` | |
| | | | 申请入口 | ✅ 小程序 + 后台三个页面都在用 | ❌ 唯一写入口 `FamilyCardPortalService.create` 无任何调用者 | |
| | | | 消费侧读取 | ❌ 无人读 | ✅ 额度/权益判定、洗车、票券包、影院、展示策略都读它 | |
| | | |
| | | - 写入侧的绑定逻辑只在**旧表审核**里缺失:`DependentCardApplyAdminService.audit()` 仅更新 `status` |
| | | 并写 `dependent_card_apply_status_log`,**不写 `family_talent_id` / `family_card_id`**,也不在新表留记录。 |
| | | - 读取侧只认新表:`BenefitQuotaService`(非 PERSONAL 卡按 `family_card_id` 找主卡,找不到即 409)、 |
| | | `BenefitQuotaService.sharedCardIds`(额度共享)、`TransportCarWashCredentialMapper`、 |
| | | `TicketPackageClaimMapper`、`CinemaPortalService`、`MerchantDisplayPolicyPortalService`。 |
| | | - 新表自己的接口 `/api/admin/cards/family-applications`、`/api/admin/cards/family-cards`、 |
| | | `/api/admin/cards/family-applications/{id}/audit`(`CardAdminService`)**前端无任何调用**。 |
| | | |
| | | ## 证据 |
| | | |
| | | 数据(开发库 `talent_card`,2026-09-14): |
| | | |
| | | ``` |
| | | 旧表 dependent_card_apply : 13 行,7 待审 / 2 通过 / 4 取消;family_talent_id、family_card_id 全部为 NULL |
| | | 新表 family_card_application : 5 行,3 已通过 / 1 已解绑 / 1 已驳回;其中 4 行有真实 family_talent_id + family_card_id |
| | | ``` |
| | | |
| | | 调用方(grep 结论): |
| | | |
| | | - 小程序 `rencaika/services/api.uts`: `appFamilyCards` → `/api/app/family-cards/applications`(旧表, |
| | | `DependentCardApplyController`) |
| | | - 后台 `talent-card-admin/src/api/admin.ts`: `getFamilyCardApplications` / `getFamilyCardApplicationDetail` / |
| | | `auditFamilyCardApplication` / `unbindFamilyCard` → 全部 `/api/admin/dependent-card-applies`(旧表) |
| | | - 后台页面 `FamilyCardView.vue`、`FamilyCardApplicationDetailView.vue`、`FamilyCardDetailView.vue` 都走上面这组接口 |
| | | - 工作台待办 `AdminBusinessService`:`select count(*) ... from family_card_application where status = '待审核'` |
| | | → 数的是新表,与实际待审(旧表)不一致 |
| | | |
| | | ## 影响 |
| | | |
| | | 1. 旧入口审核通过后**不产生绑定**,家属卡拿卡后用不了权益(额度判定第一步 409)。 |
| | | 2. 洗车凭证、票券包领取、影院购票、展示策略都查不到家属卡绑定关系。 |
| | | 3. 主卡与家属卡的**额度共享不生效**(`sharedCardIds` 也读新表)。 |
| | | 4. 后台两个页面展示不同数据源;「家属卡申请待审核」待办数恒为 0(新表无待审),后台不会提醒。 |
| | | 5. 新表现有 5 行数据**没有可持续的来源**(写入口是死代码),只能靠直接写库产生。 |
| | | |
| | | ## 建议改法 |
| | | |
| | | - **方案 A(推荐)**:把小程序提交入口 + 后台三个页面切到新表 `family_card_application`,旧表连同 |
| | | `dependent_card_apply_status_log` 一起退休;审核时写 `family_talent_id` / `family_card_id`,让 |
| | | 申请→审核→绑定→权益一条线。 |
| | | - 方案 B:反向统一到旧表——消费侧 5 处改读旧表,并补上旧表的绑定写入。 |
| | | - 方案 C:两表双向同步。不推荐,双份维护迟早再裂。 |
| | | |
| | | 决定方案前建议先确认:家属卡是否还要求「仅卓越人才卡可申请、每张主卡最多 2 个家属、累计最多 3 个申请」 |
| | | (旧表 `DependentCardApplyService` 里有这套校验,新表侧没有)。 |
| | | |
| | | ## Comments |
| | | |
| | | - 2026-09-14 支付线会话只读排查后记录;同日补建了旧表迁移 `V141__create_dependent_card_apply.sql` |
| | | (该表迁移里一直缺,缺失会导致工作台统计与家属卡申请页 500),已与用户确认保留并知会。 |