@@ -0,0 +1,288 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "6739"
|
||||||
|
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: "供应商写接口现接收最下级 countyId;基本信息详情返回 provinceId、prefectureId、countyId 和 address。当前状态:待前端接入三级联动并按字段回显。"
|
||||||
|
updated_at: "2026-08-30"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 供应商三级地址保存与回显
|
||||||
|
|
||||||
|
`countyId` 保存三级联动的最下级区县 ID,`address` 只保存详细地址,例如“某某路 1 号”。前端不要再使用 `addressId`。
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---:|---|---|---|---|---|
|
||||||
|
| 1 | 新增供应商草稿 | POST | `/admin/supplier/items/add` | 请求字段 | 可传 `countyId`、`address` |
|
||||||
|
| 2 | 修改供应商 | PUT | `/admin/supplier/items/{supplierId}/update` | 请求字段 | 可更新 `countyId`、`address` |
|
||||||
|
| 3 | 提交供应商 | POST | `/admin/supplier/items/{supplierId}/submit` | 请求字段 | 完整表单可传 `countyId`、`address` |
|
||||||
|
| 4 | 查询供应商基本信息 | GET | `/admin/supplier/items/{supplierId}/basic-info/view` | 响应字段 | 顶层返回三级 ID 与 `address` |
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
### 1. 新增供应商草稿 `POST /admin/supplier/items/add`
|
||||||
|
|
||||||
|
**VO**: `SupplierDraftSaveReqVO / SupplierWriteRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
新增草稿时同时保存区县选择和详细地址。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `countyId` | Body | String | 否 | 正整数 | 三级联动最后一级区县 ID |
|
||||||
|
| `address` | Body | String | 否 | 最长 500 字符 | 详细地址,不拼接省市区名称 |
|
||||||
|
| `fullName` / `taxNo` / `mainCooperation` | Body | String | 是 | 沿用既有规则 | 其他新增必填字段 |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `data.supplierId` | String | 新供应商 ID |
|
||||||
|
| `data.updateTime` | String | 后续修改使用的并发版本 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"fullName":"示例旅行服务有限公司","taxNo":"91350211M000100Y46","countyId":"376","address":"某某路1号","mainCooperation":"景区合作"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":200,"message":"成功","success":true,"data":{"supplierId":"2093966831894056961","status":"DRAFT","updateTime":"2026-08-30 15:39:31"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
省略 `countyId` 或 `address` 时按 `null` 保存;依赖或业务校验失败时不产生部分写入。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":400,"message":"区县ID必须为正数","success":false,"data":null}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 有三级联动选择结果时只传最后一级 `countyId`。
|
||||||
|
- `addressId` 不是本接口字段。
|
||||||
|
|
||||||
|
### 2. 修改供应商 `PUT /admin/supplier/items/{supplierId}/update`
|
||||||
|
|
||||||
|
**VO**: `SupplierUpdateReqVO / SupplierWriteRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
编辑页修改区县或详细地址。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `supplierId` | Path | String | 是 | 正整数 | 供应商 ID |
|
||||||
|
| `countyId` | Body | String | 否 | 正整数 | 新的最下级区县 ID |
|
||||||
|
| `address` | Body | String | 否 | 最长 500 字符 | 新的详细地址 |
|
||||||
|
| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 详情最新并发版本 |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `data.supplierId` | String | 供应商 ID |
|
||||||
|
| `data.updateTime` | String | 保存后的新并发版本 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"countyId":"377","address":"某某路2号","expectedUpdateTime":"2026-08-30 15:39:31"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":200,"message":"成功","success":true,"data":{"supplierId":"2093966831894056961","status":"DRAFT","updateTime":"2026-08-30 15:39:42"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
省略 `countyId` 或 `address` 表示该字段不修改;失败时原值和版本保持不变。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":400,"message":"区县ID必须为正数","success":false,"data":null}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 修改成功后使用响应中的新 `updateTime` 重新查询详情。
|
||||||
|
- 非正数 `countyId` 在写入前拒绝。
|
||||||
|
|
||||||
|
### 3. 提交供应商 `POST /admin/supplier/items/{supplierId}/submit`
|
||||||
|
|
||||||
|
**VO**: `SupplierSubmitReqVO / SupplierApprovalCommandRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
提交完整供应商表单进入审批时一并保存区县和详细地址。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `supplierId` | Path | String | 是 | 正整数 | 草稿供应商 ID |
|
||||||
|
| `countyId` | Body | String | 否 | 正整数 | 最下级区县 ID |
|
||||||
|
| `address` | Body | String | 否 | 最长 500 字符 | 详细地址 |
|
||||||
|
| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 当前并发版本 |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `data.approvalLogId` | String | 审批记录 ID |
|
||||||
|
| `data.approvalStatus` | String | 审批状态 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"fullName":"示例旅行服务有限公司","taxNo":"91350211M000100Y46","countyId":"377","address":"某某路2号","mainCooperation":"景区合作","expectedUpdateTime":"2026-08-30 15:39:42"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":200,"message":"成功","success":true,"data":{"approvalLogId":"2093967000000000001","approvalStatus":"APPROVED"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
`countyId`、`address` 为空时按完整表单既有规则处理;提交失败不推进审批状态。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":400,"message":"区县ID必须为正数","success":false,"data":null}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 仍须提交完整表单和最新 `expectedUpdateTime`。
|
||||||
|
- 本次不改变既有审批、幂等和状态门禁。
|
||||||
|
|
||||||
|
### 4. 查询供应商基本信息 `GET /admin/supplier/items/{supplierId}/basic-info/view`
|
||||||
|
|
||||||
|
**VO**: `SupplierBasicInfoRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
编辑页读取三级联动默认值和详细地址。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `supplierId` | Path | String | 是 | 正整数 | 供应商 ID |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `data.provinceId` | String/null | 省级 ID |
|
||||||
|
| `data.prefectureId` | String/null | 市级 ID |
|
||||||
|
| `data.countyId` | String/null | 已保存的最下级区县 ID |
|
||||||
|
| `data.address` | String/null | 已保存的详细地址原值 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /admin/supplier/items/2093966831894056961/basic-info/view
|
||||||
|
Authorization: Bearer <admin-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":200,"message":"成功","success":true,"data":{"supplierId":"2093966831894056961","provinceId":"1","prefectureId":"35","countyId":"377","address":"某某路2号","updateTime":"2026-08-30 15:39:42"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
历史供应商没有 `countyId` 时三个行政区划 ID 均为 `null`,`address` 仍按历史值返回。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":395001,"message":"供应商不存在","success":false,"data":null}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 三个行政区划 ID 均按 JSON 字符串返回。
|
||||||
|
- 行政区划父链不可用或不完整时失败关闭,不伪造 ID。
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
1. 用 `/admin/region/children` 逐级选择,将最后一级 ID 作为 `countyId`,门牌内容单独放入 `address`。
|
||||||
|
2. 编辑页按 `provinceId → prefectureId → countyId` 设置默认选中,并用 `address` 初始化详细地址输入框。
|
||||||
|
3. 前端字段统一命名为 `countyId`;保存后使用新版本重新查询详情。
|
||||||
|
|
||||||
|
## 五、数据库行为
|
||||||
|
|
||||||
|
- 写接口成功后,后续详情查询返回已保存的 `countyId` 和 `address`。
|
||||||
|
- 非正数 `countyId` 校验失败时不修改原值或并发版本。
|
||||||
|
- 历史供应商不自动补行政区划 ID。
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- 未认证返回业务码 `401`;供应商不存在或已删除返回 `395001`。
|
||||||
|
- 业务失败可能仍使用 HTTP 200,前端须同时判断 `code` 与 `success`。
|
||||||
|
- `address` 不包含省市区中文文本;省市区展示由三级 ID 对应的选项生成。
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
| 项目 | 修改前 | 修改后 |
|
||||||
|
|---|---|---|
|
||||||
|
| 写请求 | 仅保存详细地址 | 可同时保存最下级 `countyId` 与详细地址 |
|
||||||
|
| 详情回显 | 仅有 `address` | 顶层增加三个行政区划 ID,继续返回 `address` |
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- **是否破坏向后兼容**:否,历史空值继续返回 `null`。
|
||||||
|
- **前端是否必须同步上线**:是,需要传 `countyId` 并消费三级回显字段。
|
||||||
|
- **前端 workaround 清理点**:移除 `addressId` 映射和自行解析完整中文地址的逻辑。
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- 不改变供应商权限、状态机、审批、并发和错误码。
|
||||||
|
- 不改变行政区划联动接口契约,也不影响其他资源模块。
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
- 新增与修改后可回读对应 `countyId`、`address`,详情三个行政区划 ID 均为字符串。
|
||||||
|
- 非正数 `countyId` 返回 `400` 且原数据不变;未认证返回 `401`;验收草稿已清理。
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- [Issue #6739](https://git.1814.love:8443/wx/HL/issues/6739)
|
||||||
|
- [PR #6744](https://git.1814.love:8443/wx/HL/pulls/6744)
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
- **合并提交**: [2d24b3290](https://git.1814.love:8443/wx/HL/commit/2d24b32908bffb0e7ac95fd31b33cdfe56ae69f5)
|
||||||
|
- **后端负责人**: @lc
|
||||||
|
- **当前状态**: 待前端接入
|
||||||
在新工单中引用
屏蔽一个用户