diff --git a/changelogs-v2/2026-08/26_6391_供应商法人证件号与身份证正反面-修改接口-管理后台.md b/changelogs-v2/2026-08/26_6391_供应商法人证件号与身份证正反面-修改接口-管理后台.md new file mode 100644 index 00000000..74044ebf --- /dev/null +++ b/changelogs-v2/2026-08/26_6391_供应商法人证件号与身份证正反面-修改接口-管理后台.md @@ -0,0 +1,369 @@ +--- +schema: "hl-changelog/v2" +ticket: "6391" +title: "供应商法人证件号与身份证正反面" +consumer: "admin" +author: "lc(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "PR #6401 已合并 dev-v3 并部署 TEST;供应商创建、更新、提交新增法人身份证号及正反面永久地址,详情仅返回脱敏证件号。旧客户端省略三字段时保持兼容,前端待接入输入与双面上传。" +updated_at: "2026-08-26" +base: "dev-v3" +--- + +# 🔧 供应商法人证件号与身份证正反面 + +供应商“基本信息-法定代表人”新增身份证号、人像面和国徽面三个字段。身份证图片继续使用既有文件上传能力,本次接口只接收上传完成后的永久 HTTPS 地址,不新增上传或 OCR 接口。 + +## 变更接口 + +| 方法 | 路径 | 权限 | 变化 | +|---|---|---|---| +| POST | `/admin/supplier/items/add` | `supplier:create` | 创建草稿可保存三个法人证件字段 | +| PUT | `/admin/supplier/items/{supplierId}/update` | `supplier:update` | 增量更新三个法人证件字段 | +| POST | `/admin/supplier/items/{supplierId}/submit` | `supplier:update`、`supplier:approval:submit` | 完整注册表单可提交三个法人证件字段 | +| GET | `/admin/supplier/items/{supplierId}/basic-info/view` | `supplier:view` | 返回脱敏证件号及身份证正反面地址 | + +## 通用字段与校验 + +| 字段 | 类型 | 必填 | 规则 | +|---|---|---|---| +| `legalRepresentativeIdNo` | string | 条件必填 | 18 位中国大陆居民身份证号;校验长度、出生日期、顺序码及校验位;末位小写 `x` 会规范为大写 `X` | +| `legalRepresentativeIdCardFrontUrl` | string | 条件必填 | 身份证人像面永久地址,最长 1000 字符;必须为公网 HTTPS 地址,且不能含账号密码、查询串或片段 | +| `legalRepresentativeIdCardBackUrl` | string | 条件必填 | 身份证国徽面永久地址,规则同人像面 | + +三个字段必须“全部省略”或“同时提供”: + +- 全部省略:兼容旧客户端和没有法人证件数据的存量供应商。 +- 任意一个有值:三个字段必须同时有值,不能只保存证件号或单面图片。 +- 法定代表人可能对应多个供应商,证件号不作为供应商之间的唯一键。 +- 写接口的成功响应不回传证件号;需要展示时调用详情接口。 +- 统一响应可能以 HTTP 200 承载业务失败,必须同时判断 `code`、`success` 和 `data`。 + +## 1. 创建供应商草稿 + +### 使用场景 + +在新建供应商基本信息时,同时保存法定代表人身份证号及正反面扫描件地址。 + +### 请求 + +```http +POST /admin/supplier/items/add +Authorization: Bearer <管理员令牌> +Content-Type: application/json +``` + +本次新增的三个字段遵循上方通用规则;创建草稿的既有最低必填字段仍为 `fullName`、`taxNo`、`mainCooperation`。 + +典型成功请求: + +```json +{ + "fullName": "法人证件联调示例供应商", + "taxNo": "L6391EXAMPLE001", + "legalRepresentative": "示例法人", + "legalRepresentativeIdNo": "11010519491231002x", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front.jpg", + "legalRepresentativeIdCardBackUrl": "https://files.example.com/supplier/id/back.jpg", + "mainCooperation": "旅游资源供应" +} +``` + +典型成功响应: + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "1900000000000000001", + "supplierNo": null, + "status": "DRAFT", + "onboardingStage": "PROFILE_DRAFT", + "initialAccounts": [], + "updateTime": "2026-08-26 11:40:00" + } +} +``` + +兼容边界:旧客户端可完全省略三个新字段,其余请求保持原样。 + +异常请求(仅传人像面): + +```json +{ + "fullName": "法人证件联调示例供应商", + "taxNo": "L6391EXAMPLE001", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front.jpg", + "mainCooperation": "旅游资源供应" +} +``` + +```json +{ + "code": 400, + "message": "法定代表人证件号、人像面和国徽面必须同时提供", + "success": false, + "data": null +} +``` + +失败不会创建供应商草稿。 + +## 2. 更新供应商 + +### 使用场景 + +在供应商基本信息编辑页补录或替换完整的法人证件三字段。 + +### 请求 + +```http +PUT /admin/supplier/items/1900000000000000001/update +Authorization: Bearer <管理员令牌> +Content-Type: application/json +``` + +`changeReason` 和 `expectedUpdateTime` 沿用原接口必填约束;三个法人证件字段作为一组增量字段处理。典型成功请求: + +```json +{ + "legalRepresentative": "示例法人", + "legalRepresentativeIdNo": "11010519491231002X", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front-v2.jpg", + "legalRepresentativeIdCardBackUrl": "https://files.example.com/supplier/id/back-v2.jpg", + "changeReason": "补录法人身份证扫描件", + "expectedUpdateTime": "2026-08-26 11:40:00" +} +``` + +典型成功响应: + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "1900000000000000001", + "supplierNo": null, + "status": "DRAFT", + "onboardingStage": "PROFILE_DRAFT", + "initialAccounts": [], + "updateTime": "2026-08-26 11:42:00" + } +} +``` + +兼容边界:三个新字段全部省略时,不修改现有法人证件数据。若请求中出现任一新字段,服务端会与当前值合并后再次检查三字段是否完整。 + +异常请求(身份证校验位错误): + +```json +{ + "legalRepresentativeIdNo": "110105194912310021", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front-v2.jpg", + "legalRepresentativeIdCardBackUrl": "https://files.example.com/supplier/id/back-v2.jpg", + "changeReason": "补录法人身份证扫描件", + "expectedUpdateTime": "2026-08-26 11:40:00" +} +``` + +```json +{ + "code": 400, + "message": "法定代表人证件号的日期或校验位不合法", + "success": false, + "data": null +} +``` + +失败时主体版本、法人证件数据和变更记录均保持原状。 + +## 3. 提交供应商注册审批 + +### 使用场景 + +提交草稿的完整注册表单时,将法人证件三字段一并纳入审批内容。 + +### 请求 + +```http +POST /admin/supplier/items/1900000000000000001/submit +Authorization: Bearer <管理员令牌> +Content-Type: application/json +``` + +本接口继续要求完整注册表单和当前 `expectedUpdateTime`。典型成功请求: + +```json +{ + "fullName": "法人证件联调示例供应商", + "taxNo": "L6391EXAMPLE001", + "legalRepresentative": "示例法人", + "legalRepresentativeIdNo": "11010519491231002X", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front.jpg", + "legalRepresentativeIdCardBackUrl": "https://files.example.com/supplier/id/back.jpg", + "mainCooperation": "旅游资源供应", + "expectedUpdateTime": "2026-08-26 11:42:00" +} +``` + +典型成功响应: + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "approvalLogId": "1900000000000000101", + "requestNo": "SUP-REQ-20260826-0001", + "provider": "LOCAL_AUTO", + "approvalStatus": "APPROVED", + "spNo": null, + "spStatus": null, + "syncStatus": "APPLIED", + "submittedAt": "2026-08-26 11:43:00", + "finishedAt": "2026-08-26 11:43:00" + } +} +``` + +兼容边界:没有法人证件数据的旧草稿仍可按旧请求提交;若提交法人证件,则三字段必须完整。 + +异常请求(图片地址带查询串): + +```json +{ + "fullName": "法人证件联调示例供应商", + "taxNo": "L6391EXAMPLE001", + "legalRepresentativeIdNo": "11010519491231002X", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front.jpg?token=temporary", + "legalRepresentativeIdCardBackUrl": "https://files.example.com/supplier/id/back.jpg", + "mainCooperation": "旅游资源供应", + "expectedUpdateTime": "2026-08-26 11:42:00" +} +``` + +```json +{ + "code": 400, + "message": "法人证件人像面地址不在允许范围", + "success": false, + "data": null +} +``` + +失败时不会创建审批或改变供应商状态。 + +## 4. 查询供应商基本信息 + +### 使用场景 + +编辑页回显法人证件信息。证件号只返回掩码,不能用于恢复原文或再次提交;图片地址可用于有权限页面的预览。 + +### 请求 + +```http +GET /admin/supplier/items/1900000000000000001/basic-info/view +Authorization: Bearer <管理员令牌> +``` + +无请求体。 + +典型成功响应: + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "1900000000000000001", + "supplierNo": null, + "fullName": "法人证件联调示例供应商", + "shortName": null, + "tax_no": "L639****E001", + "legalRepresentative": "示例法人", + "legalRepresentativeIdNoMask": "110105********002X", + "legalRepresentativeIdCardFrontUrl": "https://files.example.com/supplier/id/front.jpg", + "legalRepresentativeIdCardBackUrl": "https://files.example.com/supplier/id/back.jpg", + "contactPhoneMask": null, + "establishDate": null, + "registeredCapital": null, + "businessScope": null, + "staffScale": null, + "mainCooperation": "旅游资源供应", + "status": "DRAFT", + "creditLevel": "B", + "totalScore": null, + "types": [], + "contacts": [], + "qualifications": [], + "updateTime": "2026-08-26 11:42:00" + } +} +``` + +兼容边界:存量供应商没有法人证件数据时,三个响应字段均为 `null`。响应中不存在 `legalRepresentativeIdNo` 明文字段。 + +未认证示例: + +```json +{ + "code": 401, + "message": "未认证或登录已失效", + "success": false, + "data": null +} +``` + +## 错误与前端处理 + +| 响应码 | 触发条件 | 前端处理 | +|---:|---|---| +| `400` | 身份证不是 18 位、出生日期/顺序码/校验位错误、三字段不完整、图片地址不符合规则 | 保留表单并定位到法人证件区域;不要自动重试 | +| `401` | 未登录或 Gateway 认证失效 | 进入统一重新登录流程 | +| `403` | 角色、功能权限或数据范围不足 | 隐藏无权操作并展示统一无权限提示 | +| `395014` | `expectedUpdateTime` 已过期 | 重新读取详情,提示用户确认后再提交 | + +本次不新增业务错误码;参数失败继续使用统一 `400`。 + +## 前端改造清单 + +- 在“新建/编辑供应商-基本信息-法定代表人”后增加身份证号输入框、人像面上传和国徽面上传。 +- 上传完成后提交永久 HTTPS 地址;不要提交临时签名 URL、查询参数 URL、Base64 或文件二进制。 +- 前端可做 18 位长度和末位 `X/x` 预校验,但最终以服务端日期及校验位结果为准。 +- 三字段联动必填;旧数据三个字段均为空时允许继续按原流程操作。 +- 详情只展示 `legalRepresentativeIdNoMask`;不得寻找或缓存身份证号明文。 +- 写成功后如需回显,重新调用详情接口,不要从写响应读取新字段。 + +## 验证证据 + +- 自动化:最新 `dev-v3` 的 Resource 全量测试 2111 项通过、0 失败、0 错误,38 项既有条件跳过;法人证件聚焦测试 89 项通过。 +- TEST:Deploy Panel 任务 `118fcff1` 将目标提交 `de615b49e3ecef4be13bd6bc78b3100d08ef0bd2` 部署到双实例;该提交包含 #6391 合并提交 `b909c8f7dfd73712886a33b574c72030dde89d4f`,服务与 Nacos 健康检查通过。 +- 真实 Gateway:7 组场景通过,覆盖合法创建、错误校验位零写入、详情脱敏与图片回显、未认证拒绝、非法更新零写入、旧客户端省略字段兼容和迁移状态。 +- 清理:本轮验收草稿已通过业务删除接口软删除并保留正常删除审计,不遗留可用测试供应商。 + +## 撤回 + +1. 从最新 `dev-v3` 创建回退分支,revert #6401 合并提交并经独立 PR 合入。 +2. 重新部署 `hl-resource-service`;新增的可空数据结构保留,不执行破坏性删除。 +3. 旧客户端、存量供应商和已保存的安全数据保持兼容;无需恢复配置、Redis 或 MQ。 +4. 经 Gateway 重跑旧请求、合法/非法证件号、三字段完整性、详情脱敏和失败零写入检查。 + +## 关联 / 联系人 + +- **Issue**: [#6391](https://git.1814.love:8443/wx/HL/issues/6391) +- **PR**: [#6401](https://git.1814.love:8443/wx/HL/pulls/6401) +- **合并提交**: [b909c8f7d](https://git.1814.love:8443/wx/HL/commit/b909c8f7dfd73712886a33b574c72030dde89d4f) +- **后端负责人**: @lc