16 KiB
定制师订单待办 — 新增接口 — 管理后台
涉及 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 响应结构(分页)
{
"code": 200,
"data": {
"list": [],
"total": 42
}
}
5.3 接口 6(DELETE 取消)响应
返回 Result<Boolean>,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 响应结构:
{
"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 <admin-jwt>
响应:
{
"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 <admin-jwt>
Content-Type: application/json
{
"orderId": "2073707641535696898",
"todoLabel": "跟进客户护照信息",
"todoDate": "2026-07-20"
}
响应(teamNo / productName / departDate 为 null,操作成功后建议重拉分页接口 1 获取完整上下文):
{
"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 <admin-jwt>
响应:
{
"code": 581703,
"msg": "系统待办不允许手动完成或重开"
}
另一业务失败 — 订单不属于当前定制师(接口 2 传入他人订单 orderId):
{
"code": 581707,
"msg": "仅订单定制师可维护该订单待办"
}
⑨ 业务边界
适用:
- 当前登录管理员为某订单的指派定制师(
assigneeAdminId即当前 admin ID) - 待办分页(接口 1)只返回属于当前定制师的待办
- 手动操作(接口 2-6)只能操作当前定制师名下的 MANUAL 来源待办
不适用:
- 查看全部定制师的待办(暂无此接口,当前版本只支持我的)
- 对系统待办(SYSTEM)做完成/重开/取消/修改操作
- 删除已取消(CANCELLED)的待办(取消后为软删除,不提供物理删除接口)
特殊边界:
- 接口 7 订单下拉的过滤条件:订单状态非 CANCELLED(注意是订单状态,不是待办状态)
- 系统待办由订单流程自动生灭,FINANCE_REVIEW / BUY_INSURANCE / SIGN_CONTRACT 三类待办预留不会出现
- 房型/用车需求被打回时系统更新已有待办标题为已打回,待办 ID 不变
⑩ 修改前后对比
本次全部为新增接口,无修改前状态。
⑪ 影响评估 / 回滚
全新增接口,对现有接口零影响。如需回滚,停止调用以上 7 个接口即可,无破坏性变更。
⑫ 注意事项
-
Long 型 ID 均序列化为字符串:
todoId/orderId/assigneeAdminId/completedBy/relatedBizId在 JSON 中均为字符串类型(如 "2073707641535696898"),防止 JS 精度丢失。 -
操作返回值中 teamNo / productName / departDate 恒为 null:仅分页接口 1 通过连表查询填充这三个字段;接口 2-5 的返回值是单表转换结果。建议前端操作成功后重拉分页列表,不从操作返回值取这三字段。
-
SYSTEM 待办只读:对
todoSource === "MANUAL"的待办才显示修改/完成/重开/取消按钮,系统待办只展示不操作。 -
分页排序固定:
todoDate asc → sequence asc → createTime desc,无需也不支持前端传排序参数。 -
接口 7 订单下拉不分页:返回当前定制师名下排除已取消订单的全量列表,数量通常不超过数十条。
-
并发新增防抖:请求发出后禁用提交按钮,收到 581708 时提示用户重试。
⑬ 关联 / 联系人
| 类型 | 链接 |
|---|---|
| Issue(初始需求) | wx/HL#4803 |
| Issue(列表字段+打回追溯) | wx/HL#4811 |
| Issue(订单下拉选项) | wx/HL#4817 |
| PR #4805(6 个管理接口 + 系统待办落库) | wx/HL#4805 |
| PR #4814(列表出参补 teamNo/productName/departDate + 打回追溯修复) | wx/HL#4814 |
| PR #4819(新增 order-options 下拉接口) | wx/HL#4819 |
| Commit(PR #4805) | 405ea69f0a |
| Commit(PR #4814) | de0c92b120 |
| Commit(PR #4819) | 8c6ad153d9 |
| 后端负责人 | 腰苏图 |