文件
hl-api-changelog/changelogs-v2/2026-08/23_6195_供应商资源关系查询改绑解绑与版本修正-新增接口-管理后台.md
T
lc 3f10b2478e
changelog-filename-gate / validate (push) Successful in 1s
docs(changelog): 发布供应商资源关系接口说明
Refs #6195

Refs #6197

Refs #6200
2026-08-23 14:02:20 +08:00

10 KiB
原始文件 Blame 文件历史

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 6195 供应商资源关系查询、设置改绑与解绑 admin lc(GIT) 新增接口 deployed verified pending 主 PR #6196 与补充 PR #6198/#6201 均已合并 dev-v3,最终链路提交 b71cc41c8 已完成 TEST,并包含在当前部署提交 041fb6d492 中。真实角色、Gateway、绑定/查询/解绑、车辆依赖失败关闭及首次响应版本可直接回用均已验证;两条无安全删除入口的 ACTIVE 测试供应商主档作为已记录残留保留,未执行直接 DML。 2026-08-23 dev-v3

供应商资源关系:查询、设置改绑与解绑

本次新增资源页面维护供应商关系的三个管理端接口,覆盖读取当前关系、首次绑定或显式改绑、按并发版本解绑。关系统一存放在 Resource 服务,不向景区、酒店、车辆等资源主表写入 supplier_id,也不跨 schema 读写。

补充修复 #6197 和 #6200 已一并纳入本契约:Fleet 车辆摘要的所有远端运行时异常统一映射为 395039;首次绑定返回的 updateTime 与 MySQL 秒精度持久化值一致,可立即用于改绑或解绑。

变更接口

编号 方法 路径 权限 返回
SUP-ADM-048 GET /admin/supplier/resource-relations/{resourceModule}/{resourceId}/view supplier:resource:view + 资源查看范围 当前有效关系
SUP-ADM-049 PUT /admin/supplier/resource-relations/{resourceModule}/{resourceId}/update supplier:resource:manage + 资源编辑范围 新建或改绑后的关系
SUP-ADM-050 POST /admin/supplier/resource-relations/{resourceModule}/{resourceId}/unbind supplier:resource:manage + 资源编辑范围 null

