diff --git a/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md b/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md index aadac21..e11d75c 100644 --- a/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md +++ b/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md @@ -86,8 +86,8 @@ | `id` | String | 订单主键 | | `orderNo` | String | 订单号,格式 `HL{yyyyMMddHHmmss}{3 位序号}` | | `displayOrderNo` | String | 展示订单号 = `orderNo + teamNo`;`teamNo` 为空时等同 `orderNo` | -| `orderStatus` | String | 创单后固定 `待支付`(枚举见 §6.2) | -| `flowStatus` | String | 创单后固定 `待支付订金`(枚举见 §6.3) | +| `orderStatus` | String | 创单后固定 `PENDING_PAY`(枚举见 §6.2) | +| `flowStatus` | String | 创单后固定 `AWAITING_DEPOSIT`(枚举见 §6.3) | | `consultantId` | String | 实际绑定的定制师 ID | | `consultantSource` | String | 定制师来源(枚举见 §6.4) | | `tags` | List\ | 标签列表(含入参 tags + 系统自动标签) | @@ -164,8 +164,8 @@ Content-Type: application/json "id": "60123456789012", "orderNo": "HL20260518220000001", "displayOrderNo": "HL20260518220000001", - "orderStatus": "待支付", - "flowStatus": "待支付订金", + "orderStatus": "PENDING_PAY", + "flowStatus": "AWAITING_DEPOSIT", "consultantId": "50001234567890", "consultantSource": "DEFAULT_ASSIGNED", "tags": ["VIP 客户", "含儿童"], @@ -209,8 +209,8 @@ Content-Type: application/json |------|------|:----:|------| | `page` | Integer | ❌ | 页码,默认 1 | | `pageSize` | Integer | ❌ | 每页条数,默认 10 | -| `orderStatus` | String | ❌ | 粗状态过滤(多值用逗号) | -| `flowStatus` | String | ❌ | 细状态过滤 | +| `orderStatus` | String | ❌ | 粗状态过滤(传英文枚举值,多值用逗号,见 §6.2) | +| `flowStatus` | String | ❌ | 细状态过滤(传英文枚举值,见 §6.3) | | `tagNames` | List\ | ❌ | 按标签过滤(多标签为 AND) | | `keyword` | String | ❌ | 关键字(LIKE 团号 / 客户姓名 / 产品名 / 订单号 任一) | | `departureDateFrom` | LocalDate | ❌ | 出发日期范围起始 | @@ -261,7 +261,7 @@ Content-Type: application/json **典型 - 请求**: ```http -GET /v3/admin/order?page=1&pageSize=10&orderStatus=待出行&tagNames=VIP%20%E5%AE%A2%E6%88%B7 +GET /v3/admin/order?page=1&pageSize=10&orderStatus=PENDING_DEPARTURE&tagNames=VIP%20%E5%AE%A2%E6%88%B7 Authorization: Bearer {admin_jwt} ``` @@ -284,8 +284,8 @@ Authorization: Bearer {admin_jwt} "peopleSummary": "2 大 1 小", "departureDate": "2026-06-01", "tripDays": 3, - "orderStatus": "待出行", - "flowStatus": "待出行", + "orderStatus": "PENDING_DEPARTURE", + "flowStatus": "CONFIRMED_PENDING_DEPARTURE", "totalAmount": 8580.00, "paidAmount": 8580.00, "balanceAmount": 0.00, @@ -339,18 +339,25 @@ Authorization: Bearer {admin_jwt} | `departureDate` / `returnDate` | LocalDate | 出发日 / 返团日 | | `tripDays` / `tripNights` | Integer | 行程天数 / 晚数 | | `adultCount` / `childCount` / `youngChildCount` / `babyCount` | Integer | 4 类人数 | -| `customerName` / `customerPhone` | String | 客户姓名 / 手机(admin 明文) | +| `customerName` | String | 客户姓名 | +| `customerPhoneMasked` | String | 客户手机(admin 也脱敏,如 138****2046) | | `consultantName` | String | 定制师姓名 | | `confirmedAt` | LocalDateTime? | 确认锁单时间 | -| `exceptionBadges` | Object | 异常态横条 9 类标识(见下方) | -| `progressStepper` | Object | 步骤进度条(见下方) | +| `exceptionBadges` | Map | 异常态横条 9 类标识(见下方)⚠️ 运行时**暂返 null**,OrderInfoConverter 派生逻辑待 Issue 接通子表后实现 | +| `progressStepper` | Object | 步骤进度条(见下方)⚠️ 运行时**暂返 null**,OrderInfoConverter 派生逻辑待 Issue 接通子表后实现 | +| `contractStatus` | String? | [Tab 状态] 合同状态枚举:`NONE/GENERATING/GENERATED/SIGNED/VOIDED/RESIGNING`,直接读主表 contract_status | +| `insuranceStatus` | String? | [Tab 状态] 保险状态枚举:`NONE/ISSUING/ISSUED/CANCELLED/FAILED`,直接读主表 insurance_status | +| `refundStatus` | String | [Tab 状态] 退款汇总状态枚举:`NONE/PROCESSING/COMPLETED`(派生,见 OrderMainRefundStatus) | +| `hasRefund` | Boolean | [Tab 状态] 是否存在退款记录(refundedAmount > 0) | +| `hasServiceStandard` | Boolean | [Tab 状态] 是否存在服务标准快照(EXISTS order_product_snapshot) | +| `hasFinanceDetail` | Boolean | [Tab 状态] 是否有财务明细(discountAmount > 0 OR surchargeAmount > 0,派生无 SQL) | **`exceptionBadges`** 9 类布尔字段(全 false 表示无异常):`contractFail` / `insuranceFail` / `refundAbnormal` / `grabTimeout` / `hotelPending` / `vehiclePending` / `travelerIncomplete` / `longUnpaid` / `awaitingCustomerConfirm` **`progressStepper`**:`currentStage` (String) + `nodes` 数组,每节点 `{key, label, status, subItems?}` - 节点 key 枚举:`INFO_COMPLETE` / `ASSIGN_PARALLEL` / `CONFIRM` / `DEPARTED` / `RETURNED` / `REVIEW` / `SETTLED` -- 节点 status:`DONE` / `ACTIVE` / `PENDING` -- `ASSIGN_PARALLEL` 含 `subItems`:`HOTEL` / `VEHICLE` / `LEADER` / `PHOTOGRAPHER` 子项 +- 节点 status:`DONE` / `ACTIVE` / `PENDING` / `NOT_APPLICABLE` +- `ASSIGN_PARALLEL` 含 `subItems`:`HOTEL` / `VEHICLE` / `LEADER` / `PHOTOGRAPHER` 子项,每子项 {key, label, subStatus, applicable};subStatus 枚举同节点 status:DONE / ACTIVE / PENDING / NOT_APPLICABLE `TagVO`:`name` / `type`(枚举见 §6.15) / `color` @@ -399,8 +406,8 @@ Authorization: Bearer {admin_jwt} "displayOrderNo": "HL20260510143025001-T20260601A", "productName": "长白山天池3日深度游", "tierName": "经典档", - "orderStatus": "待出行", - "flowStatus": "待出行", + "orderStatus": "PENDING_DEPARTURE", + "flowStatus": "CONFIRMED_PENDING_DEPARTURE", "totalAmount": 8580.00, "paidAmount": 8580.00, "balanceAmount": 0.00, @@ -413,7 +420,7 @@ Authorization: Bearer {admin_jwt} "youngChildCount": 0, "babyCount": 0, "customerName": "张三", - "customerPhone": "13800002046", + "customerPhoneMasked": "138****2046", "consultantName": "李定制", "confirmedAt": "2026-05-12T10:25:00", "exceptionBadges": { @@ -461,7 +468,7 @@ Authorization: Bearer {admin_jwt} "emergencyPhone": "13900008888", "roomGroupNo": 1, "profileStatus": "COMPLETED", - "transportPlanIds": ["80012345"] + "transportPlanIds": ["80012345678901234"] } ], "customerRemark": "希望住朝阳房", @@ -1046,7 +1053,7 @@ Content-Type: application/json #### 业务边界 -- ✅ **适用**:订单粗状态 ∈ {待支付, 待完善, 定制中, 已确认, 待出行} +- ✅ **适用**:订单粗状态 ∈ {PENDING_PAY, PENDING_COMPLETE, CUSTOMIZING, PENDING_DEPARTURE}(注:v3 状态机已删除「已确认」,由 CONFIRM event 直接迁到 PENDING_DEPARTURE) - ❌ **拒绝**:已取消 / 已完成 / 退款中 → `581050` - ⚠️ **`daysToDeparture` 负数**:已过出发日,前端应引导走 §3.13 出行中取消(on-trip)而非本接口预览 @@ -1238,7 +1245,7 @@ Content-Type: application/json | 字段 | 类型 | 必填 | 说明 | 校验规则 | |------|------|:----:|------|----------| -| `eventCode` | String | ✅ | 状态机事件代码(枚举见 §6.17) | `@NotBlank` | +| `eventCode` | String | ✅ | 状态机事件代码,9 个:PAY_DEPOSIT / PAY_FULL / CANCEL / CONFIRM / INITIATE_REFUND / SET_PENDING_BALANCE / SET_PENDING_DEPARTURE / DEPART / FINISH(含义见 §6.17) | `@NotBlank` | | `reason` | String | ❌ | 操作原因(按 event 强制要求时必填) | — | | `payload` | Map\ | ❌ | 事件相关额外数据(不同 event 含义不同) | — | @@ -1293,10 +1300,10 @@ Content-Type: application/json "code": 200, "data": { "success": true, - "oldStatus": "定制中", - "newStatus": "待出行", - "oldFlowStatus": "待确认", - "newFlowStatus": "待出行", + "oldStatus": "CUSTOMIZING", + "newStatus": "PENDING_DEPARTURE", + "oldFlowStatus": "PENDING_CONFIRM", + "newFlowStatus": "CONFIRMED_PENDING_DEPARTURE", "triggeredEvents": ["ASYNC_CONTRACT_GENERATE", "ASYNC_INSURANCE_ISSUE"] }, "msg": "success" @@ -1476,47 +1483,58 @@ Authorization: Bearer {admin_jwt} **使用字段**:§3.1 出参 / §3.2 出参 / §3.3 main / §3.2 入参过滤 -| 值 | 说明 | -|----|------| -| `待支付` | 创单后默认 | -| `待完善` | 订金到账后进入 | -| `定制中` | 出行人 + 房车齐后 | -| `已确认` | — | -| `出行中` | — | -| `已完成` | — | -| `已取消` | — | +> 后端 enum:`com.hulalv.order.core.enums.OrderStatus`,共 10 个值。**API 传/返均为英文枚举值(DB 存什么前端拿什么,前端自己映射中文标签)**。 + +| 值 | 中文标签 | 说明 | +|----|------|------| +| `PENDING_PAY` | 待支付 | 创单后默认 | +| `PENDING_COMPLETE` | 待完善 | 订金到账后进入 | +| `CUSTOMIZING` | 定制中 | 出行人 + 房车齐前 | +| `PENDING_DEPARTURE` | 待出行 | 确认锁单后 | +| `PENDING_BALANCE` | 待付尾款 | 切到「待支付尾款」细状态时归此粗态(状态机粗态目标) | +| `TRAVELLING` | 出行中 | 已发车 | +| `REVIEWING` | 核单中 | 出行结束待财务核算 | +| `SETTLED` | 已结算 | 财务核算完成 | +| `REFUNDING` | 退款中 | 退款流程进行中(状态机粗态目标) | +| `CANCELLED` | 已取消 | — | ### 6.3 flowStatus(订单细状态) **使用字段**:§3.1 出参 / §3.2 出参 / §3.3 main / §3.2 入参过滤 -| 值 | 说明 | -|----|------| -| `待支付订金` | 创单后默认细状态 | -| `待支付尾款` | — | -| `待补全信息` | 订金到账后 | -| `待提交房型` | — | -| `待抢房` | — | -| `配房中` | — | -| `待提交用车` | — | -| `车控处理中` | — | -| `待确认` | 房车齐后 | -| `待出行` | 确认锁单后 | -| `出行中` | — | -| `已完成` | — | -| `已取消` | — | +> 后端 enum:`com.hulalv.order.core.enums.OrderFlowStatus`,共 13 个值。flow_status 列只承载流程细节,不喂状态机;粗态见 §6.2。 -> 完整 flowStatus 枚举见订单状态机文档(§1C 推送时补全)。 +| 值 | 中文标签 | 说明 | +|----|------|------| +| `AWAITING_DEPOSIT` | 待支付订金 | 创单默认细状态 | +| `DEPOSIT_PAID_PENDING_CONFIRM` | 已付订金待确认 | — | +| `FULLY_PAID_PENDING_CONFIRM` | 已全款待确认 | — | +| `PENDING_CONFIRM` | 待确认 | — | +| `CONFIRMED_PENDING_HOTEL` | 已确认配房中 | — | +| `CONFIRMED_PENDING_VEHICLE` | 已确认配车中 | — | +| `CONFIRMED_PENDING_DEPARTURE` | 已确认待出行 | 确认锁单后默认细状态 | +| `DEPOSIT_PAID` | 已付订金 | — | +| `FULLY_PAID` | 已全款 | — | +| `REFUNDED` | 已退款 | — | +| `COMPLETED` | 已完成 | — | +| `TRAVELER_INCOMPLETE` | 出行人待完善 | — | +| `CANCELLED_BEFORE_PAY` | 未付款取消 | 取消时未支付任何金额走此值 | ### 6.4 consultantSource(定制师分配来源) **使用字段**:§3.1 出参 / §3.3 main +> 该字段为字符串而非强枚举类:admin 端硬编码 `MANUAL`;C 端分享下单硬编码 `SHARED`;C 端兜底默认定制师时透传 hl-user-service 派生值(如 `DEFAULT_ASSIGNED` / `ROUND_ROBIN`,由 user-service 决定)。 + | 值 | 说明 | |----|------| -| `DEFAULT_ASSIGNED` | 系统默认分配(轮询) | -| `LINK_BOUND` | 链接绑定(客户扫定制师专属码) | -| `MANUAL` | 手动指定 | +| `MANUAL` | admin 端代下单(JWT adminId 即定制师) | +| `SHARED` | C 端客户扫定制师专属分享码下单 | +| `DEFAULT_ASSIGNED` | C 端兜底:hl-user-service 派发默认定制师 | +| `ROUND_ROBIN` | C 端兜底:hl-user-service 轮询派发(未来扩展) | +| `LINK_BOUND` | (DB comment 保留,当前代码路径未实际写入) | + +> ⚠️ 因 user-service 可能新增 source 值,前端**严禁**对该字段穷举判断;展示时未知值兜底为 `MANUAL` 的中文标签即可。 ### 6.5 paymentMode(支付模式) @@ -1646,6 +1664,8 @@ Authorization: Bearer {admin_jwt} **使用字段**:§3.14 入参 `eventCode` +> 后端 enum:`com.hulalv.order.core.enums.OrderEvent`,共 9 个值。状态机由 `OrderStateMachineConfig` 16 条 transition 规则驱动。 + | 值 | 说明 | |----|------| | `PAY_DEPOSIT` | 客户支付订金 | diff --git a/changelogs-v2/2026-05/18_§2_traveler模块-新增接口-管理后台.md b/changelogs-v2/2026-05/18_§2_traveler模块-新增接口-管理后台.md index f45216d..d32e50c 100644 --- a/changelogs-v2/2026-05/18_§2_traveler模块-新增接口-管理后台.md +++ b/changelogs-v2/2026-05/18_§2_traveler模块-新增接口-管理后台.md @@ -69,7 +69,7 @@ `id` (path, Long) — 订单 ID -#### 出参(`Result>`,每条 17 字段) +#### 出参(`Result>`,每条 16 字段) | 字段 | 类型 | 说明 | |------|------|------| @@ -90,6 +90,8 @@ | `profileStatus` | String | 枚举见 §6.4(PENDING / COMPLETED) | | `transportPlanIds` | List\ | 关联的大交通批次 ID 列表 | +> ⚠️ **transportPlanIds 序列化规则**:后端字段类型 `List`,但 HL 全局 Jackson `NumberSerializer` 会自动把超过 JS 安全整数(2^53-1)的 Long 转 String 输出。大交通批次 ID 是雪花 ID(19 位),**实际响应中一定是 String 数组**;下面示例值 `80012345`(8 位短整数)仅为可读性目的,**生产值类似 `"80012345678901234"`**。前端按 String 数组接收。 + #### 错误码 | code | 含义 | @@ -102,7 +104,7 @@ **典型 - 请求**: ```http -GET /v3/admin/order/60123456789012/travelers +GET /v3/admin/order/60123456789012/traveler/list Authorization: Bearer {admin_jwt} ``` @@ -128,7 +130,7 @@ Authorization: Bearer {admin_jwt} "emergencyPhone": "13900008888", "roomGroupNo": 1, "profileStatus": "COMPLETED", - "transportPlanIds": [80012345, 80012346] + "transportPlanIds": ["80012345678901234", "80012345678901235"] }, { "id": "70123456789013", @@ -317,7 +319,7 @@ Content-Type: application/json **典型 - 请求**: ```http -POST /v3/admin/order/60123456789012/travelers +POST /v3/admin/order/60123456789012/traveler/add Authorization: Bearer {admin_jwt} Content-Type: application/json @@ -392,15 +394,15 @@ Content-Type: application/json |------|------| | `581020` | 订单不存在 | | `581110` | 出行人不属于该订单 | -| `581119` | 已签电子合同,禁止删除出行人 | -| `581120` | 出行人是订单最后 1 位成人,禁止删除 | +| `581106` | 已签电子合同,禁止删除出行人(DB 段位让位:581119 已被 `TRAVELER_ID_CARD_DUPLICATE` 占用,文档原 581119 让位至此) | +| `581107` | 出行人是订单最后 1 位成人,禁止删除(DB 段位让位:581120 已被 `TRANSPORT_PLAN_NOT_FOUND` 占用,文档原 581120 让位至此) | #### 业务边界 - ✅ **软删**:UPDATE `order_traveler.deleted=1`,不真删 - ✅ **级联解除桥接**:UPDATE `order_transport_plan_traveler.deleted=1` -- ❌ **已签合同禁删**:合同强约束 → `581119` -- ❌ **最后成人禁删**:保留至少 1 位成人 → `581120` +- ❌ **已签合同禁删**:合同强约束 → `581106` +- ❌ **最后成人禁删**:保留至少 1 位成人 → `581107` #### 示例 @@ -417,10 +419,10 @@ Authorization: Bearer {admin_jwt} { "code": 200, "data": true, "msg": "success" } ``` -**异常(已签合同 581119) - 响应**: +**异常(已签合同 581106) - 响应**: ```json -{ "code": 581119, "data": null, "msg": "订单已签电子合同,禁止删除出行人" } +{ "code": 581106, "data": null, "msg": "订单已签电子合同,禁止删除出行人" } ``` --- @@ -774,10 +776,10 @@ Authorization: Bearer {admin_jwt} | code | 含义 | |------|------| -| `581120` | 原文超长(> 20000 字符) | -| `581121` | 原文为空或全行无法解析 | -| `581122` | 限流触发(10 次/分钟) | -| `581123` | 订单状态不允许批量导入(已结算 / 已取消) | +| `581131` | 原文超长(> 20000 字符)(DB 段位让位:原文档 581120 已被 `TRANSPORT_PLAN_NOT_FOUND` 占用) | +| `581132` | 原文为空或全行无法解析(DB 段位让位:原文档 581121 改至此) | +| `100501` | 限流触发(10 次/分钟)—— 走 HL 全局 `CommonErrorCode.RATE_LIMITED`,不在 traveler 段位 | +| `581134` | 订单状态不允许批量导入(已结算 / 已取消)(DB 段位让位:原文档 581123 改至此) | #### 业务边界 + 审计安全 @@ -822,10 +824,10 @@ Content-Type: application/json } ``` -**异常(限流 581122) - 响应**: +**异常(限流 100501) - 响应**: ```json -{ "code": 581122, "data": null, "msg": "智能导入解析过于频繁,请稍后再试" } +{ "code": 100501, "data": null, "msg": "请求过于频繁,请稍后再试" } ``` --- @@ -1018,7 +1020,7 @@ Authorization: Bearer {admin_jwt} - **§2.8 smart-parse 待 wx 新建(Issue [#2526](https://git.1814.love:8443/wx/HL/issues/2526))**:前端可先按本文字段对接 UI,wx 实现完接口立即可调;接口字段已确定不会变 - **敏感字段明文返回**:§2.1 / §2.3 / §2.8 / §2.9 admin 接口返回 `idNo` / `phone` / `emergencyPhone` 明文,前端拿到后**不要**写本地 log / 不要塞 URL query;§2.9 `incompleteList[].name` 已脱敏 - **桥接表约束**:§3.6 / §3.7 大交通批次新增/编辑时同方向同一出行人只能在 1 个 plan(错则 `581143`) -- **删人合同强约束**:§3.4 已签电子合同后禁止删人 → `581119` +- **删人合同强约束**:§3.4 已签电子合同后禁止删人 → `581106` - **`/v3/admin/**` 公司隔离**:所有 admin 接口均带跨公司隔离校验,跨公司访问返 `581021`,前端无需自行过滤 ---