From 89733533567f8ef0e882d97c252dce3f01dde833 Mon Sep 17 00:00:00 2001 From: lc Date: Fri, 4 Sep 2026 20:09:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=A4=E4=BB=98=E4=BE=9B=E5=BA=94=E5=95=86?= =?UTF-8?q?=E4=BF=A1=E7=94=A8=E7=AD=89=E7=BA=A7=E4=B8=8E=E5=85=AC=E5=8F=B8?= =?UTF-8?q?=E8=B5=84=E6=96=99=E5=AD=97=E6=AE=B5=E5=A5=91=E7=BA=A6=EF=BC=88?= =?UTF-8?q?#7090=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...•†信用等级与公司资料字段-修改接口-管理后台.md | 506 ++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 changelogs-v2/2026-09/04_7090_供应商信用等级与公司资料字段-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/04_7090_供应商信用等级与公司资料字段-修改接口-管理后台.md b/changelogs-v2/2026-09/04_7090_供应商信用等级与公司资料字段-修改接口-管理后台.md new file mode 100644 index 00000000..13afc6c6 --- /dev/null +++ b/changelogs-v2/2026-09/04_7090_供应商信用等级与公司资料字段-修改接口-管理后台.md @@ -0,0 +1,506 @@ +--- +schema: "hl-changelog/v2" +ticket: "7090" +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: "后端已部署并通过 TEST;前端需在供应商新建和编辑表单接入信用等级、公开电子邮箱、公司类型和办公地址。" +updated_at: "2026-09-04" +base: "dev-v3" +--- + +# 供应商模块:信用等级与公司资料字段 + +供应商新建、编辑和注册提交支持 `creditLevel`、`publicEmail`、`companyType`、`officeAddress`,详情新增后三个字段回显。公司类型使用系统字典 `supplier_company_type`。 + +## ⚠️ 关键变化 + +- 新建省略 `creditLevel` 时后端默认值由 B 改为 A;可选值仍与供应商主列表筛选一致,为 A/B/C/D。 +- 只有 `SUPER_ADMIN` 可以显式提交 `creditLevel`。其他角色可以展示详情值,但请求体必须省略该字段。 + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|---|---|---|---|---| +| 1 | 查询供应商基本信息 | GET | `/admin/supplier/items/{supplierId}/basic-info/view` | 响应新增字段 | 回显公开邮箱、公司类型和办公地址 | +| 2 | 查询供应商公司类型字典 | GET | `/admin/dict/data/supplier_company_type` | 新增字典数据 | 返回固定的两个生效选项 | +| 3 | 新建供应商草稿 | POST | `/admin/supplier/items/add` | 请求新增字段 | 支持信用等级和三个可选公司资料字段 | +| 4 | 修改供应商资料 | PUT | `/admin/supplier/items/{supplierId}/update` | 请求新增字段 | 支持增量维护并保留省略字段 | +| 5 | 提交供应商注册 | POST | `/admin/supplier/items/{supplierId}/submit` | 请求新增字段 | 完整表单可携带新增字段进入审批 | + +## 三、接口详情 + +### 1. 查询供应商基本信息 `GET /admin/supplier/items/{supplierId}/basic-info/view` + +**VO**: `SupplierBasicInfoRespVO` + +#### 使用场景 + +打开供应商详情或编辑页时读取当前字段值和并发版本。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID | 供应商 ID | + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.creditLevel` | String | 信用等级 A/B/C/D | +| `data.publicEmail` | String/null | 公开电子邮箱 | +| `data.companyType` | String/null | `supplier_company_type` 的 `dictValue` | +| `data.officeAddress` | String/null | 办公地址 | +| `data.updateTime` | String | 编辑请求使用的最新并发版本 | + +#### 请求示例 + +```http +GET /admin/supplier/items/2095000000000000001/basic-info/view +Authorization: Bearer +``` + +无请求体。 + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "2095000000000000001", + "creditLevel": "A", + "publicEmail": "service@example.com", + "companyType": "1", + "officeAddress": "呼和浩特市示例办公地址", + "updateTime": "2026-09-04 20:04:19" + } +} +``` + +#### 空数据 / 降级响应 + +存量数据或新建时未填写三个可选资料字段,分别返回 `null`;接口不使用默认文案代替空值。 + +#### 错误响应 + +```json +{"code":395001,"message":"供应商不存在","data":null,"success":false} +``` + +#### 业务边界 + +- 沿用供应商详情查看权限;业务失败可能仍使用 HTTP 200,必须检查响应体。 +- `companyType` 返回字典值,不返回中文标签;前端用字典接口翻译。 +- `creditLevel` 可以展示给有详情权限的用户,是否可编辑按当前角色控制。 + +### 2. 查询供应商公司类型字典 `GET /admin/dict/data/supplier_company_type` + +**VO**: `Result>` + +#### 使用场景 + +供应商新建或编辑页加载公司类型下拉选项。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplier_company_type` | Path | String | 是 | 固定字典类型 | 不要改成中文名称 | + +#### 出参 `Result>` + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data[].dictValue` | String | 提交给供应商接口的值 | +| `data[].dictLabel` | String | 下拉展示文案 | +| `data[].sortOrder` | Number | 升序展示顺序 | +| `data[].status` | String | 当前均为 `ACTIVE` | + +#### 请求示例 + +```http +GET /admin/dict/data/supplier_company_type +Authorization: Bearer +``` + +无请求体。 + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": [ + {"dictValue":"1","dictLabel":"有限责任公司(自然人投资或控股)","sortOrder":10,"status":"ACTIVE"}, + {"dictValue":"2","dictLabel":"国企控股","sortOrder":20,"status":"ACTIVE"} + ] +} +``` + +#### 空数据 / 降级响应 + +后端已初始化两个选项;若请求失败或返回空数组,表单不要用本地硬编码选项替代。 + +#### 错误响应 + +```json +{"code":401,"message":"未登录或登录已过期","data":null,"success":false} +``` + +#### 业务边界 + +- 下拉框展示 `dictLabel`,请求只提交对应的 `dictValue`。 +- 当前合法值严格为 `1`、`2`;不要提交中文标签。 +- 字典接口需要管理端真实登录态。 + +### 3. 新建供应商草稿 `POST /admin/supplier/items/add` + +**VO**: `SupplierDraftSaveReqVO → SupplierWriteRespVO` + +#### 使用场景 + +管理端供应商新建表单保存完整草稿。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `creditLevel` | Body | String | 否 | A/B/C/D;仅 `SUPER_ADMIN` 可显式提交 | 省略时后端默认 A | +| `publicEmail` | Body | String | 否 | 邮箱格式,最长 100 | 公开电子邮箱 | +| `companyType` | Body | String | 否 | 生效的 `supplier_company_type` 值 | 公司类型 | +| `officeAddress` | Body | String | 否 | 最长 500 | 录入方式与 `address` 一致 | +| `fullName`、`taxNo` | Body | String | 是 | 沿用现有主体校验 | 供应商名称与主体证件号 | +| `types` | Body | Array | 是 | 至少 1 项 | 供应商类型完整集合 | +| 法人资料与 `contactPhone` | Body | String | 是 | 沿用现有格式校验 | 法人姓名、身份证三字段和联系电话 | +| `establishDate`、`address` | Body | String | 是 | 日期不得晚于当天;地址非空 | 成立日期和注册地址 | +| `balance`、`paymentType`、`mainCooperation` | Body | 混合 | 是 | 沿用现有规则 | 结算与合作资料 | +| `licenseImageUrl` | Body | String | 是 | 非空 | 营业执照影像 | +| `contacts`、`initialAccounts` | Body | Array | 是 | 至少一名联系人;当前一个初始账户 | 聚合子项 | + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.supplierId` | String | 新供应商 ID | +| `data.status` | String | 新建成功为 `DRAFT` | +| `data.updateTime` | String | 后续编辑使用的并发版本 | + +#### 请求示例 + +```json +{ + "fullName": "示例供应商有限公司", + "taxNo": "91350211M000100Y46", + "types": [{"typeCode":"HOTEL"}], + "legalRepresentative": "张三", + "legalRepresentativeIdNo": "11010519491231002X", + "legalRepresentativeIdCardFrontUrl": "https://example.com/id-front.jpg", + "legalRepresentativeIdCardBackUrl": "https://example.com/id-back.jpg", + "contactPhone": "13800138000", + "establishDate": "2020-01-02", + "address": "呼和浩特市示例注册地址", + "creditLevel": "A", + "publicEmail": "service@example.com", + "companyType": "1", + "officeAddress": "呼和浩特市示例办公地址", + "balance": 0, + "paymentType": "1", + "mainCooperation": "酒店资源合作", + "licenseImageUrl": "https://example.com/license.jpg", + "contacts": [{"contactName":"李四","contactPhone":"13800138001","contactRole":"contentBus","isPrimary":true}], + "initialAccounts": [{"accountType":"CORPORATE","bankName":"示例银行","accountNo":"6222000012345678"}] +} +``` + +#### 响应示例 + +```json +{ + "code":200,"message":"成功","success":true, + "data":{"supplierId":"2095000000000000001","status":"DRAFT","updateTime":"2026-09-04 20:04:19"} +} +``` + +#### 空数据 / 降级响应 + +省略 `publicEmail`、`companyType`、`officeAddress` 时保存为未填写,详情返回 `null`;无降级成功响应。 + +#### 错误响应 + +```json +{"code":395002,"message":"无权执行该供应商写操作","data":null,"success":false} +``` + +#### 业务边界 + +- `creditLevel` 省略时后端固定默认 A;不要再按旧行为假设默认 B。 +- 只有 `SUPER_ADMIN` 可显式提交 `creditLevel`;其他可创建供应商的角色必须省略该字段。 +- 三个公司资料字段均非必填;显式 `companyType` 必须命中当前生效字典。 +- 非法邮箱、信用等级、公司类型或超过 500 字的办公地址返回业务码 `400`,失败不创建草稿。 + +### 4. 修改供应商资料 `PUT /admin/supplier/items/{supplierId}/update` + +**VO**: `SupplierUpdateReqVO → SupplierWriteRespVO` + +#### 使用场景 + +编辑页按详情中的最新版本增量保存供应商资料。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID | 目标供应商 | +| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 取详情最新 `updateTime` | +| `creditLevel` | Body | String | 否 | A/B/C/D;仅 `SUPER_ADMIN` 可显式提交 | 省略保留现值 | +| `publicEmail` | Body | String | 否 | 邮箱格式,最长 100 | 省略保留现值 | +| `companyType` | Body | String | 否 | 生效的字典值 1/2 | 省略保留现值 | +| `officeAddress` | Body | String | 否 | 最长 500 | 省略保留现值 | + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.supplierId` | String | 供应商 ID | +| `data.status` | String | 保存后的状态 | +| `data.updateTime` | String | 保存后的新并发版本 | + +#### 请求示例 + +```json +{ + "creditLevel": "B", + "publicEmail": "service@example.com", + "companyType": "2", + "officeAddress": "呼和浩特市示例办公地址", + "expectedUpdateTime": "2026-09-04 20:04:19" +} +``` + +#### 响应示例 + +```json +{ + "code":200,"message":"成功","success":true, + "data":{"supplierId":"2095000000000000001","status":"DRAFT","updateTime":"2026-09-04 20:05:01"} +} +``` + +#### 空数据 / 降级响应 + +省略新增字段表示保留现值;接口没有空数据成功或降级成功。 + +#### 错误响应 + +```json +{"code":395014,"message":"数据已被他人修改,请刷新后重试","data":null,"success":false} +``` + +#### 业务边界 + +- 保存前先读取详情并使用最新 `updateTime`;过期版本不写入任何字段。 +- 只有 `SUPER_ADMIN` 可显式提交 `creditLevel`。其他角色即使值未改变也必须省略,否则返回 `395002`。 +- 省略 `creditLevel` 不会重置为 A;A 只用于新建时的缺省值。 +- `companyType` 必须提交字典值;邮箱、公司类型和办公地址的失败校验均不产生部分更新。 + +### 5. 提交供应商注册 `POST /admin/supplier/items/{supplierId}/submit` + +**VO**: `SupplierSubmitReqVO → SupplierApprovalCommandRespVO` + +#### 使用场景 + +供应商完整注册表单保存并提交审批。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID | 草稿供应商 | +| `expectedUpdateTime` | Body | String | 是 | 最新并发版本 | 防止覆盖并发编辑 | +| `creditLevel` | Body | String | 否 | A/B/C/D;仅 `SUPER_ADMIN` 可显式提交 | 省略保留草稿值 | +| `publicEmail` | Body | String | 否 | 邮箱格式,最长 100 | 省略保留草稿值 | +| `companyType` | Body | String | 否 | 生效的字典值 1/2 | 省略保留草稿值 | +| `officeAddress` | Body | String | 否 | 最长 500 | 省略保留草稿值 | +| 完整注册资料 | Body | 混合 | 是 | 沿用现有提交契约 | 主体、类型、联系人、账户及营业执照等 | + +#### 出参 `Result` + +| 字段 | 类型 | 说明 | +|---|---|---| +| `data.approvalLogId` | String | 审批记录 ID | +| `data.provider` | String | 审批提供方 | +| `data.approvalStatus` | String | 审批状态 | +| `data.submittedAt` | String | 提交时间 | + +#### 请求示例 + +```json +{ + "fullName": "示例供应商有限公司", + "taxNo": "91350211M000100Y46", + "types": [{"typeCode":"HOTEL"}], + "legalRepresentative": "张三", + "legalRepresentativeIdNo": "11010519491231002X", + "legalRepresentativeIdCardFrontUrl": "https://example.com/id-front.jpg", + "legalRepresentativeIdCardBackUrl": "https://example.com/id-back.jpg", + "contactPhone": "13800138000", + "establishDate": "2020-01-02", + "address": "呼和浩特市示例注册地址", + "creditLevel": "A", + "publicEmail": "service@example.com", + "companyType": "1", + "officeAddress": "呼和浩特市示例办公地址", + "balance": 0, + "paymentType": "1", + "mainCooperation": "酒店资源合作", + "licenseImageUrl": "https://example.com/license.jpg", + "contacts": [{"contactName":"李四","contactPhone":"13800138001","contactRole":"contentBus","isPrimary":true}], + "initialAccounts": [{"accountType":"CORPORATE","bankName":"示例银行","accountNo":"6222000012345678"}], + "expectedUpdateTime": "2026-09-04 20:05:01" +} +``` + +#### 响应示例 + +```json +{ + "code":200,"message":"成功","success":true, + "data":{"approvalLogId":"2095000000000000010","provider":"WECOM","approvalStatus":"PENDING","submittedAt":"2026-09-04 20:05:02"} +} +``` + +#### 空数据 / 降级响应 + +写接口成功时返回审批受理结果;失败时 `data` 为 `null`,不会以空对象表示成功。 + +#### 错误响应 + +```json +{"code":395002,"message":"无权执行该供应商写操作","data":null,"success":false} +``` + +#### 业务边界 + +- 新增可选字段省略时沿用既有“保留草稿值”语义,不会清空已保存资料。 +- 显式 `creditLevel` 仍只允许 `SUPER_ADMIN`;其他提交角色必须省略该字段。 +- 公司类型按提交时生效字典校验;校验失败不会进入审批。 +- 审批、幂等、重复主体确认和状态规则保持不变。 + +## 四、契约约束与正确调用方式(接口类必写) + +| 场景 | 正确调用 | +|---|---| +| 新建页面 | 从主列表相同选项展示 A/B/C/D;初始选中 A | +| 非超级管理员 | 可展示信用等级,但新建、编辑、提交请求均省略 `creditLevel` | +| 公司类型 | 调字典接口,用 `dictLabel` 展示、用 `dictValue` 提交 | +| 编辑保存 | 携带详情最新 `updateTime`;只提交实际允许修改的字段 | +| 注册提交 | 三个公司资料字段省略时保留草稿值,不需重复拼接空值 | + +## 五、数据库行为 + +| 前端提交 | 外部可观察结果 | +|---|---| +| 新建省略 `creditLevel` | 详情返回 `creditLevel: "A"` | +| 编辑或提交省略 `creditLevel` | 保留已有等级 | +| 新建省略三个公司资料字段 | 详情对应字段返回 `null` | +| 填写三个公司资料字段 | 保存成功后详情原值回显 | +| 校验或权限失败 | 不产生部分字段写入 | + +## 六、边界行为 + +- 业务失败可能仍为 HTTP 200,必须同时检查 `code`、`success` 和 `message`。 +- `creditLevel` 只接受大写 A/B/C/D;非法值返回业务码 `400`。 +- `publicEmail` 最长 100,`officeAddress` 最长 500;超限或邮箱格式非法返回业务码 `400`。 +- `companyType` 只接受当前生效字典值;字典不可用或值失效时失败关闭。 +- 存量供应商三个新增资料字段没有自动推断或回填,详情可返回 `null`。 + +## 六.5、枚举 / 数据字典 + +### creditLevel + +**所属字段**: `SupplierDraftSaveReqVO.creditLevel / SupplierUpdateReqVO.creditLevel / SupplierBasicInfoRespVO.creditLevel` | **类型**: `String` + +| 值 | 中文 | 说明 | +|---|---|---| +| `A` | A 级 | 新建省略时的默认值 | +| `B` | B 级 | 与主列表筛选共用 | +| `C` | C 级 | 与主列表筛选共用 | +| `D` | D 级 | 与主列表筛选共用 | + +### companyType(supplier_company_type) + +**所属字段**: `SupplierDraftSaveReqVO.companyType / SupplierUpdateReqVO.companyType / SupplierBasicInfoRespVO.companyType` | **类型**: `String` + +| 值 | 中文 | 说明 | +|---|---|---| +| `1` | 有限责任公司(自然人投资或控股) | 生效字典值 | +| `2` | 国企控股 | 生效字典值 | + +## 六.6、修改前后对比 + +### 字段级对比 + +| 字段 | 改前 | 改后 | +|---|---|---| +| `creditLevel` 请求 | 新建、编辑不能维护 | 新建、编辑、提交可选;仅 `SUPER_ADMIN` 可显式提交 | +| `publicEmail` | 无请求或详情字段 | 可选保存并在详情回显 | +| `companyType` | 无请求或详情字段 | 可选保存并按系统字典回显 | +| `officeAddress` | 无请求或详情字段 | 可选保存并在详情回显 | + +### 行为级对比 + +| 行为 | 改前 | 改后 | +|---|---|---| +| 新建省略信用等级 | 默认 B | 默认 A | +| 编辑省略新增字段 | 无对应字段 | 保留已有值 | +| 公司类型选项 | 无集中契约 | 从 `supplier_company_type` 动态读取 | + +## 六.7、影响评估 + +- **是否破坏向后兼容**: 否。旧客户端省略新增字段仍可调用;新建信用缺省业务值由 B 调整为 A。 +- **前端是否必须同步上线**: 是。新建和编辑页需展示四个字段并接入公司类型字典。 +- **前端 workaround 清理点**: 不要硬编码公司类型;不要再把新建缺省信用等级当作 B;非 `SUPER_ADMIN` 不要序列化 `creditLevel`。 + +## 七、不影响范围 + +- **仅影响**: 管理后台供应商新建、编辑、详情和注册提交表单。 +- **零影响**: 供应商主列表信用等级筛选选项、生命周期状态机、审批流程、账户流程和其他前端入口。 + +## 八、测试环境已验证 + +- 公司类型字典真实返回且仅返回两个约定的生效选项。 +- 真实新建、编辑和详情调用已逐项保存并回读 A/B/C/D,以及公开邮箱、公司类型 1/2、办公地址。 +- 真实新建省略四个字段后,信用等级回读为 A,三个可选公司资料字段回读为 `null`。 +- 编辑省略 `creditLevel` 后保持既有等级;两条验收草稿均已通过业务删除接口清理。 +- 注册提交沿用同一请求字段、权限和保存逻辑,已通过合并提交的后端契约测试;TEST 未创建外部审批单。 + +## 十、相关文档 + +- 关联 Issue: [wx/HL#7090](https://git.1814.love:8443/wx/HL/issues/7090) +- 关联 PR: [wx/HL#7107](https://git.1814.love:8443/wx/HL/pulls/7107) + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#7090](https://git.1814.love:8443/wx/HL/issues/7090) +- **PR**: [#7107](https://git.1814.love:8443/wx/HL/pulls/7107) +- **Merge commit**: [c1102d62ecb81c24596fba91bba6e704da6e85ff](https://git.1814.love:8443/wx/HL/commit/c1102d62ecb81c24596fba91bba6e704da6e85ff) + +### 联系人 + +- **后端负责人**: @lc