--- schema: "hl-changelog/v2" ticket: "6979" title: "统一供应商暂停状态与拉黑归档流转" consumer: "admin" author: "lc(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "a67bbd79" target_release: "" verified_at: "2026-09-03" status_note: "PR #7007 已合并 dev-v3 并部署 TEST;当前状态统一使用 SUSPENDED,新增恢复合作和解除黑名单接口,前端需按状态矩阵调整菜单。" updated_at: "2026-09-03" base: "dev-v3" --- # 供应商模块:统一暂停状态与拉黑归档流转 > **服务**: `hl-resource-service`(8082) > **Issue**: #6979 > **PR**: #7007 > **影响范围**: 管理后台供应商列表、详情与状态操作菜单 ## ⚠️ 关键变化 - 当前供应商状态不再返回 `FROZEN`,暂停合作统一为 `SUSPENDED`。 - 新增“恢复合作”和“解除黑名单”接口;拉黑只允许从 `SUSPENDED` 发起。 - 归档只允许从 `SUSPENDED` 或 `BLACKLIST` 进入门禁;清账能力未交付时仍返回 `395032`,不会归档。 ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|---|---|---|---|---| | 1 | 分页查询供应商 | GET | `/admin/supplier/items/page` | 响应枚举修改 | 当前状态不再返回 `FROZEN` | | 2 | 有界查询供应商 | GET | `/admin/supplier/items/list` | 响应枚举修改 | 当前状态不再返回 `FROZEN` | | 3 | 查询供应商详情 | GET | `/admin/supplier/items/{supplierId}/basic-info/view` | 响应枚举修改 | 暂停状态统一返回 `SUSPENDED` | | 4 | 暂停合作 | POST | `/admin/supplier/items/{supplierId}/suspend` | 行为修改 | `ACTIVE → SUSPENDED` | | 5 | 恢复合作 | POST | `/admin/supplier/items/{supplierId}/resume` | 新增接口 | `SUSPENDED → ACTIVE` | | 6 | 拉入黑名单 | POST | `/admin/supplier/items/{supplierId}/blacklist` | 行为修改 | 仅允许 `SUSPENDED → BLACKLIST` | | 7 | 解除黑名单 | POST | `/admin/supplier/items/{supplierId}/unblacklist` | 新增接口 | `BLACKLIST → SUSPENDED` | | 8 | 清账归档 | POST | `/admin/supplier/items/{supplierId}/archive` | 行为修改 | 仅 `SUSPENDED/BLACKLIST` 可进入清账门禁 | ## 三、接口详情 ### 1. 分页查询供应商 `GET /admin/supplier/items/page` **VO**: `SupplierPageReqVO / PageResult` #### 使用场景 供应商列表页分页查询,并依据每行 `status` 显示状态菜单。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | page / pageSize | Query | Integer | 否 | 页码 ≥ 1;每页 ≤ 100 | 分页参数 | | status | Query | String | 否 | 当前六状态之一 | 状态筛选 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | records[].status | String | 当前状态;不再返回 `FROZEN` | | records[].updateTime | LocalDateTime | 状态动作的乐观锁版本 | #### 请求示例 ```http GET /admin/supplier/items/page?page=1&pageSize=20&status=SUSPENDED ``` #### 响应示例 ```json {"code":200,"data":{"records":[{"supplierId":"2094672459314745346","status":"SUSPENDED","updateTime":"2026-09-03 08:03:00"}],"total":1,"page":1,"pageSize":20},"success":true} ``` #### 空数据 / 降级响应 无匹配数据返回 `records: []`;本接口无业务降级分支。 #### 错误响应 ```json {"code":401,"message":"缺少有效的 Authorization 头","data":null,"success":false} ``` #### 业务边界 - `status=FROZEN` 不再是合法筛选值;请改用 `SUSPENDED`。 ### 2. 有界查询供应商 `GET /admin/supplier/items/list` **VO**: `SupplierListReqVO / List` #### 使用场景 供应商选择器或短列表查询,并依据 `status` 显示状态菜单。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | status | Query | String | 否 | 当前六状态之一 | 状态筛选 | | limit | Query | Integer | 否 | 1~200,默认 50 | 最大返回数 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | data[].status | String | 当前状态;暂停合作为 `SUSPENDED` | | data[].updateTime | LocalDateTime | 状态动作的乐观锁版本 | #### 请求示例 ```http GET /admin/supplier/items/list?status=BLACKLIST&limit=50 ``` #### 响应示例 ```json {"code":200,"data":[{"supplierId":"2094672459314745346","status":"BLACKLIST","updateTime":"2026-09-03 08:04:00"}],"success":true} ``` #### 空数据 / 降级响应 无匹配数据返回 `data: []`;本接口无业务降级分支。 #### 错误响应 ```json {"code":400,"message":"供应商状态不合法","data":null,"success":false} ``` #### 业务边界 - 当前状态只接受 `DRAFT/VETTING/ACTIVE/SUSPENDED/BLACKLIST/ARCHIVED`。 ### 3. 查询供应商详情 `GET /admin/supplier/items/{supplierId}/basic-info/view` **VO**: `SupplierBasicInfoRespVO` #### 使用场景 进入供应商详情或执行状态动作前,读取当前状态和最新并发版本。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | supplierId | Path | String | 是 | 正整数雪花 ID | 供应商 ID | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | status | String | 当前六状态之一 | | updateTime | LocalDateTime | 后续状态动作原样回传 | #### 请求示例 ```http GET /admin/supplier/items/2094672459314745346/basic-info/view ``` #### 响应示例 ```json {"code":200,"data":{"supplierId":"2094672459314745346","status":"ACTIVE","updateTime":"2026-09-03 08:05:00"},"success":true} ``` #### 空数据 / 降级响应 详情无空对象或降级结果;目标不存在时返回业务错误。 #### 错误响应 ```json {"code":395001,"message":"供应商不存在","data":null,"success":false} ``` #### 业务边界 - 暂停合作的当前主表状态统一返回 `SUSPENDED`,历史记录仍可能展示旧快照 `FROZEN`。 ### 4. 暂停合作 `POST /admin/supplier/items/{supplierId}/suspend` **VO**: `SupplierStatusChangeReqVO / SupplierStatusChangeRespVO` #### 使用场景 在 `ACTIVE` 行点击“暂停合作”。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | supplierId | Path | String | 是 | 正整数雪花 ID | 供应商 ID | | reason | Body | String | 是 | 1~500 字符 | 审计原因 | | expectedUpdateTime | Body | LocalDateTime | 是 | `yyyy-MM-dd HH:mm:ss` | 最近读取的版本 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | status | String | 固定为 `SUSPENDED` | | updateTime | LocalDateTime | 新并发版本 | #### 请求示例 ```json {"reason":"暂停业务合作","expectedUpdateTime":"2026-09-03 08:02:00"} ``` #### 响应示例 ```json {"code":200,"data":{"supplierId":"2094672459314745346","status":"SUSPENDED","updateTime":"2026-09-03 08:03:00"},"success":true} ``` #### 空数据 / 降级响应 写接口无空成功结果,也不提供降级成功。 #### 错误响应 ```json {"code":395005,"message":"当前状态不允许执行该操作","data":null,"success":false} ``` #### 业务边界 - 仅 `ACTIVE` 可调用;成功后继续通知车务停用关联车队。 ### 5. 恢复合作 `POST /admin/supplier/items/{supplierId}/resume` **VO**: `SupplierStatusChangeReqVO / SupplierStatusChangeRespVO` #### 使用场景 在 `SUSPENDED` 行点击“恢复合作”。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | supplierId | Path | String | 是 | 正整数雪花 ID | 供应商 ID | | reason | Body | String | 是 | 1~500 字符 | 审计原因 | | expectedUpdateTime | Body | LocalDateTime | 是 | `yyyy-MM-dd HH:mm:ss` | 最近读取的版本 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | status | String | 固定为 `ACTIVE` | | updateTime | LocalDateTime | 新并发版本 | #### 请求示例 ```json {"reason":"恢复业务合作","expectedUpdateTime":"2026-09-03 08:03:00"} ``` #### 响应示例 ```json {"code":200,"data":{"supplierId":"2094672459314745346","status":"ACTIVE","updateTime":"2026-09-03 08:04:00"},"success":true} ``` #### 空数据 / 降级响应 写接口无空成功结果,也不提供降级成功。 #### 错误响应 ```json {"code":395014,"message":"数据已被他人修改,请刷新后重试","data":null,"success":false} ``` #### 业务边界 - 仅 `SUSPENDED` 可调用;恢复供应商不会自动启用车队。 ### 6. 拉入黑名单 `POST /admin/supplier/items/{supplierId}/blacklist` **VO**: `SupplierStatusChangeReqVO / SupplierStatusChangeRespVO` #### 使用场景 在 `SUSPENDED` 行点击“拉入黑名单”。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | supplierId | Path | String | 是 | 正整数雪花 ID | 供应商 ID | | reason | Body | String | 是 | 1~500 字符 | 审计原因 | | expectedUpdateTime | Body | LocalDateTime | 是 | `yyyy-MM-dd HH:mm:ss` | 最近读取的版本 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | status | String | 固定为 `BLACKLIST` | | updateTime | LocalDateTime | 新并发版本 | #### 请求示例 ```json {"reason":"列入合作黑名单","expectedUpdateTime":"2026-09-03 08:03:00"} ``` #### 响应示例 ```json {"code":200,"data":{"supplierId":"2094672459314745346","status":"BLACKLIST","updateTime":"2026-09-03 08:04:00"},"success":true} ``` #### 空数据 / 降级响应 写接口无空成功结果,也不提供降级成功。 #### 错误响应 ```json {"code":395005,"message":"当前状态不允许执行该操作","data":null,"success":false} ``` #### 业务边界 - 仅 `SUSPENDED` 可调用;`ACTIVE` 直接拉黑返回 `395005`,成功后通知车务停用关联车队。 ### 7. 解除黑名单 `POST /admin/supplier/items/{supplierId}/unblacklist` **VO**: `SupplierStatusChangeReqVO / SupplierStatusChangeRespVO` #### 使用场景 在 `BLACKLIST` 行点击“解除黑名单”。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | supplierId | Path | String | 是 | 正整数雪花 ID | 供应商 ID | | reason | Body | String | 是 | 1~500 字符 | 审计原因 | | expectedUpdateTime | Body | LocalDateTime | 是 | `yyyy-MM-dd HH:mm:ss` | 最近读取的版本 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | status | String | 固定为 `SUSPENDED` | | updateTime | LocalDateTime | 新并发版本 | #### 请求示例 ```json {"reason":"解除合作黑名单","expectedUpdateTime":"2026-09-03 08:04:00"} ``` #### 响应示例 ```json {"code":200,"data":{"supplierId":"2094672459314745346","status":"SUSPENDED","updateTime":"2026-09-03 08:05:00"},"success":true} ``` #### 空数据 / 降级响应 写接口无空成功结果,也不提供降级成功。 #### 错误响应 ```json {"code":395005,"message":"当前状态不允许执行该操作","data":null,"success":false} ``` #### 业务边界 - 仅 `BLACKLIST` 可调用;成功后回到 `SUSPENDED`,不会直接恢复交易或自动启用车队。 ### 8. 清账归档 `POST /admin/supplier/items/{supplierId}/archive` **VO**: `SupplierArchiveRespVO` #### 使用场景 在 `SUSPENDED` 或 `BLACKLIST` 行点击“清账归档”。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | supplierId | Path | String | 是 | 正整数雪花 ID | 供应商 ID;无请求体 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | data | SupplierArchiveRespVO | 当前清账能力未交付,不会返回成功数据 | #### 请求示例 ```http POST /admin/supplier/items/2094672459314745346/archive ``` #### 响应示例 ```json {"code":395032,"message":"暂无法确认财务已清账,不能归档","data":null,"success":false} ``` #### 空数据 / 降级响应 当前固定失败关闭,不提供空数据或降级成功。 #### 错误响应 ```json {"code":395005,"message":"当前状态不允许执行该操作","data":null,"success":false} ``` #### 业务边界 - `ACTIVE` 先返回 `395005`;`SUSPENDED/BLACKLIST` 进入清账门禁后返回 `395032`,两者均零写入。 ## 四、契约约束与正确调用方式 | 当前状态 | 仅显示以下操作 | 正确接口 | |---|---|---| | `ACTIVE` | 暂停合作 | `/suspend` | | `SUSPENDED` | 恢复合作、拉入黑名单、清账归档 | `/resume`、`/blacklist`、`/archive` | | `BLACKLIST` | 解除黑名单、清账归档 | `/unblacklist`、`/archive` | - `expectedUpdateTime` 必须使用最近一次详情或列表返回值;成功后使用响应的新版本刷新页面。 - 统一响应可能由 HTTP 200 承载业务失败,必须同时判断 `code` 和 `success`。 ## 五、数据库行为 - 当前主表中的旧 `FROZEN` 已转换为 `SUSPENDED`;历史审批与变更快照不改写。 - 四个状态接口成功时更新当前状态和版本,并各写一条既有变更审计;失败路径不写主体、审批或审计。 ## 六、边界行为 - 未登录返回业务码 `401`。 - 生命周期写操作要求 `SUPER_ADMIN` 和 `supplier:status:manage`;不满足返回 `395004`。 - `395005` 表示来源状态错误;`395014` 表示版本过期;`395032` 表示清账能力不可用;`100502` 表示 5 秒内重复提交。 - 暂停、拉黑继续通知车务停用关联车队;恢复、解除黑名单不会自动启用车队。 ## 六.5、枚举 / 数据字典 ### `status`(供应商当前生命周期) | 值 | 中文 | 菜单语义 | |---|---|---| | `ACTIVE` | 合作中 | 仅暂停合作 | | `SUSPENDED` | 暂停合作 | 恢复、拉黑、清账归档 | | `BLACKLIST` | 黑名单 | 解除黑名单、清账归档 | `DRAFT/VETTING/ARCHIVED` 保持既有语义;当前接口不再产生或返回主表状态 `FROZEN`。 ## 六.6、修改前后对比 | 场景 | 修改前 | 修改后 | |---|---|---| | 暂停合作 | 当前状态进入 `FROZEN` | 当前状态进入 `SUSPENDED` | | 恢复合作 | 无独立接口 | 新增 `/resume` | | `ACTIVE` 直接拉黑 | 可进入黑名单 | 返回 `395005`,零写入 | | 解除黑名单 | 无独立接口 | 新增 `/unblacklist`,返回 `SUSPENDED` | | 归档来源 | `ACTIVE/BLACKLIST` | `SUSPENDED/BLACKLIST` | ## 六.7、影响评估 - **是否破坏向后兼容**: 是。依赖当前态 `FROZEN` 或 `ACTIVE` 直接拉黑的调用方式必须调整。 - **前端是否必须同步上线**: 是。 - **前端 workaround 清理点**: 删除当前态 `FROZEN` 的筛选、文案与按钮分支。 ## 七、不影响范围 - **仅影响**: 管理后台供应商当前状态展示与生命周期操作。 - **零影响**: 草稿建档、注册审批、收款账户、资源绑定、小程序与历史审批/变更快照展示。 ## 八、测试环境已验证 - `ACTIVE → SUSPENDED → BLACKLIST → SUSPENDED → ACTIVE` 全链路通过,列表与详情状态一致。 - `ACTIVE` 直接拉黑/归档返回 `395005`;两种可归档来源均返回 `395032` 且零写入。 - 乐观锁、重复提交、未认证门禁通过;四次成功动作写四条变更审计,审批记录未增加。 - 部署提交:[`8d38f69d2d6ebd99fb25fb6b0f5dc50ce4cfa1c0`](https://git.1814.love:8443/wx/HL/commit/8d38f69d2d6ebd99fb25fb6b0f5dc50ce4cfa1c0)。 ## 十、相关文档 - [Issue #6979](https://git.1814.love:8443/wx/HL/issues/6979) - [PR #7007](https://git.1814.love:8443/wx/HL/pulls/7007) ## 前端动作与当前状态 - 移除当前态 `FROZEN`,统一映射 `SUSPENDED` 为“暂停合作”。 - 按状态矩阵接入两个新增接口并收紧按钮显隐;`395032` 不得更新页面为已归档。 - **当前状态:待前端接入。** ## 关联 / 联系人 - **Issue**: [#6979](https://git.1814.love:8443/wx/HL/issues/6979) - **PR**: [#7007](https://git.1814.love:8443/wx/HL/pulls/7007) - **后端负责人**: @lc