三个路径已经被现有 Gateway /admin/supplier/** 路由覆盖,均要求真实管理员 Token。客户端传入的 X-Admin-Id、X-Admin-Role 不会替代可信身份。

角色与权限

角色 supplier:resource:view supplier:resource:manage 默认能力
ADMIN ✓ ✓ 可查看;仅可维护本人创建、且自身有编辑范围的资源
FINANCE ✓ — 只读关系
SUPER_ADMIN ✓ ✓ 可查看和维护
其他角色 — — 拒绝

这两项权限与供应商主档权限双向隔离:supplier:update 不能单独维护资源关系,supplier:resource:manage 也不会授予供应商主档编辑能力。

支持的资源模块

resourceModule 展示模块 requiredTypeCode 规则
SCENIC 景区管理 固定 SCENIC
RESTAURANT 餐厅管理 固定 RESTAURANT
SUPPLIES 备品管理 默认 SUPPLIES,允许显式类型
SUPPLIES_COMBO 组合配品 固定 SUPPLIES
ACTIVITY 游玩项目管理 必须显式传入
HOTEL 酒店管理 固定 HOTEL
SERVICE 服务管理 默认 SERVICE,允许显式类型
COST_ITEM 额外成本 必须显式传入
STAFF 服务人员管理 必须显式传入
VEHICLE 车队管理-车队管理 固定 FLEET

未知模块返回 395034。资源不存在或已删除返回 395035。VEHICLE 通过 Internal Token 保护的 Fleet 精确摘要接口读取;超时、fallback、非成功、空响应以及 Feign 抛出的任意运行时异常均失败关闭为 395039。

请求与响应

首次绑定或改绑

{
  "supplierId": "1900000000000000001",
  "requiredTypeCode": "SCENIC",
  "remark": "主供应商",
  "expectedCurrentSupplierId": "1900000000000000000",
  "expectedRelationUpdateTime": "2026-08-23 11:20:30",
  "changeReason": "资源供应商调整"
}
  • 首次绑定不传两个 expected* 字段。
  • 已有关系时必须同时传 expectedCurrentSupplierId 与 expectedRelationUpdateTime;缺一返回参数错误,值不匹配返回 395014。
  • 同一供应商、同一要求类型和同一备注的重复请求按业务幂等成功,不更新时间,也不写空审计。

解绑

{
  "expectedCurrentSupplierId": "1900000000000000001",
  "expectedRelationUpdateTime": "2026-08-23 11:20:30",
  "changeReason": "停止合作"
}

三个字段均必填。关系不存在或已解绑返回 395038;版本不一致返回 395014。

关系响应

{
  "code": 200,
  "message": "成功",
  "data": {
    "relationId": "1900000000000000100",
    "supplierId": "1900000000000000001",
    "supplierNo": "SUP1900000000000000001",
    "supplierName": "示例供应商",
    "resourceModule": "SCENIC",
    "moduleName": "景区管理",
    "resourceId": "10001",
    "resourceName": "示例景区",
    "requiredTypeCode": "SCENIC",
    "requiredTypeName": "景区供应商",
    "remark": "主供应商",
    "available": true,
    "unavailableReasons": [],
    "createTime": "2026-08-23 11:20:30",
    "updateTime": "2026-08-23 11:20:30"
  },
  "success": true
}

所有 Snowflake Long 输出为 JSON String;时间格式为 yyyy-MM-dd HH:mm:ss。响应不包含账户、资质附件、密文或跨服务内部字段。updateTime 是并发版本,客户端必须原样回传。

可用性与写入门禁

  • 写入目标供应商必须为 ACTIVE,要求类型必须启用且属于该供应商,全部必备资质必须齐全且未过期。
  • 查询不会因为后续资格变化删除历史关系,而是通过 available=false 和稳定原因列表返回:SUPPLIER_NOT_ACTIVE、REQUIRED_TYPE_INACTIVE、SUPPLIER_TYPE_MISSING、REQUIRED_QUALIFICATION_MISSING、REQUIRED_QUALIFICATION_EXPIRED。
  • 写接口使用请求摘要幂等、资源粒度分布式锁、数据库行锁、预期版本围栏和唯一索引兜底。
  • 绑定、改绑、解绑与 supplier_change_log 同事务;审计失败整笔回滚。改绑保留旧关系软删除历史,并分别为原、新供应商记录安全审计快照。
  • 外部依赖调用在数据库事务外完成;依赖失败、越权、参数错误、版本冲突和资格门禁失败均不产生关系或变更审计写入。

主要错误码

业务码 含义
395014 关系并发版本已变化
395034 不支持的资源模块
395035 资源不存在或已删除
395036 资源已关联其他供应商,应显式改绑
395037 供应商类型不满足资源要求
395038 当前供应商资源关系不存在
395039 字典、权限、资源摘要或 Fleet 等必要依赖暂不可用

统一包络可能以 HTTP 200 承载业务失败,调用方必须检查 code 与 success。

验证证据

  • 合并链:主 PR #6196(9f83cf9c7)、Fleet 异常映射补充 PR #6198(81663f7b6)、版本时间补充 PR #6201(b71cc41c8)。
  • 自动化:Supplier 聚焦测试、Fleet 精确摘要契约、User 权限 migration/权限服务测试、Gateway 路由审计与构建均通过;补充修复分别覆盖 Feign BusinessException 映射和首次响应秒精度版本。
  • 真实 TEST 经 Gateway 覆盖权限矩阵、有效资源关系首次绑定/查询/改绑/解绑、同值幂等、版本冲突、资格门禁、VEHICLE 精确摘要成功链及依赖失败 395039。
  • #6200 复验确认首次 PUT 返回的 updateTime 与立即 GET 一致,并可直接用于解绑;关系和审计副作用按正常接口清理。
  • 临时资源关系、临时角色、临时管理员和对应 Token/权限缓存已清理。两条 HL6195-TEST ACTIVE 供应商主档因状态机禁止 ACTIVE 直接删除、且当时没有安全暂停/归档入口而保留;未执行未授权 DML,残留已在三个关联工单记录。
  • HL 仓库没有 Gitea workflow/status context;远端 PR 合并态、目标分支包含关系、提交和文件清单已复核。

前端接入提示

  • 资源编辑页先调用 SUP-ADM-048 获取当前关系和 updateTime,再决定首次绑定或显式改绑。
  • 改绑和解绑必须使用最近一次 GET/PUT 返回的供应商 ID 与 updateTime;收到 395014 后重新查询,不要覆盖服务端新版本。
  • FINANCE 只展示关系,不显示或调用改绑、解绑动作;服务端仍会独立校验,按钮隐藏不能代替权限。
  • available=false 时展示稳定原因,不应把关系静默当作不存在。
  • 395039 表示必要依赖无法可靠校验,不应降级为成功或在本地伪造资源名称。

撤回

  1. 停止调用三个管理端接口,按 #6200 → #6197 → #6195 的逆序 revert 合并提交并重新构建。
  2. 部署顺序先回退 Resource 消费方,再在确认无消费者后回退 Fleet internal Provider;既有供应商、资源和车辆接口保持运行。
  3. 已产生的 supplier_resource_rel 与 supplier_change_log 历史不做物理删除;需要恢复业务关系时,在代码回退前依据审计通过正常改绑/解绑补偿。
  4. 已应用的 User 权限 migration 不修改、不删除 Flyway 历史。两个权限可作为无消费者兼容数据保留;确需移除时新增更高版本 migration,先删除精确角色绑定,再删除 supplier:resource:view/manage。
  5. 资源锁与幂等键按 TTL 自然过期;紧急处理只清理精确 module/resourceId 和管理员权限缓存,禁止宽泛清 Redis。本链路不使用 MQ,无 MQ 恢复项。
  6. 回退后经 Gateway 验证新接口不可达,原供应商主档、资源查询及 Fleet options 契约不受影响。

关联 / 联系人

链接

联系人

  • 后端负责人: @lc