docs(supplier): publish resource info page API for #6316
changelog-filename-gate / validate (push) Successful in 2s

这个提交包含在:
lc
2026-08-25 13:10:51 +08:00
父节点 ded9289d98
当前提交 1eafac1a59
共修改 2 个文件,包含 555 行新增和 0 行删除
@@ -0,0 +1,163 @@
---
schema: "hl-changelog/v2"
ticket: "6316"
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-08-25"
status_note: "PR #6330 已合并 dev-v3,合并提交 4f032cd6f 已由任务 cc1fe248、2697d374 精确发布 Resource/Fleet 至 TEST 并经真实 Gateway 只读验收;验收后任务 45e843e5、c05eda6e 已回切包含该提交的 dev-v3,两个服务均保持双实例健康。"
updated_at: "2026-08-25"
base: "dev-v3"
---
# 供应商详情新增资源信息分页
供应商详情新增只读“资源信息”分页接口。数据以本系统 `supplier_resource_rel` 当前有效关系为入口,展示 Resource 本地九类资源及 Fleet 车辆的当前权威信息;供应商关系已保留但资源已删除时返回缺失占位,避免详情悄然丢行。
## 变更接口
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | `/admin/supplier/items/{supplierId}/resource-info/page` | 分页查询供应商当前有效关系对应的资源信息 |
查询参数:
| 参数 | 类型 | 必填 | 默认/约束 | 说明 |
|---|---|---:|---|---|
| `supplierId` | string | 是 | 正整数 | 路径参数,Snowflake ID 按字符串处理 |
| `page` | integer | 否 | 默认 `1`,最小 `1` | 页码;兼容公共分页参数 `pageNo` |
| `pageSize` | integer | 否 | 默认 `20`,范围 `1..100` | 每页条数 |
| `resourceModule` | string | 否 | 十选一 | 按关系冻结的资源模块精确筛选 |
支持模块:`SCENIC`、`RESTAURANT`、`SUPPLIES`、`SUPPLIES_COMBO`、`ACTIVITY`、`HOTEL`、`SERVICE`、`COST_ITEM`、`STAFF`、`VEHICLE`。
## 返回字段
分页 `data` 使用统一 `PageResult`:`records`、`total`、`page`、`pageSize`。`records[]` 字段如下:
| 字段 | JSON 类型 | 语义 |
|---|---|---|
| `relationId` | string | 供应商资源关系 ID |
| `resourceModule` | string | 冻结模块编码 |
| `moduleName` | string | 模块中文名 |
| `resourceId` | string | 资源 ID;资源缺失时仍保留关系原值 |
| `resourceName` | string/null | 当前资源名称 |
| `coverUrl` | string/null | 当前有效封面 URL |
| `city` | string/null | 城市展示值 |
| `isCharged` | boolean/null | 是否收费 |
| `isChargedName` | string/null | 是否收费中文名 |
| `settleTypeCode` | string/null | 结算方式编码 |
| `settleTypeName` | string/null | 结算方式中文名 |
| `tags` | array | 标签数组,永不返回 `null` |
| `seasons` | array | 标准季节数组,永不返回 `null` |
| `statusCode` | string/null | 资源当前权威状态编码 |
| `statusName` | string/null | 归一化状态中文名 |
| `enabled` | boolean/null | 归一化启用状态 |
| `resourceAvailable` | boolean | 资源当前是否存在;`false` 为关系保留、资源缺失 |
| `updateTime` | string/null | 资源本身更新时间,格式 `yyyy-MM-dd HH:mm:ss` |
`tags[]` 返回 `tagId`、`tagName`、`tagColor`;`seasons[]` 返回 `seasonCode`、`seasonName`。标量不适用或未知时返回 `null`,集合无数据时返回 `[]`。结果按关系 `update_time DESC, rel_id DESC` 排序,展示的 `updateTime` 则来自资源主数据。
响应示例:
```json
{
"code": 200,
"message": "success",
"success": true,
"data": {
"records": [
{
"relationId": "2091715622923657218",
"resourceModule": "SCENIC",
"moduleName": "景区管理",
"resourceId": "2091715622923657001",
"resourceName": "示例景区",
"coverUrl": null,
"city": "海拉尔",
"isCharged": true,
"isChargedName": "是",
"settleTypeCode": "CASH",
"settleTypeName": "现付",
"tags": [
{ "tagId": "2084636804090089473", "tagName": "自然风光", "tagColor": "#52C41A" }
],
"seasons": [
{ "seasonCode": "spring", "seasonName": "春" }
],
"statusCode": "ENABLED",
"statusName": "启用",
"enabled": true,
"resourceAvailable": true,
"updateTime": "2026-08-25 10:00:00"
}
],
"total": 1,
"page": 1,
"pageSize": 20
}
}
```
## 权限、依赖与错误码
- Gateway 强制认证;服务端仅允许 `ADMIN`、`FINANCE`、`SUPER_ADMIN`,并同时要求 `supplier:view` 与 `supplier:resource:view`。
- 任意供应商生命周期状态均可查询;接口没有写入、缓存、MQ 或操作审计副作用。
- 本地九类资源批量查询 Resource 数据;`VEHICLE` 通过内部 Token 调用 Fleet 批量接口,管理端不得直接调用内部接口。
- Resource、Fleet 或必要字典依赖异常时失败关闭,不返回半真半假的成功数据。
| 业务码 | 场景 |
|---:|---|
| `401` | 未认证或登录态失效 |
| `400` | 路径/分页参数不合法 |
| `395001` | 供应商不存在 |
| `395034` | 不支持的 `resourceModule` |
| `395039` | Fleet、字典或资源必要依赖不可用/响应不完整 |
## 管理端接入事项
1. 在供应商详情“账号信息”页签后新增“资源信息”页签,进入页签后按需请求本接口。
2. 建议列为资源名称(含封面)、模块/类型、城市、是否收费、结算方式、标签、季节、状态、更新时间;字段与用户提供的资源列表示意保持一致,但以本接口实际数据为准。
3. ID 全程按字符串传递和比较,禁止转为 JavaScript `number`。
4. 展示名称优先使用 `moduleName`、`isChargedName`、`settleTypeName`、`statusName`;未知值显示占位符,不自行推导业务码。
5. `tags`、`seasons` 直接按数组渲染;`resourceAvailable=false` 时保留该行并展示“资源已删除/不可用”,不要过滤。
6. 分页筛选变化时回到第 1 页;页容量不得超过 100。管理端不提供资源关系的新增、编辑、删除或状态切换操作。
## 兼容性与未变化范围
- 新增只读 GET,不修改既有供应商详情、账号、审批、资源管理写接口及响应字段。
- 不新增或修改数据库 migration;沿用既有 `supplier_resource_rel`、Resource 主表与 Fleet 车辆数据。
- 不变更 Gateway 顶级路由、Nacos 配置、Redis、MQ、状态机、审批、数据范围或软删除语义。
- 后端仓库未修改任何管理端源码;管理端接入状态保持 `pending`。
## 验证证据
- 自动化:供应商相关测试 282 项零失败(1 项条件跳过);Fleet 车辆包 228 项零失败;Resource 全量 2043 项零失败(38 项条件跳过);Fleet 可运行全量 3853 项零失败(7 项条件跳过);Gateway 路由审计 3 项零失败。
- 独立审计:在合并提交 `4f032cd6f` 的 detached worktree 重新核对权限、错误码、软删除、缺失资源占位、Fleet 批量与失败关闭;供应商审计套件和 Fleet 审计套件 249 项均零失败。
- TEST 精确部署:Resource 任务 `cc1fe248`(13:02:08–13:02:42)和 Fleet 任务 `2697d374`(13:03:42–13:04:18)均退出码 0;部署端 HEAD 为 `4f032cd6f`,Resource 8082/8182、Fleet 8087/8187 滚动恢复健康,Nacos `test` 中各有 2 个实例。
- 真实 Gateway:使用现有有效管理端会话只读查询全部 3 个 TEST 供应商,实际取得 1 条 `SCENIC` 资源关系;18 个字段齐全,Snowflake ID 为字符串,`tags`/`seasons` 为数组,时间格式及模块筛选通过。不存在供应商、未知模块、`page=0`、`pageSize=101` 分别返回 `395001`、`395034`、`400`、`400`;未认证请求为 HTTP 200、业务码 `401`、`success=false`。
- TEST 当前没有 `VEHICLE` 供应商关系样本,因此未伪造数据;跨服务车辆路径由真实双服务部署健康、内部 Token 控制器契约、批量查询、重复/缺失/额外响应拒绝及 tombstone 测试覆盖。
- 环境恢复:验收后任务 `45e843e5`(Resource)与 `c05eda6e`(Fleet)依次回切包含本次合并的 `dev-v3`,退出码均为 0;8082/8182、8087/8187 及 Nacos 各 2 个实例保持健康,临时精确部署分支已删除。
- 清理:验收全程只读,无供应商、资源、数据库、Redis、MQ 或配置数据需要清理。
## 撤回
1. 从最新 `dev-v3` 创建回退分支,执行 `git revert -m 1 --no-edit 4f032cd6f6698607a2f1524437533d595975fc9a`,经独立 PR 合入。
2. 依次重新构建并滚动部署 `hl-resource-service`、`hl-fleet-service`;回退期间两个服务分别维持双实例滚动策略。
3. 本次无数据库、Redis、MQ、Nacos 或其他配置变更,不需要 DDL、DML、缓存清理、消息补偿或配置恢复;不存在不可逆数据影响。
4. 回退后管理端停止调用新增 GET 和读取本次字段;既有供应商详情、账号及资源管理接口继续兼容。
5. 经 Gateway 复测新增路径不可用/已撤回、既有供应商详情正常、两个服务双实例与 Nacos 健康,并核对数据库、缓存和 MQ 无副作用。
## 关联 / 联系人
- **Issue**: [#6316](https://git.1814.love:8443/wx/HL/issues/6316)
- **PR**: [#6330](https://git.1814.love:8443/wx/HL/pulls/6330)
- **合并提交**: [4f032cd6f](https://git.1814.love:8443/wx/HL/commit/4f032cd6f6698607a2f1524437533d595975fc9a)
- **后端负责人**: @lc