diff --git a/changelogs-v2/2026-07/42_4803_定制师订单待办-新增接口-管理后台.md b/changelogs-v2/2026-07/42_4803_定制师订单待办-新增接口-管理后台.md new file mode 100644 index 0000000..bf956dc --- /dev/null +++ b/changelogs-v2/2026-07/42_4803_定制师订单待办-新增接口-管理后台.md @@ -0,0 +1,421 @@ +# 定制师订单待办 — 新增接口 — 管理后台 + +> 涉及 PR:#4805 / #4814 / #4819 Issue:#4803 / #4811 / #4817 +> 日期:2026-07-07 责任人:腰苏图 + +--- + +## ① 接口背景 + +为管理后台定制师角色新增「订单待办」功能模块。 +系统在订单关键节点(补全出行人、提交房型需求、提交用车需求、确认行程、退款/取消/终止审核等)自动生成待办,定制师亦可手动创建自定义提醒事项。 +本次共新增 7 个管理端接口,涵盖:分页查询、手动新增/修改/完成/重开/取消,以及手动待办时订单下拉选项。 + +--- + +## ② 变更清单 + +| # | 方法 | 路径 | 名称 | 变更类型 | +|---|------|------|------|----------| +| 1 | GET | `/v3/admin/order-todos/my/page` | 我的待办分页 | ✨ 新增 | +| 2 | POST | `/v3/admin/order-todos/manual` | 手动新增待办 | ✨ 新增 | +| 3 | PUT | `/v3/admin/order-todos/{todoId}` | 修改手动待办 | ✨ 新增 | +| 4 | PUT | `/v3/admin/order-todos/{todoId}/complete` | 完成手动待办 | ✨ 新增 | +| 5 | PUT | `/v3/admin/order-todos/{todoId}/reopen` | 重开手动待办 | ✨ 新增 | +| 6 | DELETE | `/v3/admin/order-todos/{todoId}` | 取消手动待办 | ✨ 新增 | +| 7 | GET | `/v3/admin/order-todos/order-options` | 手动待办订单下拉 | ✨ 新增 | + +--- + +## ③ 接口详情 + +**认证**:所有接口均需管理后台 JWT,从 token 中自动解析当前管理员 ID(`assigneeAdminId`),无需前端传入。 + +**幂等性**: +- 接口 2(手动新增):同一 (adminId, orderId, MANUAL type) 并发写有乐观锁防重(报 581708 冲突让前端重试)。 +- 接口 4/5/6(状态操作):对已是目标状态的待办调用无副作用,返回当前状态。 + +**限流**:无特殊限流,走全局网关限流。 + +**操作范围**:接口 2-6 仅能操作来源为 `MANUAL` 的待办;`SYSTEM` 待办由订单业务流自动管理,前端调接口 2-6 均会返回错误码 581703。 + +--- + +## ④ 入参 + +### 4.1 接口 1:GET /v3/admin/order-todos/my/page(Query 参数) + +继承分页基类字段 `pageNo`(默认 1)和 `pageSize`(默认 10): + +| 字段 | 类型 | 必填 | 说明 | 示例 | +|------|------|------|------|------| +| pageNo | Integer | 否 | 页码,默认 1 | 1 | +| pageSize | Integer | 否 | 每页条数,默认 10 | 20 | +| status | String | 否 | 待办状态,见枚举 TodoStatus | PENDING | +| todoSource | String | 否 | 待办来源,见枚举 TodoSource | MANUAL | +| orderId | Long(字符串) | 否 | 精确匹配订单 ID | "2073707641535696898" | +| fromDate | String | 否 | 待办日期起(含,格式 yyyy-MM-dd) | 2026-07-01 | +| toDate | String | 否 | 待办日期止(含,格式 yyyy-MM-dd) | 2026-07-31 | +| keyword | String | 否 | 模糊搜索:标题 或 订单号 | 护照 | + +**排序固定**:`todoDate asc → sequence asc → createTime desc`,不接受前端自定义排序。 + +### 4.2 接口 2:POST /v3/admin/order-todos/manual(请求体 JSON) + +| 字段 | 类型 | 必填 | 校验 | 说明 | 示例 | +|------|------|------|------|------|------| +| orderId | Long(字符串) | 是 | 非空;须为当前定制师名下订单 | 关联订单 ID | "2073707641535696898" | +| todoLabel | String | 是 | 非空,最多 50 字符 | 待办标题 | "跟进客户护照信息" | +| todoDate | String | 是 | 非空,格式 yyyy-MM-dd | 待办日期 | "2026-07-20" | + +### 4.3 接口 3:PUT /v3/admin/order-todos/{todoId}(路径参数 + 请求体 JSON) + +路径参数:`todoId`(Long,字符串形式) + +| 字段 | 类型 | 必填 | 校验 | 说明 | +|------|------|------|------|------| +| todoLabel | String | 否 | 最多 50 字符;不传则保持原值 | 修改标题 | +| todoDate | String | 否 | 格式 yyyy-MM-dd;不传则保持原值 | 修改日期 | + +> 两个字段均可选,至少传一个有意义(全不传返回原数据不报错)。 + +### 4.4 接口 4:PUT /v3/admin/order-todos/{todoId}/complete + +无请求体。路径参数:`todoId`(Long,字符串形式)。 + +### 4.5 接口 5:PUT /v3/admin/order-todos/{todoId}/reopen + +无请求体。路径参数:`todoId`(Long,字符串形式)。 + +### 4.6 接口 6:DELETE /v3/admin/order-todos/{todoId} + +无请求体。路径参数:`todoId`(Long,字符串形式)。 + +### 4.7 接口 7:GET /v3/admin/order-todos/order-options(Query 参数) + +| 字段 | 类型 | 必填 | 说明 | 示例 | +|------|------|------|------|------| +| keyword | String | 否 | 订单号/团号/产品名 LIKE 模糊搜索 | 草原 | + +不分页,返回当前定制师名下(排除已取消订单)全量,按 orderId 倒序。 + +--- + +## ⑤ 出参字段 + +### 5.1 OrderTodoRespVO(接口 1-5 出参单项) + +| 字段 | 类型 | 说明 | 来源备注 | +|------|------|------|----------| +| todoId | String | 待办 ID(Long 序列化为字符串) | | +| orderId | String | 关联订单 ID(Long 序列化为字符串) | | +| orderNo | String | 订单号,如 HL202607070001 | | +| teamNo | String | 团号(可为 null) | **仅接口 1 分页连表查询有值;接口 2-5 单表转换,该字段恒为 null** | +| productName | String | 产品名称(可为 null) | **仅接口 1 有值** | +| departDate | String | 出发日期 yyyy-MM-dd(可为 null) | **仅接口 1 有值** | +| todoType | String | 待办类型 code,见枚举 TodoType | | +| todoTypeName | String | 待办类型中文名 | | +| todoLabel | String | 标题/描述 | | +| todoSource | String | 来源 code(SYSTEM / MANUAL) | | +| todoSourceName | String | 来源中文名(系统生成 / 手动添加) | | +| todoDate | String | 待办日期 yyyy-MM-dd | | +| actionType | String | 前端跳转动作类型,见枚举 ActionType | | +| status | String | 状态 code,见枚举 TodoStatus | | +| statusName | String | 状态中文名 | | +| assigneeAdminId | String | 指派定制师管理员 ID(Long 序列化为字符串) | | +| completedBy | String | 完成人管理员 ID(未完成时为 null) | | +| completedAt | String | 完成时间(ISO 8601,未完成时为 null) | | +| relatedBizType | String | 关联业务类型(仅系统待办有值,如 REFUND_APPLICATION;手动待办为 null) | | +| relatedBizId | String | 关联业务 ID(Long 序列化为字符串;无时为 null) | | +| createTime | String | 创建时间 ISO 8601 | | + +**重要**:`teamNo` / `productName` / `departDate` 三字段**只有分页接口 1 通过连表查询填充**。接口 2-5 返回的 OrderTodoRespVO 中这三个字段恒为 null。建议前端操作成功后直接重拉分页列表(接口 1),不依赖操作返回值渲染这三个字段。 + +### 5.2 接口 1 响应结构(分页) + +```json +{ + "code": 200, + "data": { + "list": [], + "total": 42 + } +} +``` + +### 5.3 接口 6(DELETE 取消)响应 + +返回 `Result`,data 为 `true` 表示取消成功。 + +### 5.4 OrderTodoOrderOptionVO(接口 7 出参单项) + +| 字段 | 类型 | 说明 | +|------|------|------| +| orderId | String | 订单 ID(Long 序列化为字符串) | +| orderNo | String | 订单号 | +| teamNo | String | 团号(无团期时为 null) | +| productName | String | 产品名称(可为 null) | +| departDate | String | 出发日期 yyyy-MM-dd(可为 null) | + +接口 7 响应结构: + +```json +{ + "code": 200, + "data": [] +} +``` + +--- + +## ⑥ 枚举 / 数据字典 + +### TodoStatus — 待办状态 + +| code | 中文名 | 说明 | +|------|--------|------| +| PENDING | 待处理 | 初始状态 | +| COMPLETED | 已处理 | 手动完成或系统自动关闭 | +| CANCELLED | 已取消 | 仅手动待办可取消(软取消,不物理删除) | + +### TodoSource — 待办来源 + +| code | 中文名 | 说明 | +|------|--------|------| +| SYSTEM | 系统生成 | 由订单业务流自动创建,前端只读 | +| MANUAL | 手动添加 | 定制师手动创建,可增删改 | + +### TodoType — 待办类型 + +| code | 中文名 | 系统自动触发 | 可手动创建 | +|------|--------|----------|-------| +| FILL_TRAVELER | 补全出行人 | 是 | 否 | +| ASSIGN_ROOM | 房型需求 | 是 | 否 | +| ASSIGN_VEHICLE | 用车需求 | 是 | 否 | +| CONFIRM_ORDER | 确认行程 | 是 | 否 | +| PRE_TRIP_REFUND | 出行前退款 | 是 | 否 | +| CANCEL_ORDER | 取消订单 | 是 | 否 | +| TERMINATE_TRIP | 终止行程 | 是 | 否 | +| CONFIRM_CHECKLIST | 确认失败兜底 | 是 | 否 | +| FINANCE_REVIEW | 财务审核 | 预留未启用 | 否 | +| BUY_INSURANCE | 购买保险 | 预留未启用 | 否 | +| SIGN_CONTRACT | 签署合同 | 预留未启用 | 否 | +| MANUAL | 手动待办 | 否 | 是 | + +> `FINANCE_REVIEW` / `BUY_INSURANCE` / `SIGN_CONTRACT` 当前预留未启用,**不会出现在实际待办数据中**。 + +### ActionType — 前端跳转动作(字符串字面量) + +| 值 | 对应待办类型 | 建议跳转 | +|----|-------------|--------| +| info | FILL_TRAVELER | 订单出行人详情页 | +| room | ASSIGN_ROOM | 房型需求模块 | +| vehicle | ASSIGN_VEHICLE | 用车需求模块 | +| confirm | CONFIRM_ORDER | 确认行程操作 | +| refund | PRE_TRIP_REFUND | 退款申请详情 | +| cancel | CANCEL_ORDER | 取消订单操作 | +| terminate | TERMINATE_TRIP | 终止行程操作 | +| manual | MANUAL | 无固定跳转,前端可展示标题或无操作 | + +--- + +## ⑦ 错误码 + +| 错误码 | 中文描述 | 触发场景 | +|--------|---------|--------| +| 581700 | 待办不存在 | todoId 无对应记录 | +| 581701 | 无权操作该待办 | 操作他人的待办 | +| 581702 | 待办必须关联订单 | 内部校验,前端正常调用不触发 | +| 581703 | 系统待办不允许手动完成或重开 | 对 SYSTEM 来源待办调接口 3/4/5/6 | +| 581704 | 待办标题不能为空 | 接口 2 的 todoLabel 为空 | +| 581705 | 待办日期不能为空 | 接口 2 的 todoDate 为空 | +| 581706 | 待办业务事件不支持 | 内部 SYSTEM 同步逻辑,前端不直接触发 | +| 581707 | 仅订单定制师可维护该订单待办 | 接口 2 传入的 orderId 不属于当前管理员名下订单 | +| 581708 | 手动待办创建冲突,请重试 | 并发新增触发乐观锁,前端重试一次即可 | + +--- + +## ⑧ 示例 + +### 8.1 典型成功 — 分页查询我的待办(接口 1) + +请求: + +``` +GET /v3/admin/order-todos/my/page?status=PENDING&pageNo=1&pageSize=10 +Authorization: Bearer +``` + +响应: + +```json +{ + "code": 200, + "data": { + "list": [ + { + "todoId": "2073707641535696900", + "orderId": "2073707641535696898", + "orderNo": "HL202607070001", + "teamNo": "T202607070001", + "productName": "夏季草原行", + "departDate": "2026-07-20", + "todoType": "ASSIGN_ROOM", + "todoTypeName": "房型需求", + "todoLabel": "房型需求 · 待提交", + "todoSource": "SYSTEM", + "todoSourceName": "系统生成", + "todoDate": "2026-07-15", + "actionType": "room", + "status": "PENDING", + "statusName": "待处理", + "assigneeAdminId": "10001", + "completedBy": null, + "completedAt": null, + "relatedBizType": null, + "relatedBizId": null, + "createTime": "2026-07-07T11:00:00" + } + ], + "total": 1 + } +} +``` + +### 8.2 边界情况 — 手动新增待办后 teamNo 等字段为 null(接口 2) + +请求: + +``` +POST /v3/admin/order-todos/manual +Authorization: Bearer +Content-Type: application/json + +{ + "orderId": "2073707641535696898", + "todoLabel": "跟进客户护照信息", + "todoDate": "2026-07-20" +} +``` + +响应(teamNo / productName / departDate 为 null,操作成功后建议重拉分页接口 1 获取完整上下文): + +```json +{ + "code": 200, + "data": { + "todoId": "2073707641535696901", + "orderId": "2073707641535696898", + "orderNo": "HL202607070001", + "teamNo": null, + "productName": null, + "departDate": null, + "todoType": "MANUAL", + "todoTypeName": "手动待办", + "todoLabel": "跟进客户护照信息", + "todoSource": "MANUAL", + "todoSourceName": "手动添加", + "todoDate": "2026-07-20", + "actionType": "manual", + "status": "PENDING", + "statusName": "待处理", + "assigneeAdminId": "10001", + "completedBy": null, + "completedAt": null, + "relatedBizType": null, + "relatedBizId": null, + "createTime": "2026-07-07T14:00:00" + } +} +``` + +### 8.3 业务失败 — 对系统待办调完成接口(接口 4,最小复现) + +请求(todoId 对应 SYSTEM 来源待办): + +``` +PUT /v3/admin/order-todos/2073707641535696900/complete +Authorization: Bearer +``` + +响应: + +```json +{ + "code": 581703, + "msg": "系统待办不允许手动完成或重开" +} +``` + +另一业务失败 — 订单不属于当前定制师(接口 2 传入他人订单 orderId): + +```json +{ + "code": 581707, + "msg": "仅订单定制师可维护该订单待办" +} +``` + +--- + +## ⑨ 业务边界 + +**适用**: +- 当前登录管理员为某订单的指派定制师(`assigneeAdminId` 即当前 admin ID) +- 待办分页(接口 1)只返回属于当前定制师的待办 +- 手动操作(接口 2-6)只能操作当前定制师名下的 MANUAL 来源待办 + +**不适用**: +- 查看全部定制师的待办(暂无此接口,当前版本只支持我的) +- 对系统待办(SYSTEM)做完成/重开/取消/修改操作 +- 删除已取消(CANCELLED)的待办(取消后为软删除,不提供物理删除接口) + +**特殊边界**: +- 接口 7 订单下拉的过滤条件:订单状态非 CANCELLED(注意是订单状态,不是待办状态) +- 系统待办由订单流程自动生灭,FINANCE_REVIEW / BUY_INSURANCE / SIGN_CONTRACT 三类待办预留不会出现 +- 房型/用车需求被打回时系统更新已有待办标题为已打回,待办 ID 不变 + +--- + +## ⑩ 修改前后对比 + +本次全部为新增接口,无修改前状态。 + +--- + +## ⑪ 影响评估 / 回滚 + +全新增接口,对现有接口零影响。如需回滚,停止调用以上 7 个接口即可,无破坏性变更。 + +--- + +## ⑫ 注意事项 + +1. **Long 型 ID 均序列化为字符串**:`todoId` / `orderId` / `assigneeAdminId` / `completedBy` / `relatedBizId` 在 JSON 中均为字符串类型(如 "2073707641535696898"),防止 JS 精度丢失。 + +2. **操作返回值中 teamNo / productName / departDate 恒为 null**:仅分页接口 1 通过连表查询填充这三个字段;接口 2-5 的返回值是单表转换结果。建议前端操作成功后重拉分页列表,不从操作返回值取这三字段。 + +3. **SYSTEM 待办只读**:对 `todoSource === "MANUAL"` 的待办才显示修改/完成/重开/取消按钮,系统待办只展示不操作。 + +4. **分页排序固定**:`todoDate asc → sequence asc → createTime desc`,无需也不支持前端传排序参数。 + +5. **接口 7 订单下拉不分页**:返回当前定制师名下排除已取消订单的全量列表,数量通常不超过数十条。 + +6. **并发新增防抖**:请求发出后禁用提交按钮,收到 581708 时提示用户重试。 + +--- + +## ⑬ 关联 / 联系人 + +| 类型 | 链接 | +|------|------| +| Issue(初始需求) | https://git.1814.love:8443/wx/HL/issues/4803 | +| Issue(列表字段+打回追溯) | https://git.1814.love:8443/wx/HL/issues/4811 | +| Issue(订单下拉选项) | https://git.1814.love:8443/wx/HL/issues/4817 | +| PR #4805(6 个管理接口 + 系统待办落库) | https://git.1814.love:8443/wx/HL/pulls/4805 | +| PR #4814(列表出参补 teamNo/productName/departDate + 打回追溯修复) | https://git.1814.love:8443/wx/HL/pulls/4814 | +| PR #4819(新增 order-options 下拉接口) | https://git.1814.love:8443/wx/HL/pulls/4819 | +| Commit(PR #4805) | https://git.1814.love:8443/wx/HL/commit/405ea69f0a96b1624a0a10f86663f6664c2d283d | +| Commit(PR #4814) | https://git.1814.love:8443/wx/HL/commit/de0c92b12049628c2c3d1c7bc43c01d9afe2fe0f | +| Commit(PR #4819) | https://git.1814.love:8443/wx/HL/commit/8c6ad153d9699e001f058321744a570b2bd60fc6 | +| 后端负责人 | 腰苏图 |