From 34e243202155bbdb9c2c6122596c39089ef371fc Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Mon, 28 Sep 2026 18:26:31 +0800 Subject: [PATCH] =?UTF-8?q?docs(order-v3):=20=E4=B8=8B=E7=BA=BF=E5=9B=A2?= =?UTF-8?q?=E6=9C=9F=E7=9C=8B=E6=9D=BF=E5=AF=BC=E5=87=BA=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=20GB-ADM-008=20=E4=BA=A4=E6=8E=A5=E4=BB=B6=EF=BC=88#8477?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 物理删除 GET /v3/admin/order/group-batch/export 及其独占 Service 方法、 常量、权限码常量与留痕方法。核单导出 GB-ADM-055 不在范围内,行为不变 (Controller 本单改动 4 行全是注释、非注释行 0)。 已部署 TEST 并经网关实测:该端点恒返回 HTTP 200 + code 400 「参数 groupBatchId 格式错误,请检查后重试」(被同前缀的 /{groupBatchId} 详情模板接住、类型转换失败),不再产生 BATCH_EXPORT 留痕(5746 前后未变)。 hl-ui v2.1(ce469f78)的导出按钮调用链仍在,正文给出删除清单与双向自检 判据:删后 exportGroupBatch 须为 0,且 exportGroupBatchAudit 须仍 ≥7 (后者是子串包含关系,裸 grep 会误删核单导出)。 Refs #8477 Co-Authored-By: Claude Opus 5 (1M context) --- ..._下线团期看板导出接口-删除接口-管理后台.md | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 changelogs-v2/2026-09/28_8477_下线团期看板导出接口-删除接口-管理后台.md diff --git a/changelogs-v2/2026-09/28_8477_下线团期看板导出接口-删除接口-管理后台.md b/changelogs-v2/2026-09/28_8477_下线团期看板导出接口-删除接口-管理后台.md new file mode 100644 index 00000000..85cbfb3a --- /dev/null +++ b/changelogs-v2/2026-09/28_8477_下线团期看板导出接口-删除接口-管理后台.md @@ -0,0 +1,248 @@ +--- +schema: "hl-changelog/v2" +ticket: "8477" +title: "下线团期看板导出接口 GB-ADM-008" +consumer: "admin" +author: "wx(GIT)" +change_type: "删除接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "已部署 TEST 并经 Gateway 实测:GET .../group-batch/export 恒返回 HTTP 200 + code 400「参数 groupBatchId 格式错误,请检查后重试」,不再产生 BATCH_EXPORT 留痕;核单导出 GB-ADM-055 端点可达、行为不变(Controller 非注释改动 0 行)。hl-ui v2.1 的导出按钮调用链仍在,删除时须用词边界匹配 exportGroupBatch,避免误删 exportGroupBatchAudit(核单导出)。" +updated_at: "2026-09-28" +base: "dev-v3" +--- + +# order-v3:下线团期看板导出接口 GB-ADM-008(管理后台) + +> **服务**: hl-order-service-v3 +> **PR**: #8486 +> **Issue**: #8477 +> **日期**: 2026-09-28 +> **影响范围**: 管理后台团期看板导出按钮;核单导出、看板查询/分页/统计接口不受影响 + +--- + +## ⚠️ 关键变化 + +`GET /v3/admin/order/group-batch/export`(团期看板导出 CSV,GB-ADM-008)已删除。请求该路径会被同前缀的详情端点模板 `GET /v3/admin/order/group-batch/{groupBatchId}` 接住,因 `groupBatchId` 路径参数类型转换失败,返回 **HTTP 200 + `code:400`**「参数 groupBatchId 格式错误,请检查后重试」——**不是** 404,也**不会**下载到内容为错误 JSON 的假 CSV 文件。 + +核单导出 `GET /v3/admin/order/group-batch/{groupBatchId}/audit/export`(GB-ADM-055)不受影响,行为完全不变。 + +--- + +## 一、背景 + +`GET /v3/admin/order/group-batch/export`(团期看板导出,GB-ADM-008)于 2026-09-01 随 #6904 / PR #6917 上线,权限码 `group-batch:export`。#8477 将其整体删除,删除范围含 Controller 端点方法、独占的 Service 导出方法(`exportCsv` 看板侧那一份、CSV 组装、`recordExportTrail` 留痕)、导出专用常量、Java 权限码常量 `PERMISSION_EXPORT`、对应单测。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 团期看板导出(GB-ADM-008) | GET | `/v3/admin/order/group-batch/export` | 删除 | 路由已删,被详情端点模板接住,返回 code 400 | + +--- + +## 三、接口详情 + +### 1. 团期看板导出 `GET /v3/admin/order/group-batch/export` + +**VO**: `已删除` + +**状态**:已删除。请求会被同前缀详情端点 `GET /v3/admin/order/group-batch/{groupBatchId}` 接住。 + +#### 使用场景 + +该接口已删除,不再提供团期看板维度的 CSV 导出能力。如需核对单个团期的核单阶段数据,改用 `GET /v3/admin/order/group-batch/{groupBatchId}/audit/export`(GB-ADM-055,见「七、不影响范围」)——两者不是同一份数据,后者仅覆盖已进入核单阶段(`AUDITING`/`CHECKED`)的团期。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| — | — | — | — | — | 已删除 | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|------|------|------| +| — | — | 已删除 | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/export?month=2026-10 HTTP/1.1 +Host: api.test.1814.love +Authorization: Bearer +``` + +#### 响应示例 + +HTTP 状态码 **200**,业务码 400(网关实测原文): + +```json +{"code":400,"message":"参数 groupBatchId 格式错误,请检查后重试","data":null,"traceId":null,"success":false} +``` + +#### 空数据 / 降级响应 + +不适用。路由已删除,无论携带何种查询参数(含 `month`、`opsStage` 等前端实际使用的筛选条件组合),均返回上方同一响应;查询参数不参与路径匹配,实测 `?month=2026-10&opsStage=CONFIGURE` 与不带 `opsStage` 时逐字节相同。 + +#### 错误响应 + +```json +{"code":400,"message":"参数 groupBatchId 格式错误,请检查后重试","data":null,"traceId":null,"success":false} +``` + +#### 业务边界 + +- 路由已删除,任意请求都会被同前缀的详情端点模板 `GET /v3/admin/order/group-batch/{groupBatchId}` 接住,`groupBatchId` 路径参数类型转换失败由 `GlobalExceptionHandler#handleTypeMismatch` 处理(该处理器标注 `@ResponseStatus(OK)`),故 HTTP 状态码恒为 200,只能靠 `code` 字段判断失败。 +- 与 #8414 那份交接件里的 404 不是同一条分支:#8414 下线的三个端点前缀下没有能接住它们的单段路径模板,落到 404 兜底;本接口前缀下存在 `/{groupBatchId}` 这个模板,走的是类型转换失败分支。差别在路由结构,不在兜底机制。 +- 请求不会到达原 Controller 方法体,不再产生 `BATCH_EXPORT` 审计流水:实测 `group_batch_status_log` 表 `event_type='BATCH_EXPORT'` 计数请求前后均为 `5746`,未变化。 +- 前端若以 `responseType: 'blob'` 发起该请求(hl-ui 现状),会命中 blob 解包分支后转为业务错误弹窗,**不会**下载到内容为错误 JSON 的假 CSV 文件,也**不会**提示「导出成功」——见下方「过渡期用户实际会看到什么」。 + +--- + +## 四、契约约束与正确调用方式 + +### ✅ 正确 / ❌ 已下线 调用对照 + +| 场景 | 改前 | 改后 | +|------|------|------| +| 导出团期看板 CSV(任意团期、任意运营阶段) | `GET /v3/admin/order/group-batch/export?month=...` 正常返回 CSV | 路由已删除,无替代接口;该导出能力整体下线 | +| 导出单个团期的核单阶段数据 | `GET /v3/admin/order/group-batch/{groupBatchId}/audit/export` | 不变,团期须处于 `AUDITING`/`CHECKED` 阶段,否则报业务码 `589567` | + +### 过渡期用户实际会看到什么(`hl-ui@ce469f78` 逐段实证) + +mmg 删除调用前,用户点击「导出」按钮后的完整链路: + +1. `src/api/orderV2GroupBatch.js:302` 的 `exportGroupBatch` 以 `responseType: 'blob'` 发起请求; +2. 后端返回 HTTP 200 + `Content-Type: application/json;charset=UTF-8` + 上表错误 JSON; +3. `src/utils/request.js:401-403` 命中 `responseType==='blob'` 且 blob 的 `type` 含 `application/json`,进入解包分支; +4. `request.js:404-412` 对 blob 执行 `text()` + `JSON.parse` 成功,取出 `code=400`; +5. `request.js:420-431` 判断非 SUCCESS,构造 `blobErr` 并调用 `reportError(...)`,置 `blobErr.__handled = true`; +6. `src/utils/errorBus.js:109` 的 `reportError` 内部执行 `message.error(display)`,`display` 即后端 `message` 原文; +7. `batch/index.vue:562` 的 `catch` 因 `e.__handled` 已为 `true`,不再重复弹「导出失败,请收窄筛选后重试」。 + +**结论:失效是响亮的,不是静默的。** 用户点「导出」看到一条红色 toast,文案是后端原文「参数 groupBatchId 格式错误,请检查后重试」。**不会**下载到内容是错误 JSON 的假 CSV 文件,**不会**提示「导出成功」——`request.js` 的 blob 解包分支在 `downloadFile` 之前就把响应转成了 `reject`。 + +⚠️ 但这句提示对使用者是**误导**的:他没有输入任何 `groupBatchId`,提示却让他去检查 `groupBatchId` 的格式。这正是需要尽快删除按钮的原因——不是会丢数据,而是会把人引向一个不存在的排查方向。 + +### 给 mmg 的删除范围 + +hl-ui `origin/v2.1`(HEAD `ce469f78`,2026-09-28 16:45:18)里调用链完整仍在: + +| 位置 | 内容 | +|---|---| +| `src/views/order-v2/batch/index.vue:29` | `@click="onExport"`(导出按钮仍挂在模板上,可达) | +| `src/views/order-v2/batch/index.vue:284` | `import { exportGroupBatch } from '@/api/orderV2GroupBatch'` | +| `src/views/order-v2/batch/index.vue:541` | `async function onExport()`,内部 `await exportGroupBatch({...})` | +| `src/api/orderV2GroupBatch.js:302` | `export function exportGroupBatch(params, config = {})` | +| `src/api/orderV2GroupBatch.js:303` | `` http.get(`${BASE}/export`, params, ...) ``,`BASE = '/v3/admin/order/group-batch'` | +| `src/api/__tests__/orderV2GroupBatch.spec.js:9,121` | 该函数的单测 | +| `src/views/order-v2/batch/__tests__/index.spec.js:12,35,267,270` | 页面侧 mock 与用例 | + +请删除上述按钮、函数与对应测试。 + +🔴 **删除时必须用词边界锚定**:`exportGroupBatchAudit`(核单导出,**不能删**)包含 `exportGroupBatch` 这个子串,裸 `grep exportGroupBatch` 会把核单导出一起捞出来(实测:裸 grep 命中 7 个文件;按标识符整体分组是 `exportGroupBatch` 11 处、`exportGroupBatchAudit` 8 处,两个不同符号)。删除范围请用: + +``` +git grep -nE '\bexportGroupBatch\b' -- src +``` + +**自检判据(双向,缺一不可)**: + +- 删完后 `git grep -nE '\bexportGroupBatch\b' -- src` 命中应降到 0(或只剩下面这处注释引用); +- **同时** `git grep -nE '\bexportGroupBatchAudit\b' -- src` 必须仍 ≥ 7 处 —— 只看第一条的话,「两个函数都被删了」同样得 0,第二条才是防误删核单导出的那一半。 + +`src/api/order-v3/groupBatchAudit.js:235` 的注释写着「写法照 GB-ADM-008 exportGroupBatch 先例」;`exportGroupBatch` 删除后这句成了悬空引用,建议同批改写(不改不影响功能)。 + +2026-09-28 15:30 已推送过一份前端交接件(`hl-api-changelog@423be99`),要求删除该导出按钮;本篇是这条要求的完整技术支撑材料,请对照上面的删除范围与自检判据执行。 + +--- + +## 五、数据库行为 + +无 DDL、无 Flyway 迁移。 + +- 表 `group_batch_status_log`:删除后的请求不会到达原 Controller 方法体,不再新增 `event_type='BATCH_EXPORT'` 的流水(实测:请求前后 `COUNT(*) WHERE event_type='BATCH_EXPORT'` 均为 `5746`)。存量的 `BATCH_EXPORT` 流水不受影响,仍可正常读取。 +- 枚举 `GroupBatchLogEventType.BATCH_EXPORT` **保留未删**:`GroupBatchStatusLogService#eventTypeLabel` 遍历 `values()`,未命中的值会返回 `null` 标签;若把枚举一并删掉,会让库里存量的 `BATCH_EXPORT` 流水标签退化为 `null`。即新请求不再产生该类型流水,但历史流水的标签展示不受影响。 +- 权限码 `group-batch:export`:Java 常量 `PERMISSION_EXPORT` 已随端点一起删除(不再被任何端点引用),但权限码字符串本身及其在数据库中的授权行按定案保留,未新增回迁移清理,不影响其他菜单/角色的权限读取。 + +--- + +## 六、边界行为 + +| 场景 | 行为 | +|---|---| +| 调用已删路径 `GET /v3/admin/order/group-batch/export`(任意查询参数,含 `month`、`opsStage`) | HTTP 200 + `code:400`「参数 groupBatchId 格式错误,请检查后重试」;`Content-Type` 为 `application/json;charset=UTF-8`,无 `Content-Disposition` | +| 前端以 `responseType:'blob'` 发起该请求(hl-ui 现状) | blob 解包分支识别出 JSON 错误体后转为 `reject`,前端统一错误总线弹出红色 toast,文案即后端 `message` 原文;不下载文件、不出现「导出成功」提示 | +| 同前缀其余接口(`summary`、分页列表、核单导出等) | 不变 | + +## 六.6、修改前后对比 + +### 行为级对比 + +| 行为 | 改前 | 改后 | +|------|------|------| +| `GET /v3/admin/order/group-batch/export` | 返回团期看板 CSV 文件(`Content-Type: text/csv`),并写入 `BATCH_EXPORT` 审计流水 | 被 `GET .../group-batch/{groupBatchId}` 详情端点模板接住,返回 HTTP 200 + `code:400`「参数 groupBatchId 格式错误」,不写入任何流水 | +| `GroupBatchAuditController.java` 注释 | 引用「写法同 GroupBatchBoardStatsController#export」 | 已改写为不引用已删方法(原方法已删,避免悬空引用);运行时行为逐字节不变(本单改动 4 行全是注释,非注释行 0) | +| `EXPORT_MAX_ROWS` 常量归属 | 定义在 `GroupBatchBoardStatsService`,被核单导出跨类引用 | 迁入 `GroupBatchAuditService` 自身(看板导出下线后只剩核单一个使用方),阈值仍是 `2000`,比较逻辑不变 | + +## 六.7、影响评估 + +- **是否破坏向后兼容**:是——`GET /v3/admin/order/group-batch/export` 不再可用;核单导出 GB-ADM-055 不受影响。 +- **前端是否必须同步上线**:是。hl-ui `v2.1` 分支(HEAD `ce469f78`)的导出按钮、`exportGroupBatch` 函数及其测试调用链仍在,需按「四、契约约束与正确调用方式」中「给 mmg 的删除范围」清单删除,并用词边界匹配自检,避免误删 `exportGroupBatchAudit`(核单导出)。 +- **前端 workaround 清理点**:无——该接口原本没有前端侧特殊兼容逻辑,直接删除调用即可。 +- **数据影响**:无 DDL/Flyway;存量 `BATCH_EXPORT` 流水与其枚举标签保留可读;权限码 `group-batch:export` 及其授权行保留不清理。 + +--- + +## 七、不影响范围 + +- `GET /v3/admin/order/group-batch/{groupBatchId}/audit/export`(核单导出,GB-ADM-055):行为不变。**代码侧证据**——`GroupBatchAuditController.java` 本单改动 4 行全是注释(非注释行 0),运行时逐字节不变;`GroupBatchAuditService.java` 仅将 `EXPORT_MAX_ROWS=2000` 常量从 `GroupBatchBoardStatsService` 迁入本类并改指向,阈值与比较逻辑不变。**实测**该端点仍可达、业务前置校验正常执行(`GET .../2101018930993635329/audit/export` → HTTP 200,`code:589567`「该团期尚未进入整团核单:请先打开核单面板生成核算草稿后再导出」)。⚠️ 这条实测只证到「端点在、前置校验正常执行」,**没有**覆盖 CSV 成功路径——测试库当前 12 条团期批次无一处于 `AUDITING`/`CHECKED` 阶段(`summary` 也显示 `AUDITING:0, CHECKED:0`),按规则不为此单独造数。核单导出行为不变的主证据是上面的代码侧比对,这条实测只是旁证,不要理解为「核单导出已完整验证」。 +- `GET /v3/admin/order/group-batch/summary`、`GET /v3/admin/order/group-batch`(看板统计、分页列表):不变,实测均 HTTP 200 + `code:200` 正常返回数据(`summary` 的 `data.total=2`,分页列表 `records` 有真实数据)。 +- 权限码 `group-batch:export` 及其角色授权行:不变(数据库侧未清理)。 +- 网关配置:无路由改动。 + +--- + +## 八、测试环境已验证 + +部署:TEST `hl-order-service-v3` `0b08a5a6d`(2026-09-28 17:53:49 部署,deploy-status COMMIT 与之一致,BEHIND=0,两实例 Nacos healthy)。网关 `http://192.168.100.236:8080`,账号 `ha_r1_ad`(ADMIN,测试专用账号)。 + +| # | 场景 | 实测结果 | +|---|---|---| +| 1 | `GET /v3/admin/order/group-batch/export?month=2026-10` | HTTP 200,`Content-Type: application/json;charset=UTF-8`(无 `Content-Disposition`),`{"code":400,"message":"参数 groupBatchId 格式错误,请检查后重试","data":null,"traceId":null,"success":false}` | +| 2 | 同上,带前端真实参数组合 `?month=2026-10&opsStage=CONFIGURE` | 与上一行逐字节相同(查询参数不参与路径匹配) | +| 3 | 留痕表 `SELECT COUNT(*) FROM group_batch_status_log WHERE event_type='BATCH_EXPORT'` | 请求前 `5746`,两次请求后仍 `5746` | +| 4 | 阳性对照 `GET /v3/admin/order/group-batch/summary?month=2026-10` | HTTP 200,`code:200`,`data.total=2` | +| 5 | 阳性对照 `GET /v3/admin/order/group-batch?month=2026-10&pageNo=1&pageSize=5` | HTTP 200,`code:200`,`records` 有真实数据 | +| 6 | 核单导出 `GET /v3/admin/order/group-batch/2101018930993635329/audit/export` | HTTP 200,`{"code":589567,"message":"该团期尚未进入整团核单:请先打开核单面板生成核算草稿后再导出",...}`(端点可达、前置校验正常;测试库无 AUDITING/CHECKED 团期,未覆盖 CSV 成功路径) | +| 7 | 测试服前端产物核对 | `/var/www/hl-admin/index.html` 等文件 mtime `2026-09-28 16:51:35`,对应 `hl-ui@ce469f78`(提交时刻 16:45:18,产物晚 6 分 17 秒);该提交里导出按钮与调用链仍在 | + +精确测试:`mvn -o -pl hl-order-service-v3 -am test -Dtest='<13 个类>'` → **Tests run: 181, Failures: 0, Errors: 0, Skipped: 0**,BUILD SUCCESS,逐类点名核对本轮新产出报告文件 13/13;含门禁 `RedLineArchTest`(12)、`MapperBoundaryArchTest`(27)、`GroupBatchAdminWriteEndpointPermissionArchTest`(2)、`TeamNoResponseFieldGateTest`(9)、`TransactionalRemoteCallArchTest`(2) 全绿。本单只触及 1 个模块(`hl-order-service-v3`),按 CODE_RULES §12.0a 走精确测试档,未跑全量。 + +--- + +## 十、相关文档 + +- 关联 Issue: [wx/HL#8477](https://git.1814.love/wx/HL/issues/8477) +- 关联 PR: [wx/HL#8486](https://git.1814.love/wx/HL/pulls/8486) + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#8477](https://git.1814.love/wx/HL/issues/8477) +- **PR**: [#8486](https://git.1814.love/wx/HL/pulls/8486) +- **Merge commit**: [0b08a5a6d](https://git.1814.love/wx/HL/commit/0b08a5a6d) + +### 联系人 + +- **后端负责人**: @wx