diff --git a/changelogs/2026-05/18_2355_admin-order-v3-create-sharer-customizer.md b/changelogs/2026-05/18_2355_admin-order-v3-create-sharer-customizer.md new file mode 100644 index 0000000..06ed44b --- /dev/null +++ b/changelogs/2026-05/18_2355_admin-order-v3-create-sharer-customizer.md @@ -0,0 +1,196 @@ +# ⚠️✨ 管理端代下单接口 v3 新增分享追踪字段 + consultantSource 枚举新增 SHARED + +> **服务**: hl-order-service-v3 +> **接口**: `POST /admin/v3/orders` +> **PR**: #2565 refactor(order-v3): [Agency PR-4 / PR-1] 订单创建补 5 项基础逻辑 +> **日期**: 2026-05-18 23:55 +> **影响页面**: 管理后台「代下单」流程 + 小程序下单(通过 hl-mp-service 透传同接口) + +--- + +## 变了什么(前端视角) + +### 1. 请求体新增 2 个非必填字段 + +`POST /admin/v3/orders` 的请求 body 新增以下字段,**不传或传 null 行为与改造前完全一致**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `sharerOpenid` | String | 否 | 分享人微信 openid,用于 C 端裂变追踪 / 佣金归属。落表 `order_info.sharer_openid`,admin 代下单时通常不传 | +| `customizerId` | Long | 否 | C 端分享归因:从分享链接中带入的定制师 adminId。校验通过则锁定为该定制师(`consultantSource = SHARED`),校验失败兜底系统默认定制师 | + +**注意**:`customizerId` 类型必须是 **number(Long)**,不能传 string。 + +### 2. 响应体枚举 consultantSource 新增值 SHARED + +`OrderCreateRespVO` 中 `consultantSource` 字段的枚举值新增 `SHARED`: + +| 枚举值 | 含义 | 何时出现 | +|--------|------|---------| +| `DEFAULT_ASSIGNED` | 系统默认定制师 | C 端下单,customizerId 为空或校验不通过,且有系统默认定制师 | +| `LINK_BOUND` | 链接绑定定制师 | 历史逻辑(v2 遗留) | +| `MANUAL` | admin 手动指定 | admin 代下单时由 JWT adminId 指定 | +| `SHARED`(**新增**) | C 端分享锁定定制师 | C 端下单,customizerId 校验通过 | + +### 3. 新增可能抛出的错误码 + +| code | message | 触发场景 | +|------|---------|---------| +| `581035` | 订金金额不得超过订单总额 | DEPOSIT 模式下订金金额 > 订单总额时触发 | + +### 4. 行为收紧(字段名不变,错误码变化) + +| 场景 | 旧行为 | 新行为 | +|------|--------|--------| +| Agency 无默认 mchId | 抛 `MCH_RESOLVE_FAILED` | 抛 `AGENCY_NO_DEFAULT_MCHID` | +| customerName / customerRemark 含 HTML 标签 | 原样入库 | XSS 过滤后入库(前端无感,被清掉的标签不会报错) | + +--- + +## 前端要改的地方 + +### 管理后台 B 端 + +1. **consultantSource 展示标签**:若订单详情 / 列表有按 `consultantSource` 显示来源文案的地方,需补 `SHARED` 的 case,建议展示文案为**"分享锁定"**: + + ```js + // 建议 + const consultantSourceLabel = { + DEFAULT_ASSIGNED: '系统分配', + LINK_BOUND: '链接绑定', + MANUAL: '手动指定', + SHARED: '分享锁定', // 新增 + } + ``` + +2. **错误码监控 / 提示**:若代下单流程中有按错误码展示错误提示,建议给 `581035` 加 case,文案直接透传后端 message:`"订金金额不得超过订单总额"`。 + + 若之前有对 `MCH_RESOLVE_FAILED` 的特殊提示逻辑,需同步改为 `AGENCY_NO_DEFAULT_MCHID`。 + +### 小程序 C 端(通过 hl-mp-service 透传) + +3. **分享链接带 customizerId 下单**:从分享 URL 取出 `adminId`,下单时透传为 `customizerId`(参考 `07_feat_share_lock_customizer.md` 详细步骤): + + ```js + const customizerId = uni.getStorageSync('share_customizer_id') || null + // 放入 POST /mp/order/create 或 POST /admin/v3/orders 的请求体 + ``` + +4. **分享追踪 sharerOpenid**:若小程序有分享溯源需求(如显示"由 XXX 分享"),可在下单时透传 `sharerOpenid`;不传也不影响下单流程。 + +--- + +## 接口详细定义 + +### POST /admin/v3/orders — 管理端 / C 端创建订单 + +- **使用场景**:管理后台代客户下单,或 C 端小程序通过 hl-mp-service 创建订单 +- **方法**: `POST` +- **路径**: `/admin/v3/orders`(通过 gateway 路由到 hl-order-service-v3) + +#### 请求参数(Body JSON) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `productId` | Long | 是 | 产品 ID | +| `productType` | String | 是 | 产品类型(CORE / ACTIVITY 等) | +| `startDate` | String | 是 | 出发日期,格式 `yyyy-MM-dd` | +| `adultCount` | Integer | 是 | 成人人数,≥ 1 | +| `childCount` | Integer | 否 | 儿童人数,默认 0 | +| `customerName` | String | 是 | 客户姓名(会走 XSS 过滤,HTML 标签会被清除) | +| `customerPhone` | String | 是 | 客户手机号 | +| `customerRemark` | String | 否 | 客户备注(会走 XSS 过滤) | +| `sharerOpenid` | String | 否 | **[新增]** 分享人微信 openid,C 端裂变追踪用 | +| `customizerId` | Long | 否 | **[新增]** 分享人定制师 adminId,校验通过则锁定为本单定制师 | + +#### 请求示例(含新增字段) + +```json +{ + "productId": 10001, + "productType": "CORE", + "startDate": "2026-06-01", + "adultCount": 2, + "childCount": 0, + "customerName": "张三", + "customerPhone": "13800138000", + "customerRemark": "需要靠窗座位", + "sharerOpenid": "oXXXXXXXXXXX", + "customizerId": 50001 +} +``` + +#### 响应结构 + +```json +{ + "code": 200, + "msg": "success", + "data": { + "orderId": "202605181234567890", + "orderNo": "HL202605181234", + "totalAmount": 9800, + "depositAmount": 2000, + "consultantId": 50001, + "consultantName": "李定制师", + "consultantSource": "SHARED" + } +} +``` + +#### 响应字段说明 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `orderId` | String | 雪花 ID,前端按字符串处理(Long 精度问题) | +| `orderNo` | String | 可读订单号 | +| `totalAmount` | Integer | 订单总额(分) | +| `depositAmount` | Integer | 订金金额(分),DEPOSIT 模式下有值 | +| `consultantId` | Long | 绑定的定制师 adminId | +| `consultantName` | String | 定制师姓名 | +| `consultantSource` | String | 定制师来源枚举,见下表 | + +#### consultantSource 枚举值完整列表 + +| 值 | 中文展示建议 | 触发场景 | +|----|------------|---------| +| `DEFAULT_ASSIGNED` | 系统分配 | C 端下单,customizerId 无效或未传,有系统默认定制师 | +| `LINK_BOUND` | 链接绑定 | 历史逻辑(v2 遗留,v3 基本不再出现) | +| `MANUAL` | 手动指定 | admin 代下单,由登录态 JWT adminId 指定 | +| `SHARED` | 分享锁定 | C 端下单,`customizerId` 校验通过(定制师有效且角色正确) | + +--- + +## 错误码完整列表(本接口可能返回) + +| code | message | 处理建议 | +|------|---------|---------| +| `200` | success | 正常 | +| `400` | 参数校验失败 | 检查必填字段 | +| `581035` | 订金金额不得超过订单总额 | **[新增]** 直接 toast 后端 message | +| `AGENCY_NO_DEFAULT_MCHID` | Agency 未配置默认收款账号 | 联系运营配置 agency 默认 mchId | + +--- + +## 兼容性 + +- 请求字段仅新增非必填字段,**向后兼容**(旧版前端不传新字段行为不变) +- 响应枚举仅新增值不删值,**向后兼容** +- 无 DDL 变更,无需数据迁移 +- 只需重启 `hl-order-service-v3`,`hl-mp-service` 无需重启 + +--- + +## customizerId 校验兜底语义(前端无需实现) + +后端 `CustomizerValidator` 校验失败时**全部静默兜底为系统默认定制师,不报错**: + +| 失败原因 | 触发条件 | 前端表现 | +|---------|---------|---------| +| `ADMIN_NOT_FOUND` | adminId 不存在 / 已删除 | 兜底随机,静默 | +| `INACTIVE_STATUS` | admin status ≠ ACTIVE | 兜底随机,静默 | +| `WRONG_ROLE` | admin roleKey ≠ CUSTOMIZER | 兜底随机,静默 | +| `FEIGN_ERROR` | user-service Feign 调用失败 | 兜底随机,静默 | +| `INVALID_INPUT` | customizerId == null / ≤ 0 | 兜底随机,静默 | + +前端不需要对这些失败场景做任何处理。