diff --git a/changelogs-v2/2026-10/01_8679_收款账户关联服务人员档案-修改接口-管理后台.md b/changelogs-v2/2026-10/01_8679_收款账户关联服务人员档案-修改接口-管理后台.md new file mode 100644 index 00000000..25938f8e --- /dev/null +++ b/changelogs-v2/2026-10/01_8679_收款账户关联服务人员档案-修改接口-管理后台.md @@ -0,0 +1,223 @@ +--- +schema: "hl-changelog/v2" +ticket: "8679" +title: "收款账户关联服务人员档案:新增选服务人员候选接口 + 个人类收款方 payeeRefId 必填并挂档案校验(#8679)" +consumer: "admin" +author: "yst(GIT)" +change_type: "修改接口" +backend_status: "merged" +gateway_status: "not_required" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "财务「资金账户→收款账户」个人类收款方(司机/导游/摄影/领队)从手填人员 ID/按名认人,改为从人员档案下拉选具体人。新增「选服务人员」聚合候选接口;create 个人类 payeeRefId 由可空变必填、payeeName 由手填变档案真名覆盖(后端强制),并新增档案存在性+在册校验(拦下架人员/黑名单·休假司机)。司机接 fleet 车队档案、导游/摄影/领队接 resource 服务人员档案。组织类(车队/导游公司/供应商)不变仍手填。" +updated_at: "2026-10-01" +base: "dev-v3" +--- + +# finance:收款账户关联服务人员档案(管理后台) + +## 1. 接口背景 + +财务「资金账户 → 收款账户」登记收款方时,**个人类收款方**(司机 DRIVER / 导游 GUIDE / 摄影 PHOTOGRAPHER / 领队 LEADER)原来是**手填人员 ID + 手填姓名**,无档案校验——可填错人、填黑名单司机、填已下架人员,钱打给谁的依据不严谨。 + +本次让个人类收款方**挂到真实人员档案**:前端表单改为「选择服务人员」下拉(从档案源选人),后端 create 强制校验档案真实存在且在册。司机档案在 **fleet 车队域**,导游/摄影/领队在 **resource 服务人员域**。 + +## 2. 变更清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 选服务人员候选 | GET | `/admin/finance/payee-accounts/staff-candidates` | **新增接口** | 按 payeeType 分流返回人员候选下拉数据 | +| 2 | 登记收款方账户 | POST | `/admin/finance/payee-accounts` | **修改接口** | 个人类 `payeeRefId` 必填 + `payeeName` 被档案真名覆盖 + 档案校验 | +| 3 | 编辑收款方账户 | PUT | `/admin/finance/payee-accounts/{payeeId}` | **修改接口** | 个人类禁止手改 `payeeName` | + +## 3. 接口详情 + +### 3.1 选服务人员候选(新增) + +- **使用场景**:收款账户表单选了「收款方类型」为个人类后,「选择服务人员」下拉/弹窗的数据源 +- **认证**:JWT(管理后台) +- **入参(query)**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| payeeType | string | 是 | `DRIVER`/`GUIDE`/`PHOTOGRAPHER`/`LEADER`(个人类;传组织类或非法值报 595202) | +| keyword | string | 否 | 姓名模糊;输入 11 位手机号按手机精确匹配。≤50 字,超限报 595202 | +| page | int | 否 | 缺省 1 | +| pageSize | int | 否 | 缺省 20,最大 100 | + +- **行为**:按 payeeType 分流到对应档案源——DRIVER→fleet 司机、GUIDE→resource 导游(含助理导游)、PHOTOGRAPHER→摄影、LEADER→领队。档案服务故障时**降级返回空集合**(不打塌表单,前端下拉显示"暂无可选人员"即可)。 +- **出参**:`data.records[]` + `data.total` + +### 3.2 登记收款方账户(修改) + +- 个人类:`payeeRefId` **必填**(选中的服务人员 ID),后端校验该 ID 在对应档案源**真实存在且在册**(staff 上架 status=1;driver 在册 season=active 且非休假/待激活),并以**档案真名覆盖 payeeName**。 +- 组织类(FLEET/GUIDE_CO/SUPPLIER):不变,`payeeRefId` 可空、`payeeName` 手填。 + +### 3.3 编辑收款方账户(修改) + +- 个人类:禁止手改 `payeeName`(名称以人员档案为准),传了报 595202。账户要素(qr/bankAccount/bankName)仍可改。 +- 组织类:不变。 + +## 4. 接口入参 + +### 4.1 登记请求体关键字段(变化部分) + +| 字段 | 类型 | 必填 | 说明 | 校验规则 | +|------|------|------|------|----------| +| payeeType | string | 是 | 收款方类型 | 个人类见下 | +| payeeRefId | string(Long) | **个人类必填** | 服务人员 ID(staff-candidates 返回的 refId);组织类可空 | 个人类必填否则 595203;档案不存在/已下架 595204 | +| payeeName | string | 否 | 收款方姓名 | **个人类会被档案真名强制覆盖**(手填无效);组织类手填 | + +## 5. 出参(响应) + +### 5.1 staff-candidates 出参 records[] + +| 字段 | 类型 | 说明 | +|------|------|------| +| refId | string(Long) | 人员 ID(司机=driverId,其余=staffId)——登记时填入 payeeRefId | +| name | string | 姓名(档案真名) | +| phone | string | 手机号(**明文**,出纳选人看全号区分同名;落库后的列表/详情仍脱敏) | +| payeeType | string | 回显收款方类型 | +| staffType | string | 人员类型(仅 staff 类有值:`GUIDE`/`GUIDE_ASSISTANT`/`PHOTOGRAPHER`/`LEADER`;DRIVER 为 null)。GUIDE 候选合并导游+助理导游,前端据此字段区分 | +| guideLevel | string | 导游等级(仅 staff 导游类有值:初级/中级/高级/特级;其余为 null) | + +## 6. 枚举 / 数据字典 + +### 6.1 staffType(人员类型,字典 staff_type) + +| 值 | 中文 | +|----|------| +| `GUIDE` | 导游 | +| `GUIDE_ASSISTANT` | 助理导游 | +| `PHOTOGRAPHER` | 摄影师 | +| `LEADER` | 领队 | + +> payeeType=GUIDE 的候选同时含 GUIDE 和 GUIDE_ASSISTANT 两类,前端用 `staffType` 区分展示;payeeType=PHOTOGRAPHER/LEADER 只含对应一类。 + +### 6.2 payeeType 个人类 ↔ 档案源 + +| payeeType | 档案源 | refId 含义 | +|-----------|--------|-----------| +| DRIVER 司机 | fleet 车队 | driverId | +| GUIDE 导游 | resource 服务人员 | staffId | +| PHOTOGRAPHER 摄影 | resource 服务人员 | staffId | +| LEADER 领队 | resource 服务人员 | staffId | + +## 7. 错误码 + +| code | 含义 | 触发场景 | +|------|------|----------| +| 595202 | 收款方账户字段组合不合法 | staff-candidates 传组织类/非法 payeeType、keyword 超 50;编辑个人类手改 payeeName | +| 595203 | 个人类收款方须选择服务人员 | create 个人类未传 payeeRefId | +| 595204 | 服务人员不存在或已下架 | create 个人类 payeeRefId 在档案源不存在、staff 已下架、driver 黑名单/归档/休假/待激活;或档案服务暂不可用(文案为"档案服务暂不可用,请稍后重试") | + +## 8. 示例(3 组) + +### 8.1 典型成功(选司机 → 登记司机收款账户) + +**① 候选** `GET /admin/finance/payee-accounts/staff-candidates?payeeType=DRIVER&keyword=张`: +```json +{ + "code": 200, "success": true, + "data": { + "total": 1, + "records": [ + { "refId": "1823456789012345678", "name": "张三", "phone": "13800138000", + "payeeType": "DRIVER", "staffType": null, "guideLevel": null } + ] + } +} +``` + +**② 登记** `POST /admin/finance/payee-accounts`: +```json +{ + "payeeType": "DRIVER", + "payeeRefId": "1823456789012345678", + "accountType": "WECHAT_QR", + "qrUrl": "https://oss.example.com/qr/zhangsan.png", + "isDefault": 1 +} +``` +**响应**(payeeName 由后端用档案真名"张三"覆盖,无需前端传): +```json +{ "code": 200, "success": true, "data": { "id": "2105..." } } +``` + +### 8.2 边界(导游候选含助理导游,staffType 区分) + +`GET /admin/finance/payee-accounts/staff-candidates?payeeType=GUIDE`: +```json +{ + "code": 200, "success": true, + "data": { + "total": 2, + "records": [ + { "refId": "1811...", "name": "李四", "phone": "13911112222", "payeeType": "GUIDE", "staffType": "GUIDE", "guideLevel": "高级" }, + { "refId": "1822...", "name": "王五", "phone": "13933334444", "payeeType": "GUIDE", "staffType": "GUIDE_ASSISTANT", "guideLevel": "初级" } + ] + } +} +``` + +### 8.3 业务失败(个人类未选服务人员) + +`POST /admin/finance/payee-accounts`: +```json +{ "payeeType": "GUIDE", "accountType": "WECHAT_QR", "qrUrl": "https://..." } +``` +**响应**: +```json +{ "code": 595203, "message": "个人类收款方须选择服务人员", "success": false } +``` + +选了已下架人员: +```json +{ "code": 595204, "message": "服务人员不存在或已下架", "success": false } +``` + +## 9. 业务边界 + +- ✅ 个人类收款方:必须先调 staff-candidates 选人,把返回的 `refId` 作为 `payeeRefId` 提交;`payeeName` 不用传(后端用档案真名覆盖)。 +- ✅ 组织类(车队/导游公司/供应商):维持手填 `payeeName`,`payeeRefId` 可空,不调候选接口。 +- ❌ 不要再手填个人类的 payeeRefId/payeeName——后端强制档案校验+真名覆盖,手填无效或被 595203/595204 拦。 +- ⚠️ 候选接口降级:档案服务故障时返回空 records(非报错),前端下拉显示"暂无可选人员,请稍后重试"即可,不要当成"无此人员"。 + +## 10. 修改前后对比 + +| 行为 | 改前 | 改后 | +|------|------|------| +| 个人类选人方式 | 手填人员 ID + 手填姓名 | staff-candidates 下拉选人,payeeRefId=选中人员 ID | +| 个人类 payeeRefId | 可空 | **必填**(595203) | +| 个人类 payeeName | 手填生效 | **被档案真名覆盖**(手填无效) | +| 档案校验 | 无 | 存在性+在册校验(595204),拦下架/黑名单/休假 | +| 编辑个人类 payeeName | 可手改 | 禁止(595202) | + +## 11. 影响评估 / 回滚 + +- **是否破坏向后兼容**:**是**。个人类 create 原来可不传 payeeRefId,现在必填;原来手填 payeeName 生效,现在被档案覆盖。前端个人类表单必须改为「先选人」流程。 +- **前端是否必须同步上线**:是。个人类收款账户表单需加「选择服务人员」下拉(数据源 staff-candidates),并移除个人类的手填姓名/手填 ID 输入。 +- **影响已有数据**:测试库 fin_payee_account 个人类存量少,存量数据不受影响(仅新增/编辑走新校验)。 +- **回滚方式**:revert PR #8692(finance)+ PR #8688(fleet)。 + +## 12. 注意事项 + +- **选人下拉数据分端**:司机候选来自 fleet(含 season/driverStatus 过滤),导游/摄影/领队来自 resource staff。前端只调一个 staff-candidates 接口,后端按 payeeType 分流,无需关心来源。 +- **staffType/guideLevel 仅 staff 类有**:DRIVER 候选这两字段为 null,前端展示时判空。 +- **手机号明文仅选人下拉里**:落库后的收款账户列表/详情 phone 仍按 PII 口径脱敏,不要在别处用候选接口的明文 phone 当展示数据源。 + +## 13. 关联 / 联系人 + +### 13.1 链接 + +- **Issue**: [#8679](https://git.1814.love/wx/HL/issues/8679) +- **PR(finance)**: [#8692](https://git.1814.love/wx/HL/pulls/8692) · merge [7cb5aa9e6d](https://git.1814.love/wx/HL/commit/7cb5aa9e6d717efe34ce099b9e11eabdc9811dbf) +- **PR(fleet 司机候选数据源)**: [#8688](https://git.1814.love/wx/HL/pulls/8688) · merge [b4edefd08e](https://git.1814.love/wx/HL/commit/b4edefd08e5a439db6e7a6e2d245a5d0fd1cc067) + +### 13.2 联系人 + +- **后端负责人**: @yst +- **前端对接(管理后台)**: 待认领