diff --git a/api-docs/supplier/供应商详情资源信息分页 API 接口规范-v1.0.html b/api-docs/supplier/供应商详情资源信息分页 API 接口规范-v1.0.html new file mode 100644 index 00000000..0e77cdcc --- /dev/null +++ b/api-docs/supplier/供应商详情资源信息分页 API 接口规范-v1.0.html @@ -0,0 +1,392 @@ + + + + + + 供应商详情资源信息分页 API 接口规范 · v1.0 + + + +
+
+
HL Supplier API · Admin
+

供应商详情资源信息分页 API 接口规范

+

v1.0 · Issue #6316 · 2026-08-25

+
+ 已实现 · 可联调 + 后端 deployed + Gateway verified + 前端 pending + 只读接口 +
+
+
+ + +
+

1. 接口概览

+
GET/admin/supplier/items/{supplierId}/resource-info/page
+

用于供应商管理详情页“资源信息”页签,分页展示该供应商当前有效关系对应的资源权威信息。关系来源为本系统 supplier_resource_rel;Resource 提供九类本地资源,Fleet 提供车辆资源。

+
+
实现状态已实现 · 可联调
+
调用方管理后台;前端接入待完成
+
数据副作用无写库、Redis、MQ、配置或审计副作用
+
+
契约真相本文以合并提交 4f032cd6f 的 Controller、请求/响应 VO、Service 权限门禁及 TEST Gateway 验收为准。
+
+ +
+

2. 请求契约

+

2.1 路径与查询参数

+ + + + + + + + +
参数位置类型必填约束与默认值
supplierIdpathstring是正整数;Snowflake ID 必须按字符串传递
pagequeryinteger否默认 1,最小 1;公共分页兼容 pageNo
pageSizequeryinteger否默认 20,范围 1..100
resourceModulequerystring否为空查询全部;非空按关系冻结模块精确筛选
+

2.2 支持的资源模块

+ + + + + + + + + + + + + + +
编码moduleName数据归属
SCENIC景区管理Resource
RESTAURANT餐厅管理Resource
SUPPLIES备品管理Resource
SUPPLIES_COMBO组合配品Resource
ACTIVITY游玩项目管理Resource
HOTEL酒店管理Resource
SERVICE服务管理Resource
COST_ITEM额外成本Resource
STAFF服务人员管理Resource
VEHICLE车队管理-车队管理Fleet(内部批量聚合)
+

2.3 调用示例

+
GET /admin/supplier/items/2091715622923657217/resource-info/page?page=1&pageSize=20&resourceModule=SCENIC
+Authorization: Bearer <有效管理端访问令牌>
+
权限是双门禁服务端仅允许 ADMIN、FINANCE、SUPER_ADMIN,并同时要求 supplier:view 与 supplier:resource:view。不能只通过隐藏页签代替服务端授权。
+
+ +
+

3. 响应结构

+

统一返回 Result<PageResult<SupplierResourceInfoRespVO>>。业务失败通常仍是 HTTP 200,调用方必须检查 code、success 与 message。

+
{
+  "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
+  }
+}
+
+ +
+

4. records[] 字段

+ + + + + + + + + + + + + + + + + + + + + + +
字段类型可空说明
relationIdstring否供应商资源关系 ID
resourceModulestring否关系冻结的资源模块编码
moduleNamestring否模块中文名
resourceIdstring否资源 ID;资源缺失仍保留关系原值
resourceNamestring是当前资源名称
coverUrlstring是当前有效封面 URL
citystring是城市展示值
isChargedboolean是是否收费;不适用/未知为 null
isChargedNamestring是是否收费中文名
settleTypeCodestring是结算方式编码
settleTypeNamestring是结算方式中文名
tagsarray否标签列表;无数据为 []
seasonsarray否标准季节列表;无数据为 []
statusCodestring是资源当前权威状态编码
statusNamestring是归一化状态中文名
enabledboolean是归一化启用标记
resourceAvailableboolean否false 表示关系保留但资源已删除/缺失
updateTimestring是资源本身更新时间;yyyy-MM-dd HH:mm:ss
+

4.1 子结构

+ + + + + + +
数组字段说明
tags[]tagId、tagName、tagColor标签 ID 沿用各资源模块的字符串表达
seasons[]seasonCode、seasonName标准季节编码与中文名
+
+ +
+

5. 业务口径

+
    +
  • 只读取当前有效的供应商资源关系,按关系 update_time DESC, rel_id DESC 稳定排序。
  • +
  • 响应中的 updateTime 是资源主数据更新时间,不是关系更新时间。
  • +
  • 标量字段不适用、未知或资源缺失时返回 null;tags 与 seasons 永远返回数组。
  • +
  • 资源被软删除或不存在时不丢弃关系行:resourceAvailable=false,名称、状态、更新时间等当前资源字段为 null。
  • +
  • 十类资源以本系统权威数据为准;展示形式可参考现有资源列表,但不要从参考图硬编码字段值或状态。
  • +
  • 供应商处于草稿、审批中、合作中、暂停、黑名单、归档等任意生命周期状态时均可只读查询。
  • +
  • Fleet/字典依赖出现空响应、非成功、重复、缺失、额外或非法数据时返回 395039,不降级为部分成功。
  • +
