修改原因:#7090 前端已交付(commit 32a1a289,sync-log 已记 done)但 frontmatter 仍为 pending, 发布门禁前端核验状态与真实交付不符。 修改内容:frontend_status=verified、frontend_owner=mmg、frontend_ref=32a1a289、verified_at=2026-09-04; target_release 与 status_note 保持原值,正文未动。 实际验证:git diff 逐字段核对仅改 frontmatter 5 字段。
19 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 7090 | 供应商信用等级与公司资料字段 | admin | lc(GIT) | 修改接口 | deployed | verified | verified | mmg | 32a1a289 | 2026-09-04 | 后端已部署并通过 TEST;前端需在供应商新建和编辑表单接入信用等级、公开电子邮箱、公司类型和办公地址。 | 2026-09-04 | 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<SupplierBasicInfoRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
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 | 编辑请求使用的最新并发版本 |
请求示例
GET /admin/supplier/items/2095000000000000001/basic-info/view
Authorization: Bearer <token>
无请求体。
响应示例
{
"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;接口不使用默认文案代替空值。
错误响应
{"code":395001,"message":"供应商不存在","data":null,"success":false}
业务边界
- 沿用供应商详情查看权限;业务失败可能仍使用 HTTP 200,必须检查响应体。
companyType返回字典值,不返回中文标签;前端用字典接口翻译。creditLevel可以展示给有详情权限的用户,是否可编辑按当前角色控制。
2. 查询供应商公司类型字典 GET /admin/dict/data/supplier_company_type
VO: Result<List<SysDictDataRespVO>>
使用场景
供应商新建或编辑页加载公司类型下拉选项。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
supplier_company_type |
Path | String | 是 | 固定字典类型 | 不要改成中文名称 |
出参 Result<List<SysDictDataRespVO>>
| 字段 | 类型 | 说明 |
|---|---|---|
data[].dictValue |
String | 提交给供应商接口的值 |
data[].dictLabel |
String | 下拉展示文案 |
data[].sortOrder |
Number | 升序展示顺序 |
data[].status |
String | 当前均为 ACTIVE |
请求示例
GET /admin/dict/data/supplier_company_type
Authorization: Bearer <token>
无请求体。
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": [
{"dictValue":"1","dictLabel":"有限责任公司(自然人投资或控股)","sortOrder":10,"status":"ACTIVE"},
{"dictValue":"2","dictLabel":"国企控股","sortOrder":20,"status":"ACTIVE"}
]
}
空数据 / 降级响应
后端已初始化两个选项;若请求失败或返回空数组,表单不要用本地硬编码选项替代。
错误响应
{"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<SupplierWriteRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
data.supplierId |
String | 新供应商 ID |
data.status |
String | 新建成功为 DRAFT |
data.updateTime |
String | 后续编辑使用的并发版本 |
请求示例
{
"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"}]
}
响应示例
{
"code":200,"message":"成功","success":true,
"data":{"supplierId":"2095000000000000001","status":"DRAFT","updateTime":"2026-09-04 20:04:19"}
}
空数据 / 降级响应
省略 publicEmail、companyType、officeAddress 时保存为未填写,详情返回 null;无降级成功响应。
错误响应
{"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<SupplierWriteRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
data.supplierId |
String | 供应商 ID |
data.status |
String | 保存后的状态 |
data.updateTime |
String | 保存后的新并发版本 |
请求示例
{
"creditLevel": "B",
"publicEmail": "service@example.com",
"companyType": "2",
"officeAddress": "呼和浩特市示例办公地址",
"expectedUpdateTime": "2026-09-04 20:04:19"
}
响应示例
{
"code":200,"message":"成功","success":true,
"data":{"supplierId":"2095000000000000001","status":"DRAFT","updateTime":"2026-09-04 20:05:01"}
}
空数据 / 降级响应
省略新增字段表示保留现值;接口没有空数据成功或降级成功。
错误响应
{"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<SupplierApprovalCommandRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
data.approvalLogId |
String | 审批记录 ID |
data.provider |
String | 审批提供方 |
data.approvalStatus |
String | 审批状态 |
data.submittedAt |
String | 提交时间 |
请求示例
{
"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"
}
响应示例
{
"code":200,"message":"成功","success":true,
"data":{"approvalLogId":"2095000000000000010","provider":"WECOM","approvalStatus":"PENDING","submittedAt":"2026-09-04 20:05:02"}
}
空数据 / 降级响应
写接口成功时返回审批受理结果;失败时 data 为 null,不会以空对象表示成功。
错误响应
{"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
- 关联 PR: wx/HL#7107
关联 / 联系人
链接
- Issue: #7090
- PR: #7107
- Merge commit: c1102d62ecb81c24596fba91bba6e704da6e85ff
联系人
- 后端负责人: @lc