docs: add supplier context handoff (#7059)
changelog-filename-gate / validate (push) Successful in 2s
changelog-filename-gate / validate (push) Successful in 2s
这个提交包含在:
@@ -0,0 +1,306 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "7059"
|
||||||
|
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: "2026-09-04"
|
||||||
|
status_note: "后端已部署并验证;待前端删除本地映射,仅透传资源上下文。"
|
||||||
|
updated_at: "2026-09-04"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 资源管理:设置供应商候选按资源上下文过滤
|
||||||
|
|
||||||
|
> **服务**: hl-resource-service (8082)
|
||||||
|
> **PR**: #7064
|
||||||
|
> **Issue**: #7059
|
||||||
|
> **日期**: 2026-09-04
|
||||||
|
> **影响范围**: 管理后台资源管理、车务管理的“设置供应商”候选与绑定
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 关键变化
|
||||||
|
|
||||||
|
前端不再维护“资源分类 → 供应商类型”映射;候选查询传 `resourceModule`、`resourceId`,后端解析类型并只返回 `ACTIVE` 且匹配的供应商。
|
||||||
|
|
||||||
|
## 一、背景
|
||||||
|
|
||||||
|
#7042 要求前端传 `typeCode` 的结论已撤销。本次由后端统一解析资源上下文,避免景区混入车队供应商,并修正组合备品误用 `SUPPLIES` 的问题。
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---|------|------|------|----------|------|
|
||||||
|
| 1 | 有界查询供应商 | GET | `/admin/supplier/items/list` | 新增可选查询参数 | 完整资源上下文下由后端过滤候选 |
|
||||||
|
| 2 | 设置或改绑资源供应商 | PUT | `/admin/supplier/resource-relations/{resourceModule}/{resourceId}/update` | 调整类型解析 | 固定映射模块可省略 `requiredTypeCode` |
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
### 1. 有界查询供应商 `GET /admin/supplier/items/list`
|
||||||
|
|
||||||
|
**VO**: `SupplierListReqVO / SupplierListItemRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
资源管理或车务管理打开“设置供应商”候选列表时调用;搜索时沿用 `keyword`。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| `resourceModule` | Query | String | 场景必填 | 与 `resourceId` 同传 | 当前资源模块,不是供应商类型 |
|
||||||
|
| `resourceId` | Query | String | 场景必填 | 正整数,与 `resourceModule` 同传 | 当前资源 ID |
|
||||||
|
| `keyword` | Query | String | 否 | 最长 500 | 搜索关键字 |
|
||||||
|
| `limit` | Query | Integer | 否 | 1~200,默认 50 | 候选列表建议传 200 |
|
||||||
|
| `typeCode` | Query | String | 否 | 通用列表兼容参数 | 设置供应商场景不要传;资源上下文存在时后端忽略调用方值 |
|
||||||
|
| `status` | Query | String | 否 | 通用列表兼容参数 | 设置供应商场景不要传;资源上下文存在时后端固定 `ACTIVE` |
|
||||||
|
|
||||||
|
#### 出参 `Result<List<SupplierListItemRespVO>>`
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `data[].supplierId` | String | 供应商 ID |
|
||||||
|
| `data[].supplierNo` | String | 供应商编号 |
|
||||||
|
| `data[].fullName` | String | 供应商全称 |
|
||||||
|
| `data[].shortName` | String | 供应商简称 |
|
||||||
|
| `data[].types` | Array | 类型列表;元素含 `typeCode`、`typeName`、`isPrimary` |
|
||||||
|
| `data[].status` | String | 资源上下文场景恒为 `ACTIVE` |
|
||||||
|
| 其他既有字段 | - | 响应结构未变化 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /admin/supplier/items/list?resourceModule=SCENIC&resourceId=3001000000000000019&limit=200
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"supplierId": "2091381643661983746",
|
||||||
|
"supplierNo": "SUP2091381643661983746",
|
||||||
|
"fullName": "示例景区供应商",
|
||||||
|
"types": [{ "typeCode": "SCENIC", "typeName": "景区", "isPrimary": true }],
|
||||||
|
"status": "ACTIVE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
没有符合条件的供应商时返回 `data: []`;资源不存在、上下文不完整或映射不可用时失败关闭,不降级为全量列表。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": 200, "message": "成功", "data": [], "success": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 400,
|
||||||
|
"message": "resourceModule与resourceId必须同时提供或同时省略",
|
||||||
|
"data": null,
|
||||||
|
"success": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 完整资源上下文下,后端校验供应商列表权限、资源关系查看权限、资源存在性和数据范围。
|
||||||
|
- 后端只返回状态为 `ACTIVE` 且包含映射类型的供应商;调用方传入的 `typeCode`、`status` 不会覆盖该规则。
|
||||||
|
- 不传资源上下文时,原有 `typeCode`、`status`、`keyword`、`limit` 通用查询行为保持不变。
|
||||||
|
|
||||||
|
### 2. 设置或改绑资源供应商 `PUT /admin/supplier/resource-relations/{resourceModule}/{resourceId}/update`
|
||||||
|
|
||||||
|
**VO**: `SupplierResourceReassignReqVO / SupplierResourceRelationRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
用户确认候选供应商后首次设置或改绑当前资源的供应商。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| `resourceModule` | Path | String | 是 | 见映射表 | 当前资源模块 |
|
||||||
|
| `resourceId` | Path | String | 是 | 正整数 | 当前资源 ID |
|
||||||
|
| `supplierId` | Body | String | 是 | 正整数 | 候选供应商 ID |
|
||||||
|
| `requiredTypeCode` | Body | String | 否 | 最长 64 | 七个固定映射模块应省略,由后端解析 |
|
||||||
|
| `remark` | Body | String | 否 | 最长 500 | 关系备注 |
|
||||||
|
| `changeReason` | Body | String | 是 | 非空,最长 500 | 设置或改绑原因 |
|
||||||
|
| `expectedCurrentSupplierId` | Body | String | 改绑时必填 | 与版本时间同传 | 当前关系供应商 ID |
|
||||||
|
| `expectedRelationUpdateTime` | Body | String | 改绑时必填 | 与当前供应商 ID 同传 | 当前关系并发版本 |
|
||||||
|
|
||||||
|
#### 出参 `Result<SupplierResourceRelationRespVO>`
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `data.supplierId` | String | 生效供应商 ID |
|
||||||
|
| `data.resourceModule` | String | 资源模块 |
|
||||||
|
| `data.resourceId` | String | 资源 ID |
|
||||||
|
| `data.requiredTypeCode` | String | 后端解析并冻结的供应商类型 |
|
||||||
|
| `data.updateTime` | String | 后续改绑或解绑使用的并发版本 |
|
||||||
|
| 其他既有字段 | - | 响应结构未变化 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"supplierId": "2091381643661983746",
|
||||||
|
"changeReason": "设置资源供应商"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"supplierId": "2091381643661983746",
|
||||||
|
"resourceModule": "SUPPLIES_COMBO",
|
||||||
|
"resourceId": "2046122595429806082",
|
||||||
|
"requiredTypeCode": "SUPPLIES_COMBO",
|
||||||
|
"updateTime": "2026-09-04 12:00:00"
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
写接口成功时返回完整关系;校验失败时返回业务错误和 `data: null`,不会创建或改写关系。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 395037,
|
||||||
|
"message": "供应商类型不满足资源关联要求",
|
||||||
|
"data": null,
|
||||||
|
"success": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 七个固定映射模块由后端确定 `requiredTypeCode`;前端不要提交本地映射值。
|
||||||
|
- 供应商必须处于 `ACTIVE` 且包含所需类型;失败时关系保持不变。
|
||||||
|
- 已有关系改绑仍必须传成对的并发版本字段,既有审计、权限和数据范围规则不变。
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
| 场景 | 正确调用 | 错误调用 |
|
||||||
|
|------|----------|----------|
|
||||||
|
| 打开候选列表 | `resourceModule=SCENIC&resourceId={id}&limit=200` | 前端把 `SCENIC` 映射为 `typeCode` 后只按类型查询 |
|
||||||
|
| 搜索候选 | 上述参数继续加 `keyword` | 搜索时丢失资源上下文 |
|
||||||
|
| 设置/改绑 | Path 传资源上下文,Body 省略 `requiredTypeCode` | 前端根据字典或资源分类拼 `requiredTypeCode` |
|
||||||
|
|
||||||
|
前端应删除资源分类与供应商类型的本地映射。`supplier_type` 在“系统管理 → 字典管理”维护供应商类型的名称、状态和排序;它不是资源模块映射配置。资源模块映射由后端统一维护。
|
||||||
|
|
||||||
|
## 五、数据库行为
|
||||||
|
|
||||||
|
设置或改绑时,关系中冻结后端解析出的 `requiredTypeCode`;本次无表结构、存量数据迁移或跨库写入变化,原有关系审计行为保持不变。
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- `resourceModule` 与 `resourceId` 只传一个 → `400`,`resourceModule与resourceId必须同时提供或同时省略`。
|
||||||
|
- 未知模块 → `395034`,`不支持的资源模块`;资源不存在或已删除 → `395035`。
|
||||||
|
- `ACTIVITY`、`COST_ITEM`、`STAFF` 本工单没有默认映射,按资源上下文查询会以 `400 requiredTypeCode不能为空` 失败关闭。
|
||||||
|
- 映射类型在 `supplier_type` 字典缺失或停用 → `400`,`供应商类型不合法或已停用`。
|
||||||
|
- 未登录 → 应用响应 `401`;无权限或超出资源数据范围 → 拒绝访问。
|
||||||
|
|
||||||
|
## 六.5、枚举 / 数据字典
|
||||||
|
|
||||||
|
### resourceModule 与 supplier_type
|
||||||
|
|
||||||
|
**所属字段**: `SupplierListReqVO.resourceModule / SupplierResourceRelationRespVO.requiredTypeCode` | **类型**: `String`
|
||||||
|
|
||||||
|
| `resourceModule` | 后端要求的 `supplier_type` | 页面 |
|
||||||
|
|------------------|-------------------------------|------|
|
||||||
|
| `SCENIC` | `SCENIC` | 景区管理 |
|
||||||
|
| `RESTAURANT` | `RESTAURANT` | 餐厅管理 |
|
||||||
|
| `SUPPLIES` | `SUPPLIES` | 备品管理 |
|
||||||
|
| `SUPPLIES_COMBO` | `SUPPLIES_COMBO` | 组合配品 |
|
||||||
|
| `HOTEL` | `HOTEL` | 酒店管理 |
|
||||||
|
| `SERVICE` | `SERVICE` | 服务管理 |
|
||||||
|
| `VEHICLE` | `FLEET` | 车务管理-车队管理 |
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
### 字段级对比
|
||||||
|
|
||||||
|
| 字段 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| 候选查询资源上下文 | 无 | 新增可选 `resourceModule`、`resourceId`,必须成对传入 |
|
||||||
|
| `requiredTypeCode` | 组合备品可能由调用方误传 `SUPPLIES` | 固定映射模块可省略,组合备品由后端解析为 `SUPPLIES_COMBO` |
|
||||||
|
|
||||||
|
### 行为级对比
|
||||||
|
|
||||||
|
| 行为 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| 设置供应商候选 | 依赖前端映射 `typeCode`,可能展示不对应类型 | 后端按真实资源上下文过滤 `ACTIVE` 且匹配的供应商 |
|
||||||
|
| 无资源上下文的通用列表 | 按调用方筛选 | 保持不变 |
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- **是否破坏向后兼容**: 否;无资源上下文的原调用保持兼容。
|
||||||
|
- **前端是否必须同步上线**: 是。
|
||||||
|
- **前端 workaround 清理点**: 删除资源分类与供应商类型本地映射;候选查询改传 `resourceModule`、`resourceId`,绑定请求不再拼 `requiredTypeCode`。
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- **仅影响**: 管理后台资源管理、车务管理的供应商候选和设置/改绑类型解析。
|
||||||
|
- **零影响**: 供应商分页管理、供应商注册审批、既有响应字段、数据库结构、Redis、MQ 和其他前端源码。
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
```text
|
||||||
|
SCENIC 候选:忽略错误 typeCode/status,只返回 ACTIVE + SCENIC,FLEET-only 为 0 ✓
|
||||||
|
SUPPLIES_COMBO 候选及绑定:返回/冻结 SUPPLIES_COMBO,绑定后已解绑恢复原关系状态 ✓
|
||||||
|
VEHICLE 候选:忽略错误 typeCode/status,只返回 ACTIVE + FLEET ✓
|
||||||
|
通用列表 typeCode/status/keyword/limit:保持兼容 ✓
|
||||||
|
上下文不完整、无默认映射、失效类型、资源不存在:均失败关闭 ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
## 九、相关历史 PR
|
||||||
|
|
||||||
|
| PR / 提交 | Issue | 说明 | 是否仍有效 |
|
||||||
|
|-----------|-------|------|------------|
|
||||||
|
| changelog `5046bce` | #7042 | 原要求前端维护映射 | ❌ 已更正 |
|
||||||
|
| changelog `a0daab2` | #7042 | 撤销前端映射要求,转后端工单 | ✅ 有效 |
|
||||||
|
| **PR #7064** | **#7059** | 后端按资源上下文解析、过滤并修正组合备品映射 | ✅ 最新 |
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- 关联 Issue: [wx/HL#7059](https://git.1814.love:8443/wx/HL/issues/7059)
|
||||||
|
- 关联 PR: [wx/HL#7064](https://git.1814.love:8443/wx/HL/pulls/7064)
|
||||||
|
- 被更正记录: [#7042 Changelog](./03_7042_设置供应商列表按资源类型过滤-前端缺陷-管理后台.md)
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
### 链接
|
||||||
|
|
||||||
|
- **Issue**: [#7059](https://git.1814.love:8443/wx/HL/issues/7059)
|
||||||
|
- **PR**: [#7064](https://git.1814.love:8443/wx/HL/pulls/7064)
|
||||||
|
- **Merge commit**: [5999b532e9f9725ac3b36f859ee48f6f0b8aa43c](https://git.1814.love:8443/wx/HL/commit/5999b532e9f9725ac3b36f859ee48f6f0b8aa43c)
|
||||||
|
|
||||||
|
### 联系人
|
||||||
|
|
||||||
|
- **后端负责人**: @lc
|
||||||
在新工单中引用
屏蔽一个用户