+
内部依赖说明Resource 通过内部 Token 调用 POST /internal/fleet/vehicles/supplier-resource-info/batch 聚合车辆信息。该路径不面向管理端,前端不得调用、转发或持有内部 Token。
+
+ +
+

6. 错误码

+ + + + + + + + + +
业务码场景管理端建议
401未认证或登录态失效按统一登录续期/退出逻辑处理
400supplierId、page 或 pageSize 等参数不合法修正请求,不自动重试
395001供应商不存在关闭失效详情或刷新列表
395034resourceModule 不受支持仅使用本文十个稳定编码
395039Fleet、字典或资源必要依赖不可用/响应不完整提示稍后重试,不展示旧数据冒充成功
+
{
+  "code": 395034,
+  "message": "不支持的资源模块",
+  "data": null,
+  "success": false
+}
+
+ +
+

7. 管理端接入清单

+
    +
  1. 在供应商详情“账号信息”页签后新增“资源信息”页签;仅在页签打开时加载数据。
  2. +
  3. 建议列:资源名称(封面 + 名称)、资源模块、城市、是否收费、结算方式、标签、季节、状态、更新时间。
  4. +
  5. 所有 ID 按字符串保存、传参和比较,禁止转换为 JavaScript number。
  6. +
  7. 优先展示服务端中文字段;未知字段显示“—”,不得前端猜测状态或字典名称。
  8. +
  9. resourceAvailable=false 时保留行并明确显示“资源已删除/不可用”。
  10. +
  11. 模块筛选或页容量改变时回到第 1 页;pageSize 最大 100。
  12. +
  13. 按 code/success 判断业务结果;不要仅依据 HTTP 200。
  14. +
  15. 页签为只读展示,不增加绑定、改绑、解绑、启停或删除按钮。
  16. +
+

7.1 建议验收场景

+ + + + + + + + + + +
场景预期
有资源关系按分页显示,中文字段、数组、字符串 ID 正常
无资源关系records=[]、total=0,不显示错误空态
按模块筛选返回行的 resourceModule 全部等于筛选值
关系存在但资源缺失保留关系行,resourceAvailable=false
无双权限/未登录服务端拒绝,页面不泄露数据
依赖暂不可用展示 395039 对应提示,不展示不完整成功页
+
+ +
+

8. 实现与验收状态

+
    +
  • 代码:PR #6330 已合并 dev-v3,合并提交 4f032cd6f6698607a2f1524437533d595975fc9a。
  • +
  • 自动化:Resource 全量 2043 项零失败;Fleet 可运行全量 3853 项零失败;GatewayRouteAuditTest 3 项零失败;独立审计套件再次通过。
  • +
  • TEST:任务 cc1fe248、2697d374 精确部署同一合并提交,Resource/Fleet 双实例与 Nacos 各 2 实例健康。
  • +
  • 真实 Gateway:有效管理端会话只读查询 3 个供应商,实际取得 1 条 SCENIC 关系;18 字段、字符串 ID、数组、时间和模块筛选均通过。
  • +
  • 负向:395001、395034、page/pageSize 参数 400 与未认证 401 均实测通过。
  • +
  • 车辆样本:TEST 当时无 VEHICLE 供应商关系;未伪造数据,跨服务路径由双服务真实部署健康与内部契约/批量/失败关闭测试覆盖。
  • +
  • 环境恢复:任务 45e843e5、c05eda6e 已回切包含本次合并的 dev-v3;Resource 8082/8182、Fleet 8087/8187 及 Nacos 各 2 个实例健康,临时部署分支已删除。
  • +
+
数据清理TEST 验收全部为 GET 只读请求,没有创建或修改供应商、资源、数据库、Redis、MQ 或配置数据。
+
+ +
+

9. 撤回方案

+
    +
  1. 从最新 dev-v3 创建回退分支,执行 git revert -m 1 --no-edit 4f032cd6f6698607a2f1524437533d595975fc9a,经独立 PR 合入。
  2. +
  3. 依次重新构建并滚动部署 Resource、Fleet,分别保持双实例可用。
  4. +
  5. 本次无数据库、Redis、MQ、Nacos 或其他配置变更,无需 DDL、DML、缓存清理、消息补偿或配置恢复,也无不可逆影响。
  6. +
  7. 管理端停止调用新增 GET 和读取本次字段;既有供应商详情、账号和资源管理接口不受影响。
  8. +
  9. 经 Gateway 复测新增路径撤回、既有供应商详情正常,并确认两服务双实例和 Nacos 健康。
  10. +
+
+
+ +
+ + diff --git a/changelogs-v2/2026-08/25_6316_供应商详情新增资源信息分页-新增接口-管理后台.md b/changelogs-v2/2026-08/25_6316_供应商详情新增资源信息分页-新增接口-管理后台.md new file mode 100644 index 00000000..a5eac94a --- /dev/null +++ b/changelogs-v2/2026-08/25_6316_供应商详情新增资源信息分页-新增接口-管理后台.md @@ -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