diff --git a/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md b/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md index e063323..9c8c74b 100644 --- a/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md +++ b/changelogs-v2/2026-05/18_§1_订单核心模块-新增接口-管理后台.md @@ -20,7 +20,7 @@ ## 1. 接口背景 -订单服务 v3(hl-order-service-v3 全新二期)的订单核心模块 §1 core 提供订单管理基础能力,覆盖定制师 B 端代下单 / 多维度筛选列表 / 订单详情(首屏一次聚合 + 6 个 Tab 独立刷新双模式)/ 非关键字段修改。 +订单服务 v3(hl-order-service-v3 全新二期)的订单核心模块 §1 core 提供订单管理基础能力,覆盖定制师 B 端代下单 / 多维度筛选列表 / 订单详情(首屏主聚合 + 6 个 Tab 独立懒加载)/ 非关键字段修改。 本次(§1A)推送 10 个接口,对应管理后台原型 F8-F20(订单列表+创建+详情主体)、F22-F26(详情各 Tab 单刷新)、F37(修改订单字段)。 @@ -45,68 +45,18 @@ ## 3. 接口详情 -### 3.1 创建订单(§1.1) - -- **使用场景**:定制师代下单(电话 / 微信 / 线下渠道)。客户自助下单走 mp 端不在本模块。 -- **认证**:JWT(admin 角色) -- **幂等性**:否 -- **限流**:无 - -### 3.2 订单列表(§1.2) - -- **使用场景**:定制师 / 主管 / 客服多维度筛选订单 -- **认证**:JWT(admin 角色) -- **支持过滤**:粗状态 / 细状态 / 标签(AND) / 关键字 / 出发日期范围 / 来源 / 是否含已取消 -- **分页**:继承 PageParam(`page` / `pageSize`) - -### 3.3 订单详情主聚合(§1.3.1) - -- **使用场景**:详情页**首屏加载**——一次请求拿全订单 + 9 Tab 数据 -- **认证**:JWT(admin 角色 + 公司隔离校验) -- **公司隔离**:调用方 adminId 跨公司访问返 `581021` - -### 3.4 财务 Tab 子接口(§1.3.2) - -- **使用场景**:详情页**单 Tab 刷新**——财务 Tab 内操作(优惠/退款)后单独刷此 Tab,避免重拉整页 -- **认证**:JWT + 公司隔离 - -### 3.5 合同保险 Tab 子接口(§1.3.3) - -- **使用场景**:合同重签 / 保险重投后单独刷新这个 Tab -- **响应结构**:`contract` / `insurance` 两个并列子对象,前端在 Tab 内上下两栏布局 - -### 3.6 行程安排 Tab 子接口(§1.3.4) - -- **使用场景**:调整行程节点 / 房车配置后单独刷新 -- **⚠️ 当前数据 Mock**:行程节点 + 房车需求&实配为 Mock 数据,真实化进度见后端 follow-up Issue - -### 3.7 状态记录 Tab 子接口(§1.3.5) - -- **使用场景**:执行 transition 等状态变更后刷新时间线 -- **数据来源**:5 张审计表联合(status_log / payment / refund / contract_event / insurance_event)按 `occurredAt desc` 倒序 - -### 3.8 退款明细 Tab 子接口(§1.3.6) - -- **使用场景**:退款流程节点变更后刷新 -- **空值约定**:无退款时 `data=null`(前端据此判断是否显示 Tab) - -### 3.9 服务标准 Tab 子接口(§1.3.7) - -- **使用场景**:详情页"服务标准" Tab 单独刷新 -- **数据来源**:产品快照冻结(永不变) -- **空值约定**:快照缺失时 `data=null` - -### 3.10 修改订单字段(§1.4) - -- **使用场景**:修改订单**非关键字段**(备注 / 紧急联系人 / 客户信息 / 转单等),不触发状态机 -- **关键字段约定**:订单金额 / 状态等不允许在此接口改,需走专用接口 -- **审计**:每次修改写 1 行 `order_status_log`(即使状态未变也记录"字段被改") +> 每个接口自包含:使用场景 / 入参 / 出参 / 错误码 / 业务边界 / 示例(请求 + 响应)。 +> 跨接口共享枚举集中在 §6;模块整体影响评估在 §11。 --- -## 4. 接口入参 +### 3.1 §1.1 创建订单 -### 4.1 §1.1 创建订单(`OrderCreateReqVO`,13 字段) +**路径**:`POST /v3/admin/order` +**使用场景**:定制师 B 端代下单(电话 / 微信 / 线下渠道)。客户自助下单走 mp 端不在本模块。 +**认证**:JWT(admin 角色) | **幂等性**:否 | **限流**:无 + +#### 入参(`OrderCreateReqVO`,13 字段) | 字段 | 类型 | 必填 | 说明 | 校验规则 | |------|------|:----:|------|----------| @@ -120,50 +70,12 @@ | `customerName` | String | ✅ | 客户姓名 | `@NotBlank` | | `customerPhone` | String | ✅ | 客户手机(明文传,11 位数字) | `@NotBlank` | | `customerRemark` | String | ❌ | 客户备注 | `@Size(max=500)` | -| `createSource` | String | ❌ | 创建来源(不传默认 `CONSULTANT`) | `@Size(max=20)`,枚举见 §6.1 | +| `createSource` | String | ❌ | 创建来源(不传默认 `CONSULTANT`) | 枚举见 §6.1 | | `groupBatchId` | Long | ❌ | 拼团批次 ID(自由出团传空) | — | | `roomCount` | Integer | ❌ | 房间数 | `@Min(1)` | | `tags` | List\ | ❌ | 订单标签名列表 | — | -### 4.2 §1.2 订单列表(`OrderListReqVO extends PageParam`) - -| 字段 | 类型 | 必填 | 说明 | -|------|------|:----:|------| -| `page` | Integer | ❌ | 页码,默认 1(继承 PageParam) | -| `pageSize` | Integer | ❌ | 每页条数,默认 10(继承 PageParam) | -| `orderStatus` | String | ❌ | 粗状态过滤(多值用逗号) | -| `flowStatus` | String | ❌ | 细状态过滤 | -| `tagNames` | List\ | ❌ | 按标签过滤(多标签为 AND) | -| `keyword` | String | ❌ | 搜索关键字(匹配 团号 / 客户姓名 / 产品名 / 订单号 任一字段 LIKE) | -| `departureDateFrom` | LocalDate | ❌ | 出发日期范围起始 | -| `departureDateTo` | LocalDate | ❌ | 出发日期范围结束 | -| `createSource` | String | ❌ | 来源过滤(枚举见 §6.1) | -| `cancelled` | Boolean | ❌ | 是否含已取消(默认 false) | - -### 4.3 §1.3.1 ~ §1.3.7 详情主聚合 + 6 Tab 子接口 - -**全部统一入参**:`id` (path, Long) — 订单 ID - -### 4.4 §1.4 修改订单字段(`OrderUpdateReqVO`,PATCH 语义) - -| 字段 | 类型 | 必填 | 说明 | -|------|------|:----:|------| -| `customerName` | String | ❌ | 客户姓名 | -| `customerPhone` | String | ❌ | 客户手机 | -| `emergencyContactName` | String | ❌ | 紧急联系人姓名 | -| `emergencyContactPhone` | String | ❌ | 紧急联系人电话 | -| `customerRemark` | String | ❌ | 客户备注 | -| `consultantRemark` | String | ❌ | 定制师备注 | -| `targetConsultantId` | Long | ❌ | 转单目标定制师 ID(仅主管 / 客服角色可传) | -| `transferReason` | String | ❌ | 转单原因(传 `targetConsultantId` 时必填) | - -> 所有字段可空,传哪个改哪个(PATCH 语义)。 - ---- - -## 5. 出参 - -### 5.1 §1.1 创建订单(`OrderCreateRespVO`,20 字段) +#### 出参(`Result`,20 字段) | 字段 | 类型 | 说明 | |------|------|------| @@ -189,344 +101,7 @@ | `payUrl` | String | 支付页绝对 URL | | `customerName` | String | 客户姓名(回显) | -### 5.2 §1.2 订单列表(`Result>`) - -`PageResult` 字段:`list: List` / `total: Long` / `page` / `pageSize` - -`OrderListItemRespVO`(17 字段): - -| 字段 | 类型 | 说明 | -|------|------|------| -| `id` | String | 订单 ID | -| `orderNo` | String | 订单号 | -| `displayOrderNo` | String | 完整展示订单号 | -| `productName` | String | 产品名(快照) | -| `productCoverImg` | String | 产品封面 URL | -| `tierName` | String | 档位名(快照) | -| `customerName` | String | 客户姓名 | -| `customerPhoneMasked` | String | 客户手机(脱敏 `138****2046`) | -| `peopleSummary` | String | 人数摘要("2 大 1 小") | -| `departureDate` | LocalDate? | 出发日(未定时 null) | -| `tripDays` | Integer | 行程天数 | -| `orderStatus` | String | 粗状态(枚举见 §6.2) | -| `flowStatus` | String | 细状态(枚举见 §6.3) | -| `totalAmount` | BigDecimal | 订单金额 | -| `paidAmount` | BigDecimal | 实付金额 | -| `balanceAmount` | BigDecimal | 待付金额 | -| `consultantName` | String | 定制师姓名 | -| `tags` | List\ | 标签列表 | -| `createdAt` | LocalDateTime | 创单时间 | - -### 5.3 §1.3.1 订单详情主聚合(`Result`) - -包含 9 个顶层字段: - -| 字段 | 类型 | 说明 | -|------|------|------| -| `main` | OrderMainVO | 订单主单 + 异常态横条 9 类标识 + `progressStepper` 步骤进度条 | -| `tags` | List\ | 标签列表(`name` / `type` / `color`) | -| `overview` | OverviewVO | Tab 1 概览(含 travelers[] 出行人完整集合,详见 traveler 模块文档 §2.1) | -| `finance` | FinanceVO | Tab 4 财务(结构同 §5.4) | -| `itinerary` | ItineraryVO | Tab 2 行程(结构同 §5.6) | -| `contractInsurance` | ContractInsuranceVO | Tab 3 合同保险(结构同 §5.5) | -| `serviceStandard` | ServiceVO | Tab 5 服务标准(结构同 §5.9) | -| `statusLog` | List\ | Tab 7 记录(结构同 §5.7) | -| `refund` | RefundDetailVO? | Tab 9 退款明细(无退款时 null,结构同 §5.8) | - -`OrderMainVO.exceptionBadges`(异常态横条 9 类标识):`contractFail / insuranceFail / refundAbnormal / grabTimeout / hotelPending / vehiclePending / travelerIncomplete / longUnpaid / awaitingCustomerConfirm`(全 false 表示无异常) - -`OrderMainVO.progressStepper`(步骤进度条):`currentStage` + `nodes: [{key, label, status, subItems?}]`,节点 key 枚举:`INFO_COMPLETE / ASSIGN_PARALLEL / CONFIRM / DEPARTED / RETURNED / REVIEW / SETTLED`;节点 status:`DONE / ACTIVE / PENDING` - -### 5.4 §1.3.2 财务 Tab(`Result`) - -| 字段 | 类型 | 说明 | -|------|------|------| -| `totalAmount` | BigDecimal | 订单总额 | -| `paidAmount` | BigDecimal | 实付金额 | -| `balanceAmount` | BigDecimal | 待付金额 | -| `discountAmount` | BigDecimal | 优惠金额汇总 | -| `surchargeAmount` | BigDecimal | 附加费用汇总 | -| `refundAmount` | BigDecimal | 退款金额汇总 | -| `payments` | List\ | 支付明细 | -| `discounts` | List\ | 优惠明细 | -| `surcharges` | List\ | 附加费用 | - -`PaymentVO`:`id` / `payType`(枚举见 §6.6) / `amount` / `paidAt` / `status`(枚举见 §6.7) - -`DiscountVO`:`id` / `name` / `amount` / `type`(枚举见 §6.8) / `source`(枚举见 §6.9) / `createdAt` - -`SurchargeVO`:`id` / `name` / `amount` / `type`(`MANUAL` / `AUTO`) / `source`(`HOTEL_ASSIGN` / `VEHICLE_ASSIGN` / ...) / `createdAt` - -### 5.5 §1.3.3 合同保险 Tab(`Result`) - -| 字段 | 类型 | 说明 | -|------|------|------| -| `contract.contractStatus` | String | 合同状态(枚举见 §6.10) | -| `contract.contractSignedAt` | LocalDateTime? | 签约时间 | -| `contract.contractFileUrl` | String? | 合同文件 URL | -| `contract.events[].eventType` | String | 合同事件类型(枚举见 §6.11) | -| `contract.events[].occurredAt` | LocalDateTime | 事件发生时间 | -| `insurance.insuranceStatus` | String | 保险状态(枚举见 §6.12) | -| `insurance.insurancePolicyNo` | String? | 保单号 | -| `insurance.insurancePremium` | BigDecimal? | 保费 | -| `insurance.events[].eventType` | String | 保险事件类型(枚举见 §6.11) | -| `insurance.events[].occurredAt` | LocalDateTime | 事件发生时间 | - -### 5.6 §1.3.4 行程安排 Tab(`Result`)⚠️ Mock - -| 字段 | 类型 | 说明 | -|------|------|------| -| `days[].dayIndex` | Integer | 天序 | -| `days[].dayDate` | String | 日期(`yyyy-MM-dd`) | -| `days[].title` | String | 标题 | -| `days[].nodes` | List\ | 节点列表(结构见 itinerary 模块 §5) | -| `hotelGroup.requirement` | Object | 配房需求(`requirementId / status / roomTypeSummary / claimedBy` 等) | -| `hotelGroup.assignments` | List\ | 实际配房(`hotelName / stayDate / roomType / roomCount / unitPrice / subtotal`) | -| `vehicleGroup.requirement` | Object | 配车需求(`requirementId / status / vehicleTypeSummary / claimedBy`) | -| `vehicleGroup.assignments` | List\ | 实际配车(`vehicleType / plate / driverName / dailyFee / totalFee`) | - -### 5.7 §1.3.5 状态记录 Tab(`Result>`) - -| 字段 | 类型 | 说明 | -|------|------|------| -| `occurredAt` | LocalDateTime | 发生时间 | -| `operator` | String | 操作人 | -| `action` | String | 操作描述 | -| `fromStatus` | String? | 变更前状态(有状态变更时有值) | -| `toStatus` | String? | 变更后状态 | -| `amount` | BigDecimal? | 涉及金额(支付/退款时有值) | - -按 `occurredAt desc` 倒序。 - -### 5.8 §1.3.6 退款明细 Tab(`Result` 或 `data=null`) - -| 字段 | 类型 | 说明 | -|------|------|------| -| `totalRefundAmount` | BigDecimal | 合计退款金额(= `finance.refundAmount`) | -| `applications[].applicationId` | Long | 申请 ID | -| `applications[].status` | String | 进度状态(枚举见 §6.13) | -| `applications[].statusText` | String | 状态描述文案 | -| `applications[].refundAmount` | BigDecimal | 退款金额 | -| `applications[].refundChannel` | String | 退款渠道("原路退回(支付宝)") | -| `applications[].approverName` | String? | 审批人 | -| `applications[].approvedAt` | LocalDateTime? | 审批时间 | -| `applications[].estimatedArriveDate` | LocalDate? | 预计到账日期 | -| `applications[].actualArriveDate` | LocalDate? | 实际到账日期 | -| `applications[].progress[].step` | String | 步骤(枚举见 §6.14) | -| `applications[].progress[].label` | String | 步骤展示标签 | -| `applications[].progress[].status` | String | 步骤状态(`DONE` / `ACTIVE` / `PENDING`) | -| `applications[].progress[].occurredAt` | LocalDateTime? | 步骤发生时间 | -| `applications[].items[].itemName` | String | 项目名称 | -| `applications[].items[].reason` | String | 退款原因 | -| `applications[].items[].appliedAt` | LocalDateTime | 申请时间 | -| `applications[].items[].amount` | BigDecimal | 退款金额(负数) | - -### 5.9 §1.3.7 服务标准 Tab(`Result` 或 `data=null`) - -| 字段 | 类型 | 说明 | -|------|------|------| -| `itinerary` | List\ | 行程天纲(产品快照) | -| `notice.title` | String | 出团注意事项标题 | -| `notice.content` | String | 出团注意事项内容(Markdown) | -| `refundPolicy.policyId` | Long | 退改政策 ID | -| `refundPolicy.policyName` | String | 退改政策名称 | -| `refundPolicy.tiers[].minDays` | Integer | 出发前最小天数 | -| `refundPolicy.tiers[].refundRatio` | Integer | 退款比例(百分比 0-100) | -| `refundPolicy.tiers[].label` | String | 展示文案 | - -### 5.10 §1.4 修改订单字段(`Result`) - -返回 `true` 表示成功,`false` 表示无字段实际变化。 - ---- - -## 6. 枚举 / 数据字典 - -### 6.1 createSource(订单创建来源) - -**使用字段**:入参 §4.1 `createSource` / 入参 §4.2 `createSource` 过滤 - -| 值 | 中文 | 说明 | -|----|------|------| -| `CUSTOMER` | 客户自助 | 客户在小程序自助下单 | -| `CONSULTANT` | 定制师代下单 | 默认值 | -| `OTA` | OTA 渠道 | 携程 / 美团等 OTA 引流 | -| `WALK_IN` | 门店步入 | 线下门店现场下单 | -| `B2B` | B2B 渠道 | 旅行社代下单 | -| `VIP_REPURCHASE` | VIP 复购 | — | -| `REFERRAL` | 老客户转介绍 | — | -| `PROMOTION` | 营销活动 | — | -| `INTERNAL` | 内部测试 | 不计入业绩 | - -### 6.2 orderStatus(订单粗状态) - -**使用字段**:出参 §5.1 / §5.2 / §5.3 main / 入参 §4.2 过滤 - -| 值 | 说明 | -|----|------| -| `待支付` | 创单后默认 | -| `待完善` | 订金到账后进入 | -| `定制中` | 出行人 + 房车齐后 | -| `已确认` | — | -| `出行中` | — | -| `已完成` | — | -| `已取消` | — | - -### 6.3 flowStatus(订单细状态) - -**使用字段**:出参 §5.1 / §5.2 / §5.3 main / 入参 §4.2 过滤 - -| 值 | 说明 | -|----|------| -| `待支付订金` | 创单后默认细状态 | -| `待支付尾款` | — | -| `待补全信息` | 订金到账后 | -| `待提交房型` | — | -| `待抢房` | — | -| `配房中` | — | -| `待提交用车` | — | -| `车控处理中` | — | -| `待确认` | 房车齐后 | -| `待出行` | 确认锁单后 | -| `出行中` | — | -| `已完成` | — | -| `已取消` | — | - -> 完整 flowStatus 枚举详见订单状态机文档(§1C 推送时补全)。 - -### 6.4 consultantSource(定制师分配来源) - -**使用字段**:出参 §5.1 / §5.3 main - -| 值 | 说明 | -|----|------| -| `DEFAULT_ASSIGNED` | 系统默认分配(轮询) | -| `LINK_BOUND` | 链接绑定(客户扫定制师专属码) | -| `MANUAL` | 手动指定 | - -### 6.5 paymentMode(支付模式) - -**使用字段**:出参 §5.1 - -| 值 | 说明 | -|----|------| -| `DEPOSIT` | 定金模式(30% 定金 + 余款) | -| `FULL` | 全款模式(100% 一次付清) | - -### 6.6 payType(支付类型) - -**使用字段**:出参 §5.4 `payments[].payType` - -| 值 | 说明 | -|----|------| -| `DEPOSIT` | 定金 | -| `BALANCE` | 尾款 | - -### 6.7 payment status(支付记录状态) - -**使用字段**:出参 §5.4 `payments[].status` - -| 值 | 说明 | -|----|------| -| `SUCCESS` | 成功 | -| `PENDING` | 处理中 | -| `FAIL` | 失败 | - -### 6.8 discount type(优惠类型) - -**使用字段**:出参 §5.4 `discounts[].type` - -| 值 | 说明 | -|----|------| -| `EARLY_BIRD` | 早鸟优惠 | -| `VIP` | VIP 优惠 | -| `COUPON` | 优惠券 | -| `PROMOTION` | 营销活动优惠 | - -### 6.9 discount source(优惠来源) - -**使用字段**:出参 §5.4 `discounts[].source` / `surcharges[].source` - -| 值 | 说明 | -|----|------| -| `MANUAL` | 手动添加(定制师人工) | -| `AUTO` | 系统自动 | -| `HOTEL_ASSIGN` | 配房环节产生(仅 surcharge) | -| `VEHICLE_ASSIGN` | 配车环节产生(仅 surcharge) | - -### 6.10 contractStatus(合同状态) - -**使用字段**:出参 §5.5 `contract.contractStatus` - -| 值 | 说明 | -|----|------| -| `PENDING` | 待生成 | -| `GENERATED` | 已生成待签 | -| `SIGNED` | 已签约 | -| `VOIDED` | 已作废 | - -### 6.11 event type(合同 / 保险事件类型) - -**使用字段**:出参 §5.5 `contract.events[].eventType` / `insurance.events[].eventType` - -| 值 | 说明 | -|----|------| -| `GENERATE` | 合同生成 | -| `SIGN` | 合同签约 | -| `VOID` | 合同作废 | -| `REOPEN` | 合同重开 | -| `ISSUE` | 保险出单 | -| `CANCEL` | 保险退保 | - -### 6.12 insuranceStatus(保险状态) - -**使用字段**:出参 §5.5 `insurance.insuranceStatus` - -| 值 | 说明 | -|----|------| -| `PENDING` | 待出单 | -| `ACTIVE` | 已生效 | -| `FAILED` | 出单失败 | -| `CANCELLED` | 已退保 | - -### 6.13 refund application status(退款申请状态) - -**使用字段**:出参 §5.8 `applications[].status` - -| 值 | 说明 | -|----|------| -| `PENDING_APPROVE` | 待审批 | -| `PENDING_PAYOUT` | 财务已审批,待打款 | -| `PENDING_ARRIVAL` | 已打款,待到账 | -| `COMPLETED` | 退款完成(已到账) | -| `REJECTED` | 已拒绝 | - -### 6.14 refund progress step(退款进度步骤) - -**使用字段**:出参 §5.8 `applications[].progress[].step` - -| 值 | 说明 | -|----|------| -| `APPLY` | 退款申请 | -| `APPROVE` | 财务审批 | -| `PAYOUT` | 退款打款 | -| `ARRIVED` | 到账确认 | - -### 6.15 tag type(标签类型) - -**使用字段**:出参 §5.3 main `tags[].type` - -| 值 | 说明 | -|----|------| -| `SYSTEM` | 系统自动打的标签 | -| `PERSONAL` | 定制师手动打的标签 | -| `MANUAL` | 主管手动打的标签 | - ---- - -## 7. 错误码 - -### 7.1 §1.1 创建订单(5101xx 段) +#### 错误码 | code | 含义 | |------|------| @@ -538,44 +113,23 @@ | `510106` | 总人数 = 0 | | `510107` | `createSource` 枚举非法 | | `510108` | 客户手机格式非法 | -| `510109` | 系统未配置默认定制师(DEFAULT_ASSIGNED 时轮询池为空) | +| `510109` | 系统未配置默认定制师 | | `581013` | 定制师 ID 缺失(admin 端 JWT adminId 缺失) | | `581014` | 产品域 Feign 调用失败 | | `581015` | 产品域返回产品不存在 | | `581020` | MQ 事件发布失败(非主路径,记审计) | | `581021` | 跨公司访问被拒(公司隔离) | -### 7.2 §1.2 订单列表 +#### 业务边界 -| code | 含义 | -|------|------| -| 无业务错误码 | 参数格式错误走全局 400 | +- ✅ **适用**:产品上架;档位有效;出发日期 ≥ 今天;总人数 ≥ 1;客户手机合法 +- ❌ **拒绝**:产品下架 / 出发日期过期 / 总人数 0 / 拼团满员 / 客户手机非 11 位 +- ⚠️ **可选字段省略**:不传 `createSource` 用默认 `CONSULTANT` / 不传 `roomCount` 返 null / 不传 `tags` 仅含系统自动标签 -### 7.3 §1.3.x 详情主聚合 + 6 Tab 子接口 +#### 示例 -**全部 7 接口共享**: -| code | 含义 | -|------|------| -| `581020` | 订单不存在 | -| `581021` | 无权访问该订单(公司隔离) | +**典型成功 - 请求**: -### 7.4 §1.4 修改订单字段 - -| code | 含义 | -|------|------| -| `581020` | 订单不存在 | -| `581021` | 无权访问该订单 | -| `581030` | 转单目标定制师不存在 | -| `581031` | 转单原因为空(传 targetConsultantId 时) | -| `581032` | 当前角色无转单权限(仅主管 / 客服可转单) | - ---- - -## 8. 示例 - -### 8.1 §1.1 创建订单 - 典型成功 - -**请求**: ```http POST /v3/admin/order Authorization: Bearer {admin_jwt} @@ -597,7 +151,8 @@ Content-Type: application/json } ``` -**响应**: +**典型成功 - 响应**: + ```json { "code": 200, @@ -628,14 +183,86 @@ Content-Type: application/json } ``` -### 8.2 §1.2 订单列表 - 典型 +**异常(拼团满员 510105) - 请求**:(同上,但 `groupBatchId` 指向已满批次) -**请求**: -```http -GET /v3/admin/order?page=1&pageSize=10&orderStatus=待出行&tagNames=VIP%20%E5%AE%A2%E6%88%B7 +**异常 - 响应**: + +```json +{ "code": 510105, "data": null, "msg": "拼团批次不存在或已满员" } ``` -**响应**: +--- + +### 3.2 §1.2 订单列表 + +**路径**:`GET /v3/admin/order` +**使用场景**:定制师 / 主管 / 客服多维度筛选订单 +**认证**:JWT(admin 角色) | **分页**:继承 PageParam + +#### 入参(`OrderListReqVO extends PageParam`) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|:----:|------| +| `page` | Integer | ❌ | 页码,默认 1 | +| `pageSize` | Integer | ❌ | 每页条数,默认 10 | +| `orderStatus` | String | ❌ | 粗状态过滤(多值用逗号) | +| `flowStatus` | String | ❌ | 细状态过滤 | +| `tagNames` | List\ | ❌ | 按标签过滤(多标签为 AND) | +| `keyword` | String | ❌ | 关键字(LIKE 团号 / 客户姓名 / 产品名 / 订单号 任一) | +| `departureDateFrom` | LocalDate | ❌ | 出发日期范围起始 | +| `departureDateTo` | LocalDate | ❌ | 出发日期范围结束 | +| `createSource` | String | ❌ | 来源过滤(枚举见 §6.1) | +| `cancelled` | Boolean | ❌ | 是否含已取消(默认 false) | + +#### 出参(`Result>`) + +`PageResult` 字段:`list: List` / `total: Long` / `page` / `pageSize` + +`OrderListItemRespVO`(17 字段): + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | String | 订单 ID | +| `orderNo` | String | 订单号 | +| `displayOrderNo` | String | 完整展示订单号 | +| `productName` | String | 产品名(快照) | +| `productCoverImg` | String | 产品封面 URL | +| `tierName` | String | 档位名(快照) | +| `customerName` | String | 客户姓名 | +| `customerPhoneMasked` | String | 客户手机(脱敏 `138****2046`) | +| `peopleSummary` | String | 人数摘要("2 大 1 小") | +| `departureDate` | LocalDate? | 出发日(未定时 null) | +| `tripDays` | Integer | 行程天数 | +| `orderStatus` | String | 粗状态(枚举见 §6.2) | +| `flowStatus` | String | 细状态(枚举见 §6.3) | +| `totalAmount` | BigDecimal | 订单金额 | +| `paidAmount` | BigDecimal | 实付金额 | +| `balanceAmount` | BigDecimal | 待付金额 | +| `consultantName` | String | 定制师姓名 | +| `tags` | List\ | 标签列表 | +| `createdAt` | LocalDateTime | 创单时间 | + +#### 错误码 + +参数格式错误走全局 400,无业务错误码。 + +#### 业务边界 + +- ✅ **默认行为**:`cancelled` 不传 = 不含已取消订单 +- ⚠️ **关键字**:`keyword` 同时 LIKE 4 字段(团号 / 客户姓名 / 产品名 / 订单号)任一命中 +- ⚠️ **标签过滤**:`tagNames` 多值是 **AND**(订单必须含全部标签才命中),不是 OR + +#### 示例 + +**典型 - 请求**: + +```http +GET /v3/admin/order?page=1&pageSize=10&orderStatus=待出行&tagNames=VIP%20%E5%AE%A2%E6%88%B7 +Authorization: Bearer {admin_jwt} +``` + +**典型 - 响应**: + ```json { "code": 200, @@ -671,14 +298,94 @@ GET /v3/admin/order?page=1&pageSize=10&orderStatus=待出行&tagNames=VIP%20%E5% } ``` -### 8.3 §1.3.1 详情主聚合 - 典型(精简:每 Tab 仅示范 1-2 字段) +--- + +### 3.3 §1.3.1 订单详情主聚合 + +**路径**:`GET /v3/admin/order/{id}` +**使用场景**:详情页**首屏加载**——一次请求拿到主单 + 标签 + 概览(出行人 / 备注 / 紧急联系人);Tab 详情按需懒加载(§1.3.2 ~ §1.3.7) +**认证**:JWT + 公司隔离 | **响应规模**:精简,不含 6 Tab 子接口数据 + +> 📌 **本接口只返回 main / tags / overview 3 个顶层字段**。原 v5.48 设计的"一次返 9 Tab 全部数据"已拆分:finance / itinerary / contractInsurance / serviceStandard / statusLog / refund 移到 §1.3.2 ~ §1.3.7 独立懒加载接口。 + +#### 入参 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|:----:|------| +| `id` | Long | ✅ | 订单 ID(path) | + +#### 出参(`Result`,3 顶层字段) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `main` | OrderMainVO | 订单主单 + 异常态横条 + progressStepper 步骤进度条 | +| `tags` | List\ | 标签列表 | +| `overview` | OverviewVO | Tab 1 概览(出行人 + 备注 + 紧急联系人) | + +`OrderMainVO` 关键字段: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | String | 订单 ID | +| `displayOrderNo` | String | 完整展示订单号 | +| `productName` / `tierName` | String | 产品名 / 档位名(快照) | +| `orderStatus` | String | 粗状态(枚举见 §6.2) | +| `flowStatus` | String | 细状态(枚举见 §6.3) | +| `totalAmount` / `paidAmount` / `balanceAmount` | BigDecimal | 金额三件套 | +| `departureDate` / `returnDate` | LocalDate | 出发日 / 返团日 | +| `tripDays` / `tripNights` | Integer | 行程天数 / 晚数 | +| `adultCount` / `childCount` / `youngChildCount` / `babyCount` | Integer | 4 类人数 | +| `customerName` / `customerPhone` | String | 客户姓名 / 手机(admin 明文) | +| `consultantName` | String | 定制师姓名 | +| `confirmedAt` | LocalDateTime? | 确认锁单时间 | +| `exceptionBadges` | Object | 异常态横条 9 类标识(见下方) | +| `progressStepper` | Object | 步骤进度条(见下方) | + +**`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` 子项 + +`TagVO`:`name` / `type`(枚举见 §6.15) / `color` + +`OverviewVO` 关键字段: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `travelers` | List\ | 出行人完整集合(复用 traveler 模块 TravelerVO,含证件 / 性别 / 生日 / 民族 / 手机 / 紧急联系人 / 同住分组等,admin 明文) | +| `customerRemark` | String? | 客户备注 | +| `consultantRemark` | String? | 定制师备注 | +| `emergencyContactName` | String? | 紧急联系人姓名 | +| `emergencyContactPhone` | String? | 紧急联系人手机 | + +`TravelerVO` 字段口径详见 traveler 模块 §2.1 出行人列表 changelog。 + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单(公司隔离) | + +#### 业务边界 + +- ✅ **首屏一次请求拿全 main + tags + overview** +- ⚠️ 6 Tab 数据**不在本响应**,按需调 §1.3.2 ~ §1.3.7 子接口 +- ⚠️ 跨公司访问 → `581021` + +#### 示例 + +**典型 - 请求**: -**请求**: ```http GET /v3/admin/order/60123456789012 +Authorization: Bearer {admin_jwt} ``` -**响应**: +**典型 - 响应**: + ```json { "code": 200, @@ -686,9 +393,25 @@ GET /v3/admin/order/60123456789012 "main": { "id": "60123456789012", "displayOrderNo": "HL20260510143025001-T20260601A", + "productName": "长白山天池3日深度游", + "tierName": "经典档", "orderStatus": "待出行", "flowStatus": "待出行", "totalAmount": 8580.00, + "paidAmount": 8580.00, + "balanceAmount": 0.00, + "departureDate": "2026-06-01", + "returnDate": "2026-06-03", + "tripDays": 3, + "tripNights": 2, + "adultCount": 2, + "childCount": 1, + "youngChildCount": 0, + "babyCount": 0, + "customerName": "张三", + "customerPhone": "13800002046", + "consultantName": "李定制", + "confirmedAt": "2026-05-12T10:25:00", "exceptionBadges": { "contractFail": false, "insuranceFail": false, "refundAbnormal": false, "grabTimeout": false, "hotelPending": false, "vehiclePending": false, @@ -699,36 +422,115 @@ GET /v3/admin/order/60123456789012 "nodes": [ {"key": "INFO_COMPLETE", "label": "补全信息", "status": "DONE"}, {"key": "ASSIGN_PARALLEL", "label": null, "status": "DONE", "subItems": [ - {"key": "HOTEL", "label": "配房", "subStatus": "DONE"} + {"key": "HOTEL", "label": "配房", "subStatus": "DONE", "applicable": true}, + {"key": "VEHICLE", "label": "配车", "subStatus": "DONE", "applicable": true}, + {"key": "LEADER", "label": "配领队", "subStatus": "DONE", "applicable": true}, + {"key": "PHOTOGRAPHER", "label": "配摄影", "subStatus": "DONE", "applicable": true} ]}, - {"key": "RETURNED", "label": "返团", "status": "ACTIVE"} + {"key": "CONFIRM", "label": "确认", "status": "DONE"}, + {"key": "DEPARTED", "label": "出行", "status": "DONE"}, + {"key": "RETURNED", "label": "返团", "status": "ACTIVE"}, + {"key": "REVIEW", "label": "核单", "status": "PENDING"}, + {"key": "SETTLED", "label": "结算", "status": "PENDING"} ] } }, - "tags": [{"name": "二次复购", "type": "SYSTEM", "color": "#52C41A"}], - "overview": { "travelers": [/* TravelerVO 完整字段,见 traveler 模块文档 §2.1 */] }, - "finance": { "totalAmount": 8580.00, "paidAmount": 8580.00, "payments": [/* ... */] }, - "itinerary": { "days": [/* Mock 中 */], "hotelGroup": {/*...*/}, "vehicleGroup": {/*...*/} }, - "contractInsurance": { - "contract": {"contractStatus": "SIGNED", "events": [{"eventType": "SIGN", "occurredAt": "2026-05-12T11:00:00"}]}, - "insurance": {"insuranceStatus": "ACTIVE", "insurancePolicyNo": "PICC2026060100123"} - }, - "serviceStandard": { "itinerary": ["Day1 抵达长春-接机入住"], "notice": {/*...*/}, "refundPolicy": {/*...*/} }, - "statusLog": [{"occurredAt": "2026-05-12T10:25:00", "operator": "李定制", "action": "确认锁单"}], - "refund": null + "tags": [ + {"name": "二次复购", "type": "SYSTEM", "color": "#52C41A"}, + {"name": "VIP 客户", "type": "PERSONAL", "color": "#FAAD14"} + ], + "overview": { + "travelers": [ + { + "id": "70123456789012", + "orderId": "60123456789012", + "travelerType": "ADULT", + "name": "张三", + "gender": "MALE", + "birthday": "1985-08-12", + "idType": "ID_CARD", + "idNo": "220103198508121234", + "nationality": "中国", + "race": "汉族", + "phone": "13800002046", + "emergencyContact": "李四", + "emergencyPhone": "13900008888", + "roomGroupNo": 1, + "profileStatus": "COMPLETED", + "transportPlanIds": ["80012345"] + } + ], + "customerRemark": "希望住朝阳房", + "consultantRemark": "VIP 客户,已沟通到达接机", + "emergencyContactName": "李四", + "emergencyContactPhone": "13900008888" + } }, "msg": "success" } ``` -### 8.4 §1.3.2 财务 Tab 单刷 - 典型 +**异常(跨公司访问 581021) - 请求**:(admin JWT 不属于订单所属公司) -**请求**: ```http -GET /v3/admin/order/60123456789012/finance +GET /v3/admin/order/60999999999999 +Authorization: Bearer {admin_jwt} ``` -**响应**: +**异常 - 响应**: + +```json +{ "code": 581021, "data": null, "msg": "无权访问该订单" } +``` + +--- + +### 3.4 §1.3.2 财务 Tab(懒加载) + +**路径**:`GET /v3/admin/order/{id}/finance` +**使用场景**:详情页财务 Tab 单独刷新(如优惠 / 退款操作完后刷新) +**认证**:JWT + 公司隔离 + +#### 入参 + +`id` (path, Long) — 订单 ID + +#### 出参(`Result`) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `totalAmount` | BigDecimal | 订单总额 | +| `paidAmount` | BigDecimal | 实付金额 | +| `balanceAmount` | BigDecimal | 待付金额 | +| `discountAmount` | BigDecimal | 优惠金额汇总 | +| `surchargeAmount` | BigDecimal | 附加费用汇总 | +| `refundAmount` | BigDecimal | 退款金额汇总 | +| `payments` | List\ | 支付明细 | +| `discounts` | List\ | 优惠明细 | +| `surcharges` | List\ | 附加费用 | + +`PaymentVO`:`id` / `payType`(枚举见 §6.6) / `amount` / `paidAt` / `status`(枚举见 §6.7) +`DiscountVO`:`id` / `name` / `amount` / `type`(枚举见 §6.8) / `source`(枚举见 §6.9) / `createdAt` +`SurchargeVO`:`id` / `name` / `amount` / `type` / `source` / `createdAt` + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | + +#### 示例 + +**典型 - 请求**: + +```http +GET /v3/admin/order/60123456789012/finance +Authorization: Bearer {admin_jwt} +``` + +**典型 - 响应**: + ```json { "code": 200, @@ -752,23 +554,428 @@ GET /v3/admin/order/60123456789012/finance } ``` -### 8.5 §1.3.6 退款明细 Tab - 无退款(data=null) +--- + +### 3.5 §1.3.3 合同保险 Tab(懒加载) + +**路径**:`GET /v3/admin/order/{id}/contract-insurance` +**使用场景**:合同重签 / 保险重投后单独刷新该 Tab +**响应结构**:`contract` / `insurance` 两个并列子对象(前端 Tab 内上下两栏布局) + +#### 入参 + +`id` (path, Long) — 订单 ID + +#### 出参(`Result`) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `contract.contractStatus` | String | 合同状态(枚举见 §6.10) | +| `contract.contractSignedAt` | LocalDateTime? | 签约时间 | +| `contract.contractFileUrl` | String? | 合同文件 URL | +| `contract.events[].eventType` | String | 合同事件类型(枚举见 §6.11) | +| `contract.events[].occurredAt` | LocalDateTime | 事件发生时间 | +| `insurance.insuranceStatus` | String | 保险状态(枚举见 §6.12) | +| `insurance.insurancePolicyNo` | String? | 保单号 | +| `insurance.insurancePremium` | BigDecimal? | 保费 | +| `insurance.events[].eventType` | String | 保险事件类型(枚举见 §6.11) | +| `insurance.events[].occurredAt` | LocalDateTime | 事件发生时间 | + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | + +#### 示例 + +**典型 - 请求**: -**请求**: ```http -GET /v3/admin/order/60123456789012/refund +GET /v3/admin/order/60123456789012/contract-insurance +Authorization: Bearer {admin_jwt} ``` -**响应**: +**典型 - 响应**: + +```json +{ + "code": 200, + "data": { + "contract": { + "contractStatus": "SIGNED", + "contractSignedAt": "2026-05-12T11:00:00", + "contractFileUrl": "https://oss.hulalv.com/contract/HL20260510143025001.pdf", + "events": [ + {"eventType": "GENERATE", "occurredAt": "2026-05-12T10:55:00"}, + {"eventType": "SIGN", "occurredAt": "2026-05-12T11:00:00"} + ] + }, + "insurance": { + "insuranceStatus": "ACTIVE", + "insurancePolicyNo": "PICC2026060100123", + "insurancePremium": 88.00, + "events": [ + {"eventType": "ISSUE", "occurredAt": "2026-05-12T11:05:00"} + ] + } + }, + "msg": "success" +} +``` + +--- + +### 3.6 §1.3.4 行程安排 Tab(懒加载)⚠️ Mock + +**路径**:`GET /v3/admin/order/{id}/itinerary` +**使用场景**:调整行程节点 / 房车配置后单独刷新 + +> ⚠️ **当前数据 Mock**:行程节点 + 房车需求&实配为 Mock 数据,真实化进度见 follow-up Issue。前端可先按字段结构对接,真实化后无需改字段口径。 + +#### 入参 + +`id` (path, Long) — 订单 ID + +#### 出参(`Result`) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `days[].dayIndex` | Integer | 天序 | +| `days[].dayDate` | String | 日期(`yyyy-MM-dd`) | +| `days[].title` | String | 标题 | +| `days[].nodes` | List\ | 节点列表(结构见 itinerary 模块 §5) | +| `hotelGroup.requirement` | Object | 配房需求(`requirementId / status / roomTypeSummary / claimedBy` 等) | +| `hotelGroup.assignments` | List\ | 实际配房(`hotelName / stayDate / roomType / roomCount / unitPrice / subtotal`) | +| `vehicleGroup.requirement` | Object | 配车需求(`requirementId / status / vehicleTypeSummary / claimedBy`) | +| `vehicleGroup.assignments` | List\ | 实际配车(`vehicleType / plate / driverName / dailyFee / totalFee`) | + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | + +#### 示例 + +**典型 - 请求**: + +```http +GET /v3/admin/order/60123456789012/itinerary +Authorization: Bearer {admin_jwt} +``` + +**典型 - 响应**(Mock 数据示意): + +```json +{ + "code": 200, + "data": { + "days": [ + { + "dayIndex": 1, + "dayDate": "2026-06-01", + "title": "抵达长春-接机", + "nodes": [ + {"nodeType": "TRANSPORT", "title": "接机", "startTime": "10:30"}, + {"nodeType": "HOTEL", "title": "入住凯悦酒店", "actualResourceName": "长春凯悦酒店"} + ] + } + ], + "hotelGroup": { + "requirement": { + "requirementId": "70011", "status": "DONE", "version": 2, + "roomTypeSummary": "1 大床房×2 + 1 标间×1", + "remark": "希望朝阳房,带浴缸优先", + "budgetRange": "500-800/晚", + "claimedBy": "房控-王芳", "claimedAt": "2026-05-11T14:20:00" + }, + "assignments": [ + {"id": "80011", "hotelName": "长春凯悦酒店", "stayDate": "2026-06-01", "roomType": "大床房", "roomCount": 2, "roomGroupNo": 1, "unitPrice": 680, "subtotal": 1360} + ] + }, + "vehicleGroup": { + "requirement": { + "requirementId": "70021", "status": "DONE", "version": 1, + "vehicleTypeSummary": "9 座商务车×1", + "claimedBy": "车控-李强", "claimedAt": "2026-05-11T15:00:00" + }, + "assignments": [ + {"id": "80021", "vehicleType": "MPV", "plate": "吉A·888XX", "driverName": "王师傅", "driverPhone": "138****1234", "dailyFee": 1100, "totalDays": 3, "totalFee": 3300} + ] + } + }, + "msg": "success" +} +``` + +--- + +### 3.7 §1.3.5 状态记录 Tab(懒加载) + +**路径**:`GET /v3/admin/order/{id}/status-log` +**使用场景**:执行状态变更后刷新时间线 +**数据来源**:5 张审计表联合(status_log / payment / refund / contract_event / insurance_event)按 `occurredAt desc` 倒序 + +#### 入参 + +`id` (path, Long) — 订单 ID + +#### 出参(`Result>`) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `occurredAt` | LocalDateTime | 发生时间 | +| `operator` | String | 操作人 | +| `action` | String | 操作描述 | +| `fromStatus` | String? | 变更前状态(有状态变更时有值) | +| `toStatus` | String? | 变更后状态 | +| `amount` | BigDecimal? | 涉及金额(支付/退款时有值) | + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | + +#### 示例 + +**典型 - 请求**: + +```http +GET /v3/admin/order/60123456789012/status-log +Authorization: Bearer {admin_jwt} +``` + +**典型 - 响应**: + +```json +{ + "code": 200, + "data": [ + {"occurredAt": "2026-05-12T10:25:00", "operator": "李定制", "action": "确认锁单", "fromStatus": "定制中", "toStatus": "待出行"}, + {"occurredAt": "2026-05-10T15:00:00", "operator": "张三", "action": "支付订金", "amount": 2000.00}, + {"occurredAt": "2026-05-10T14:30:25", "operator": "李定制", "action": "创建订单"} + ], + "msg": "success" +} +``` + +--- + +### 3.8 §1.3.6 退款明细 Tab(懒加载,条件显示) + +**路径**:`GET /v3/admin/order/{id}/refund` +**使用场景**:退款流程节点变更后刷新;前端轮询等待退款到账 +**空值约定**:无退款时 `data=null`(前端据此判断是否渲染该 Tab) + +#### 入参 + +`id` (path, Long) — 订单 ID + +#### 出参(`Result` 或 `Result`) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `totalRefundAmount` | BigDecimal | 合计退款金额(= `finance.refundAmount`) | +| `applications[].applicationId` | Long | 申请 ID | +| `applications[].status` | String | 进度状态(枚举见 §6.13) | +| `applications[].statusText` | String | 状态描述文案 | +| `applications[].refundAmount` | BigDecimal | 退款金额 | +| `applications[].refundChannel` | String | 退款渠道("原路退回(支付宝)") | +| `applications[].approverName` | String? | 审批人 | +| `applications[].approvedAt` | LocalDateTime? | 审批时间 | +| `applications[].estimatedArriveDate` | LocalDate? | 预计到账日期 | +| `applications[].actualArriveDate` | LocalDate? | 实际到账日期 | +| `applications[].progress[].step` | String | 步骤(枚举见 §6.14) | +| `applications[].progress[].label` | String | 步骤展示标签 | +| `applications[].progress[].status` | String | 步骤状态(`DONE` / `ACTIVE` / `PENDING`) | +| `applications[].progress[].occurredAt` | LocalDateTime? | 步骤发生时间 | +| `applications[].items[].itemName` | String | 项目名称 | +| `applications[].items[].reason` | String | 退款原因 | +| `applications[].items[].appliedAt` | LocalDateTime | 申请时间 | +| `applications[].items[].amount` | BigDecimal | 退款金额(负数) | + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | + +#### 示例 + +**典型(有退款) - 请求**: + +```http +GET /v3/admin/order/60123456789012/refund +Authorization: Bearer {admin_jwt} +``` + +**典型(有退款) - 响应**: + +```json +{ + "code": 200, + "data": { + "totalRefundAmount": 4800.00, + "applications": [ + { + "applicationId": 60101, + "status": "PENDING_PAYOUT", + "statusText": "财务已审批,等待打款", + "refundAmount": 4800.00, + "refundChannel": "原路退回(支付宝)", + "approverName": "财务 · 周经理", + "approvedAt": "2026-04-25T14:20:00", + "estimatedArriveDate": "2026-04-30", + "actualArriveDate": null, + "progress": [ + {"step": "APPLY", "label": "退款申请", "status": "DONE", "occurredAt": "2026-04-25T11:30:00"}, + {"step": "APPROVE", "label": "财务审批", "status": "DONE", "occurredAt": "2026-04-25T14:20:00"}, + {"step": "PAYOUT", "label": "退款打款", "status": "ACTIVE", "occurredAt": null}, + {"step": "ARRIVED", "label": "到账确认", "status": "PENDING", "occurredAt": null} + ], + "items": [ + {"itemName": "主行程退款(同行小孩临时不能出行)", "reason": "同行儿童突发感冒,不参与本次出行", "appliedAt": "2026-04-25T11:30:00", "amount": -4800.00} + ] + } + ] + }, + "msg": "success" +} +``` + +**边界(无退款) - 请求**:(同上路径) + +**边界 - 响应**: + ```json { "code": 200, "data": null, "msg": "success" } ``` -### 8.6 §1.4 修改订单字段 - 典型(转单) +--- + +### 3.9 §1.3.7 服务标准 Tab(懒加载,条件显示) + +**路径**:`GET /v3/admin/order/{id}/service-standard` +**使用场景**:服务标准 Tab 单独刷新 +**数据来源**:产品快照冻结(永不变) +**空值约定**:快照缺失时 `data=null` + +#### 入参 + +`id` (path, Long) — 订单 ID + +#### 出参(`Result` 或 `Result`) + +| 字段 | 类型 | 说明 | +|------|------|------| +| `itinerary` | List\ | 行程天纲(产品快照) | +| `notice.title` | String | 出团注意事项标题 | +| `notice.content` | String | 出团注意事项内容(Markdown) | +| `refundPolicy.policyId` | Long | 退改政策 ID | +| `refundPolicy.policyName` | String | 退改政策名称 | +| `refundPolicy.tiers[].minDays` | Integer | 出发前最小天数 | +| `refundPolicy.tiers[].refundRatio` | Integer | 退款比例(百分比 0-100) | +| `refundPolicy.tiers[].label` | String | 展示文案 | + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | + +#### 示例 + +**典型 - 请求**: + +```http +GET /v3/admin/order/60123456789012/service-standard +Authorization: Bearer {admin_jwt} +``` + +**典型 - 响应**: + +```json +{ + "code": 200, + "data": { + "itinerary": ["Day1 抵达长春-接机入住", "Day2 长白山天池1日游", "Day3 返程"], + "notice": { + "title": "长白山天池 3 日深度游 - 出团注意事项", + "content": "# 出团必读\n\n1. 高原反应:海拔 2691m,请提前服用红景天\n2. 天气:山顶常年低于 0℃,请备厚外套\n..." + }, + "refundPolicy": { + "policyId": 50001, + "policyName": "标准退改政策", + "tiers": [ + {"minDays": 15, "refundRatio": 100, "label": "出发前 15 天 100%退"}, + {"minDays": 7, "refundRatio": 80, "label": "出发前 7-14 天 80%退"}, + {"minDays": 3, "refundRatio": 50, "label": "出发前 3-6 天 50%退"}, + {"minDays": 0, "refundRatio": 0, "label": "出发前 2 天内不退"} + ] + } + }, + "msg": "success" +} +``` + +--- + +### 3.10 §1.4 修改订单字段 + +**路径**:`PUT /v3/admin/order/{id}` +**使用场景**:修改订单**非关键字段**(备注 / 紧急联系人 / 客户信息 / 转单),不触发状态机 +**关键字段约定**:订单金额 / 状态等不允许在此接口改,需走专用接口 +**语义**:PATCH(传哪个改哪个) +**审计**:每次修改写 1 行 `order_status_log`(即使状态未变也记录"字段被改") + +#### 入参(`OrderUpdateReqVO`,PATCH 语义) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|:----:|------| +| `customerName` | String | ❌ | 客户姓名 | +| `customerPhone` | String | ❌ | 客户手机 | +| `emergencyContactName` | String | ❌ | 紧急联系人姓名 | +| `emergencyContactPhone` | String | ❌ | 紧急联系人电话 | +| `customerRemark` | String | ❌ | 客户备注 | +| `consultantRemark` | String | ❌ | 定制师备注 | +| `targetConsultantId` | Long | ❌ | 转单目标定制师 ID(仅主管 / 客服角色可传) | +| `transferReason` | String | ❌ | 转单原因(传 `targetConsultantId` 时必填) | + +#### 出参(`Result`) + +返回 `true` 表示成功,`false` 表示无字段实际变化。 + +#### 错误码 + +| code | 含义 | +|------|------| +| `581020` | 订单不存在 | +| `581021` | 无权访问该订单 | +| `581030` | 转单目标定制师不存在 | +| `581031` | 转单原因为空(传 `targetConsultantId` 时) | +| `581032` | 当前角色无转单权限(仅主管 / 客服可转单) | + +#### 业务边界 + +- ✅ **可改字段**:备注 / 紧急联系人 / 客户信息 / 转单(仅主管 / 客服角色) +- ❌ **不可改字段**:订单金额 / 订单状态 / 出发日期 / 出行人数 / 拼团批次 → 需走专用接口 +- ⚠️ **转单约束**:传 `targetConsultantId` 必须同时传 `transferReason` +- ⚠️ **PATCH 语义**:不传 = 不改;传空字符串 = 改成空(区分两者) + +#### 示例 + +**典型(转单) - 请求**: -**请求**: ```http PUT /v3/admin/order/60123456789012 +Authorization: Bearer {admin_jwt} Content-Type: application/json { @@ -778,76 +985,221 @@ Content-Type: application/json } ``` -**响应**: +**典型 - 响应**: + ```json { "code": 200, "data": true, "msg": "success" } ``` -### 8.7 §1.1 创建订单 - 异常(拼团满员) +**异常(转单缺原因 581031) - 请求**: -**请求**:(同 8.1,但 `groupBatchId` 满员) - -**响应**: -```json -{ "code": 510105, "data": null, "msg": "拼团批次不存在或已满员" } -``` - -### 8.8 §1.3.1 详情主聚合 - 异常(跨公司访问) - -**请求**:(用户 adminId 不属于订单所属公司) ```http -GET /v3/admin/order/60999999999999 +PUT /v3/admin/order/60123456789012 +Authorization: Bearer {admin_jwt} +Content-Type: application/json + +{ + "targetConsultantId": 50009876543210 +} ``` -**响应**: +**异常 - 响应**: + ```json -{ "code": 581021, "data": null, "msg": "无权访问该订单" } +{ "code": 581031, "data": null, "msg": "转单原因为空" } ``` --- -## 9. 业务边界 +## 6. 枚举 / 数据字典 -### 9.1 创建订单(§1.1) +> 跨接口共享枚举集中列出,按字段分组,标注「使用字段在哪里」。 -- ✅ **适用**:产品上架;档位有效;出发日期 ≥ 今天;总人数 ≥ 1;客户手机合法 -- ❌ **拒绝**:产品下架 / 出发日期过期 / 总人数 0 / 拼团满员 / 客户手机非 11 位 -- ⚠️ **可选字段省略行为**: - - 不传 `createSource` → 接受,使用默认 `CONSULTANT` - - 不传 `roomCount` → 接受,返回订单 `roomCount` 为 null - - 不传 `tags` → 接受,仅含系统自动标签 +### 6.1 createSource(订单创建来源) -### 9.2 订单列表(§1.2) +**使用字段**:§3.1 入参 `createSource` / §3.2 入参 `createSource` 过滤 -- ✅ **默认行为**:`cancelled` 不传 = 不含已取消订单 -- ⚠️ **关键字搜索**:`keyword` 同时 LIKE 团号 / 客户姓名 / 产品名 / 订单号 任一字段 -- ⚠️ **标签过滤**:`tagNames` 多值是 **AND**(订单必须含全部标签才命中),不是 OR +| 值 | 中文 | 说明 | +|----|------|------| +| `CUSTOMER` | 客户自助 | 客户在小程序自助下单 | +| `CONSULTANT` | 定制师代下单 | 默认值 | +| `OTA` | OTA 渠道 | 携程 / 美团等 OTA 引流 | +| `WALK_IN` | 门店步入 | 线下门店现场下单 | +| `B2B` | B2B 渠道 | 旅行社代下单 | +| `VIP_REPURCHASE` | VIP 复购 | — | +| `REFERRAL` | 老客户转介绍 | — | +| `PROMOTION` | 营销活动 | — | +| `INTERNAL` | 内部测试 | 不计入业绩 | -### 9.3 详情主聚合 vs 子接口(§1.3.x) +### 6.2 orderStatus(订单粗状态) -| 场景 | 用哪个 | -|---|---| -| 详情页首次打开 | §1.3.1 主聚合(1 次拉全) | -| 单个 Tab 操作完后刷新 | §1.3.2 ~ §1.3.7 对应 Tab 子接口 | -| 状态变更后整页刷新 | §1.3.1 主聚合 | -| 高频轮询单 Tab(如等待退款到账) | §1.3.6 退款 Tab 子接口 | +**使用字段**:§3.1 出参 / §3.2 出参 / §3.3 main / §3.2 入参过滤 -- ⚠️ **`itinerary` 子接口数据为 Mock**:行程节点 + 房车需求&实配为占位数据,待 follow-up issue 真实化 -- ⚠️ **退款 Tab 条件显示**:`refund` 字段无退款时为 null,前端据此判断是否渲染该 Tab -- ⚠️ **服务标准 Tab 条件显示**:`serviceStandard` 字段产品快照缺失时为 null +| 值 | 说明 | +|----|------| +| `待支付` | 创单后默认 | +| `待完善` | 订金到账后进入 | +| `定制中` | 出行人 + 房车齐后 | +| `已确认` | — | +| `出行中` | — | +| `已完成` | — | +| `已取消` | — | -### 9.4 修改订单字段(§1.4) +### 6.3 flowStatus(订单细状态) -- ✅ **可改字段**:备注 / 紧急联系人 / 客户信息 / 转单(仅主管 / 客服角色) -- ❌ **不可改字段**:订单金额 / 订单状态 / 出发日期 / 出行人数 / 拼团批次 → 需走专用接口 -- ⚠️ **转单约束**:传 `targetConsultantId` 必须同时传 `transferReason` -- ⚠️ **PATCH 语义**:不传 = 不改;传空字符串 = 改成空(区分两者) +**使用字段**:§3.1 出参 / §3.2 出参 / §3.3 main / §3.2 入参过滤 ---- +| 值 | 说明 | +|----|------| +| `待支付订金` | 创单后默认细状态 | +| `待支付尾款` | — | +| `待补全信息` | 订金到账后 | +| `待提交房型` | — | +| `待抢房` | — | +| `配房中` | — | +| `待提交用车` | — | +| `车控处理中` | — | +| `待确认` | 房车齐后 | +| `待出行` | 确认锁单后 | +| `出行中` | — | +| `已完成` | — | +| `已取消` | — | -## 10. 修改前后对比 +> 完整 flowStatus 枚举见订单状态机文档(§1C 推送时补全)。 -> 不适用 - 新增接口跳过本节 +### 6.4 consultantSource(定制师分配来源) + +**使用字段**:§3.1 出参 / §3.3 main + +| 值 | 说明 | +|----|------| +| `DEFAULT_ASSIGNED` | 系统默认分配(轮询) | +| `LINK_BOUND` | 链接绑定(客户扫定制师专属码) | +| `MANUAL` | 手动指定 | + +### 6.5 paymentMode(支付模式) + +**使用字段**:§3.1 出参 + +| 值 | 说明 | +|----|------| +| `DEPOSIT` | 定金模式(30% 定金 + 余款) | +| `FULL` | 全款模式(100% 一次付清) | + +### 6.6 payType(支付类型) + +**使用字段**:§3.4 出参 `payments[].payType` + +| 值 | 说明 | +|----|------| +| `DEPOSIT` | 定金 | +| `BALANCE` | 尾款 | + +### 6.7 payment status(支付记录状态) + +**使用字段**:§3.4 出参 `payments[].status` + +| 值 | 说明 | +|----|------| +| `SUCCESS` | 成功 | +| `PENDING` | 处理中 | +| `FAIL` | 失败 | + +### 6.8 discount type(优惠类型) + +**使用字段**:§3.4 出参 `discounts[].type` + +| 值 | 说明 | +|----|------| +| `EARLY_BIRD` | 早鸟优惠 | +| `VIP` | VIP 优惠 | +| `COUPON` | 优惠券 | +| `PROMOTION` | 营销活动优惠 | + +### 6.9 discount source(优惠 / 附加费来源) + +**使用字段**:§3.4 出参 `discounts[].source` / `surcharges[].source` + +| 值 | 说明 | +|----|------| +| `MANUAL` | 手动添加(定制师人工) | +| `AUTO` | 系统自动 | +| `HOTEL_ASSIGN` | 配房环节产生(仅 surcharge) | +| `VEHICLE_ASSIGN` | 配车环节产生(仅 surcharge) | + +### 6.10 contractStatus(合同状态) + +**使用字段**:§3.5 出参 `contract.contractStatus` + +| 值 | 说明 | +|----|------| +| `PENDING` | 待生成 | +| `GENERATED` | 已生成待签 | +| `SIGNED` | 已签约 | +| `VOIDED` | 已作废 | + +### 6.11 event type(合同 / 保险事件类型) + +**使用字段**:§3.5 出参 `contract.events[].eventType` / `insurance.events[].eventType` + +| 值 | 说明 | +|----|------| +| `GENERATE` | 合同生成 | +| `SIGN` | 合同签约 | +| `VOID` | 合同作废 | +| `REOPEN` | 合同重开 | +| `ISSUE` | 保险出单 | +| `CANCEL` | 保险退保 | + +### 6.12 insuranceStatus(保险状态) + +**使用字段**:§3.5 出参 `insurance.insuranceStatus` + +| 值 | 说明 | +|----|------| +| `PENDING` | 待出单 | +| `ACTIVE` | 已生效 | +| `FAILED` | 出单失败 | +| `CANCELLED` | 已退保 | + +### 6.13 refund application status(退款申请状态) + +**使用字段**:§3.8 出参 `applications[].status` + +| 值 | 说明 | +|----|------| +| `PENDING_APPROVE` | 待审批 | +| `PENDING_PAYOUT` | 财务已审批,待打款 | +| `PENDING_ARRIVAL` | 已打款,待到账 | +| `COMPLETED` | 退款完成(已到账) | +| `REJECTED` | 已拒绝 | + +### 6.14 refund progress step(退款进度步骤) + +**使用字段**:§3.8 出参 `applications[].progress[].step` + +| 值 | 说明 | +|----|------| +| `APPLY` | 退款申请 | +| `APPROVE` | 财务审批 | +| `PAYOUT` | 退款打款 | +| `ARRIVED` | 到账确认 | + +### 6.15 tag type(标签类型) + +**使用字段**:§3.3 出参 `tags[].type` + +| 值 | 说明 | +|----|------| +| `SYSTEM` | 系统自动打的标签 | +| `PERSONAL` | 定制师手动打的标签 | +| `MANUAL` | 主管手动打的标签 | + +### 6.16 traveler & exception badge(出行人 / 异常态字段) + +`OverviewVO.travelers[]` 的 `travelerType` / `idType` / `profileStatus` 等枚举详见 traveler 模块 §2.1 出行人列表 changelog。 + +`OrderMainVO.exceptionBadges` 9 类布尔标识 / `progressStepper.nodes[].key` / `progressStepper.nodes[].status` 字段含义已在 §3.3 出参说明中列出。 --- @@ -861,9 +1213,9 @@ GET /v3/admin/order/60999999999999 ## 12. 注意事项 -- **§1.3.4 itinerary 子接口数据 Mock**:当前返回占位数据,前端可先按字段结构对接,真实化后无需改字段口径 -- **§1.3.6 / §1.3.7 条件显示**:前端拿到 `data=null` 时不渲染对应 Tab -- **主聚合 vs 子接口性能取舍**:首屏用主聚合(1 次请求拿全);单 Tab 刷新用子接口(响应更小) +- **§3.6 itinerary 子接口数据 Mock**:当前返回占位数据,前端按字段结构对接即可,真实化后无需改字段口径 +- **§3.8 / §3.9 条件显示**:`data=null` 时前端不渲染对应 Tab +- **首屏 vs 单 Tab 刷新**:详情页打开用 §3.3 主聚合(一次拿 main + tags + overview);Tab 切换 / 单 Tab 操作完按需调 §3.4 ~ §3.9 - **公司隔离 581021**:所有 §1 接口均带跨公司隔离校验,前端无需自行过滤 ---