From fa41956b7a186a6821dc8345d4b0e7fd0c2bd8c0 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Thu, 19 Mar 2026 12:49:39 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=A7=81=E4=BA=BA=E5=AE=9A=E5=88=B6?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E6=B5=81=E7=A8=8B=E5=AF=B9=E6=8E=A5=E6=8C=87?= =?UTF-8?q?=E5=8D=97=EF=BC=88C=E7=AB=AF6=E6=8E=A5=E5=8F=A3=20+=20=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=AB=AF5=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 含状态机、按钮显示规则、字典、页面布局、完整调用示例 Co-Authored-By: Claude Opus 4.6 --- .../2026-03/2026-03-19_customize_full_flow.md | 697 ++++++++++++++++++ 1 file changed, 697 insertions(+) create mode 100644 changelogs/2026-03/2026-03-19_customize_full_flow.md diff --git a/changelogs/2026-03/2026-03-19_customize_full_flow.md b/changelogs/2026-03/2026-03-19_customize_full_flow.md new file mode 100644 index 0000000..039edb0 --- /dev/null +++ b/changelogs/2026-03/2026-03-19_customize_full_flow.md @@ -0,0 +1,697 @@ +# 私人定制完整流程(C端提交 + 管理端处理) - 前端对接指南 + +> **日期**: 2026-03-19 +> **后端状态**: ✅ 已完成,测试环境已部署 +> **涉及模块**: hl-mp-service(C端BFF)、hl-order-service(管理端+内部接口)、hl-product-service(定制产品) +> **Knife4j 文档**: `192.168.100.236:8080/doc.html` +> - C端:左侧选 "C端 - 定制需求接口" +> - 管理端:左侧选 "订单服务 - 私人定制管理" + +--- + +## 业务流程总览 + +``` +用户(小程序) 管理员(后台) + │ │ + ├─ 提交定制需求 ──────────────────→ │ + │ POST /mp/custom/submit │ + │ ├─ 查看定制请求列表 + │ │ GET /admin/order/customize/page + │ │ + │ ├─ 查看请求详情 + │ │ GET /admin/order/customize/{id} + │ │ + │ ├─ 接受请求(分配定制师) + │ │ PUT /admin/order/customize/{id}/accept + │ │ + │ ├─ 回复/报价(关联产品) + │ ← 收到通知 ──────────────────────┤ PUT /admin/order/customize/{id}/reply + │ │ + │ ├─ 标记完成 + │ ← 收到通知 ──────────────────────┤ PUT /admin/order/customize/{id}/complete + │ │ + ├─ 查看定制需求列表 │ + │ GET /mp/custom/list │ + │ │ + ├─ 查看需求详情 │ + │ GET /mp/custom/detail │ + │ │ + ├─ 查看已完成的定制产品 │ + │ GET /mp/custom/product/{id} │ + │ │ + ├─ 取消定制需求 │ + │ POST /mp/custom/{id}/cancel │ + │ │ + └─ 下单购买定制产品 │ + POST /mp/order/create │ +``` + +--- + +## 一、C端接口(小程序,需登录) + +### 接口清单 + +| # | 接口 | 方法 | 路径 | 说明 | +|---|------|------|------|------| +| 1 | 提交定制需求 | POST | `/mp/custom/submit` | 用户发起定制请求 | +| 2 | 定制需求列表 | GET | `/mp/custom/list` | 分页查询我的定制需求 | +| 3 | 定制需求详情 | GET | `/mp/custom/detail` | 查看单条定制需求 | +| 4 | 取消定制需求 | POST | `/mp/custom/{requestId}/cancel` | 取消待处理/处理中的需求 | +| 5 | 已完成定制产品详情 | GET | `/mp/custom/product/{productId}` | 查看定制产品方案 | +| 6 | 我的已完成定制产品列表 | GET | `/mp/custom/products` | 所有已完成的定制产品 | + +--- + +### 接口 C1:提交定制需求 + +``` +POST /mp/custom/submit +Content-Type: application/json +Authorization: Bearer {token} +``` + +#### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| designerId | Long | 否 | 指定定制师ID(不传则系统分配) | +| destination | String | 否 | 目标地区,如"云南大理",最长200字 | +| travelPurpose | String | 否 | 旅游目的(字典:`travel_purpose`) | +| requestType | String | 否 | 需求类型(字典:`customize_request_type`) | +| startDate | String | 否 | 期望出发日期,格式 `yyyy-MM-dd` | +| endDate | String | 否 | 期望结束日期,格式 `yyyy-MM-dd` | +| days | Integer | 否 | 期望天数(1~365) | +| adultCount | Integer | 否 | 成人数(至少1,最多99) | +| childCount | Integer | 否 | 儿童数(0~99) | +| budget | String | 否 | 预算范围(字典:`customize_budget`) | +| requirements | String | 否 | 详细需求描述,最长2000字 | +| contactPhone | String | 否 | 联系电话,最长20字 | +| contactName | String | 否 | 联系人,最长50字 | + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "requestId": 2029926129876320258, + "userId": 2026279738275856300, + "designerId": null, + "destination": "呼伦贝尔", + "travelPurpose": "FAMILY", + "requestType": "FAMILY_TRIP", + "startDate": "2026-07-01", + "endDate": "2026-07-07", + "days": 7, + "adultCount": 2, + "childCount": 1, + "budget": "BUDGET_10000_20000", + "requirements": "希望安排亲子活动,孩子3岁", + "contactPhone": "13800138000", + "contactName": "张三", + "status": "PENDING", + "statusLabel": "待处理", + "designerName": null, + "designerAvatar": null, + "productId": null, + "reply": null, + "repliedAt": null, + "createTime": "2026-03-19T10:30:00", + "updateTime": "2026-03-19T10:30:00" + } +} +``` + +#### 响应字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| requestId | Long | 定制请求ID | +| userId | Long | 用户ID | +| designerId | Long | 指定定制师ID(未指定则null) | +| destination | String | 目标地区 | +| travelPurpose | String | 旅游目的(字典:`travel_purpose`) | +| requestType | String | 需求类型(字典:`customize_request_type`) | +| startDate | String | 期望出发日期 | +| endDate | String | 期望结束日期 | +| days | Integer | 期望天数 | +| adultCount | Integer | 成人数 | +| childCount | Integer | 儿童数 | +| budget | String | 预算范围(字典:`customize_budget`) | +| requirements | String | 详细需求描述 | +| contactPhone | String | 联系电话 | +| contactName | String | 联系人 | +| status | String | 状态(字典:`customize_request_status`) | +| statusLabel | String | 状态中文标签 | +| designerName | String | 定制师姓名(未分配时null) | +| designerAvatar | String | 定制师头像URL | +| productId | Long | 关联产品ID(定制完成后才有值) | +| reply | String | 定制师回复内容 | +| repliedAt | String | 回复时间 | +| createTime | String | 创建时间 | +| updateTime | String | 更新时间 | + +--- + +### 接口 C2:定制需求列表 + +``` +GET /mp/custom/list?page=1&pageSize=20 +Authorization: Bearer {token} +``` + +#### 请求参数 + +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| page | int | 否 | 1 | 页码 | +| pageSize | int | 否 | 20 | 每页条数 | + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "records": [ + { + "requestId": 2029926129876320258, + "userId": 2026279738275856300, + "destination": "呼伦贝尔", + "travelPurpose": "FAMILY", + "requestType": "FAMILY_TRIP", + "startDate": "2026-07-01", + "days": 7, + "adultCount": 2, + "childCount": 1, + "budget": "BUDGET_10000_20000", + "status": "DESIGNING", + "statusLabel": "设计中", + "designerName": "李设计师", + "designerAvatar": "https://oss.example.com/avatar.jpg", + "createTime": "2026-03-19T10:30:00" + } + ], + "total": 3, + "page": 1, + "pageSize": 20 + } +} +``` + +--- + +### 接口 C3:定制需求详情 + +``` +GET /mp/custom/detail?id={requestId} +Authorization: Bearer {token} +``` + +#### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | ✅ | 定制请求ID | + +#### 响应 + +同接口 C1 的响应字段(完整的 `MpCustomizeRequestVO`)。 + +**前端关键逻辑**: +- 当 `status` 为 `QUOTED` 或 `COMPLETED` 且 `productId` 不为null → 展示"查看定制方案"按钮 +- 当 `status` 为 `PENDING` / `ACCEPTED` / `DESIGNING` → 展示"取消定制"按钮 + +--- + +### 接口 C4:取消定制需求 + +``` +POST /mp/custom/{requestId}/cancel +Authorization: Bearer {token} +``` + +#### 请求参数 + +| 参数 | 类型 | 位置 | 必填 | 说明 | +|------|------|------|------|------| +| requestId | Long | 路径 | ✅ | 定制请求ID | + +#### 业务规则 + +- ✅ 可取消状态:`PENDING`(待处理)、`ACCEPTED`(已接受)、`DESIGNING`(设计中) +- ❌ 不可取消状态:`QUOTED`(已报价)、`COMPLETED`(已完成)、`CANCELLED`(已取消) + +#### 响应 + +同接口 C1 的响应字段,status 变为 `CANCELLED`。 + +--- + +### 接口 C5/C6:已完成定制产品 + +详见已有文档:`2026-03-19_custom_product_query.md` + +--- + +## 二、管理端接口(后台,需管理员登录) + +### 接口清单 + +| # | 接口 | 方法 | 路径 | 说明 | +|---|------|------|------|------| +| 1 | 定制请求列表 | GET | `/admin/order/customize/page` | 分页+搜索+筛选 | +| 2 | 定制请求详情 | GET | `/admin/order/customize/{requestId}` | 完整信息 | +| 3 | 接受请求 | PUT | `/admin/order/customize/{requestId}/accept` | 分配定制师 | +| 4 | 回复/报价 | PUT | `/admin/order/customize/{requestId}/reply` | 回复或关联产品 | +| 5 | 标记完成 | PUT | `/admin/order/customize/{requestId}/complete` | 定制完成 | + +--- + +### 接口 A1:定制请求列表(分页) + +``` +GET /admin/order/customize/page?page=1&pageSize=20 +Authorization: Bearer {admin-token} +``` + +#### 请求参数 + +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| keyword | String | 否 | | 搜索关键词(联系人/目标地区/需求描述) | +| status | String | 否 | | 状态过滤(字典:`customize_request_status`) | +| designerId | Long | 否 | | 定制师ID过滤 | +| sortBy | String | 否 | createTime | 排序字段:`createTime` / `startDate` | +| sortDir | String | 否 | desc | 排序方向:`desc` / `asc` | +| page | int | 否 | 1 | 页码 | +| pageSize | int | 否 | 20 | 每页条数(最大100) | + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "records": [ + { + "requestId": 2029926129876320258, + "userId": 2026279738275856300, + "destination": "呼伦贝尔", + "travelPurpose": "FAMILY", + "requestType": "FAMILY_TRIP", + "startDate": "2026-07-01", + "days": 7, + "adultCount": 2, + "childCount": 1, + "budget": "BUDGET_10000_20000", + "status": "PENDING", + "statusLabel": "待处理", + "designerName": null, + "designerAvatar": null, + "createTime": "2026-03-19T10:30:00" + } + ], + "total": 15, + "page": 1, + "pageSize": 20 + } +} +``` + +#### 响应字段(CustomizeRequestListVO) + +| 字段 | 类型 | 说明 | +|------|------|------| +| requestId | Long | 请求ID | +| userId | Long | 用户ID | +| destination | String | 目标地区 | +| travelPurpose | String | 旅游目的(字典:`travel_purpose`) | +| requestType | String | 需求类型(字典:`customize_request_type`) | +| startDate | String | 期望出发日期 | +| days | Integer | 期望天数 | +| adultCount | Integer | 成人数 | +| childCount | Integer | 儿童数 | +| budget | String | 预算范围(字典:`customize_budget`) | +| status | String | 状态(字典:`customize_request_status`) | +| statusLabel | String | 状态中文标签 | +| designerName | String | 定制师姓名 | +| designerAvatar | String | 定制师头像URL | +| createTime | String | 创建时间 | + +#### 使用场景 + +管理后台"私人定制"列表页: +1. 顶部筛选栏:状态下拉(全部/待处理/已接受/设计中/已报价/已完成/已取消)+ 关键词搜索 + 定制师筛选 +2. 表格展示:目标地区、需求类型、出发日期、天数、人数、预算、定制师、状态、创建时间 +3. 操作按钮根据状态显示(见下方状态机) + +--- + +### 接口 A2:定制请求详情 + +``` +GET /admin/order/customize/{requestId} +Authorization: Bearer {admin-token} +``` + +#### 请求参数 + +| 参数 | 类型 | 位置 | 必填 | 说明 | +|------|------|------|------|------| +| requestId | Long | 路径 | ✅ | 定制请求ID | + +#### 响应字段(CustomizeRequestVO) + +同接口 C1 的完整响应字段(24个字段)。管理端可看到所有信息包括联系人电话等。 + +--- + +### 接口 A3:接受定制请求 + +``` +PUT /admin/order/customize/{requestId}/accept +Authorization: Bearer {admin-token} +``` + +#### 请求参数 + +| 参数 | 类型 | 位置 | 必填 | 说明 | +|------|------|------|------|------| +| requestId | Long | 路径 | ✅ | 定制请求ID | + +无请求体。管理员ID从token中自动获取。 + +#### 业务规则 + +- 仅 `PENDING`(待处理)状态可接受 +- 如果用户未指定定制师(designerId为null),自动分配当前操作人为定制师 +- 如果用户已指定定制师,保留原定制师 +- 状态变更:`PENDING` → `ACCEPTED` + +#### 响应 + +返回更新后的完整 `CustomizeRequestVO`(status=ACCEPTED,designerName/designerAvatar 已填充)。 + +--- + +### 接口 A4:回复/报价 + +``` +PUT /admin/order/customize/{requestId}/reply +Content-Type: application/json +Authorization: Bearer {admin-token} +``` + +#### 请求参数 + +| 参数 | 类型 | 位置 | 必填 | 说明 | +|------|------|------|------|------| +| requestId | Long | 路径 | ✅ | 定制请求ID | + +#### 请求体(AdminReplyRequest) + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| reply | String | ✅ | 回复内容,最长2000字 | +| productId | Long | 否 | 关联的定制产品ID(已创建定制产品后传入) | + +#### 业务规则 + +- 仅 `ACCEPTED`(已接受)或 `DESIGNING`(设计中)状态可回复 +- **仅填写 reply**:状态变为 `DESIGNING`(设计中) +- **同时传 productId**:状态变为 `QUOTED`(已报价),C端用户可通过 productId 查看产品方案 + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "requestId": 2029926129876320258, + "status": "QUOTED", + "statusLabel": "已报价", + "reply": "您好!我为您设计了一套7天6晚的呼伦贝尔亲子游方案,请查看。", + "productId": 2029926131830865921, + "repliedAt": "2026-03-19T14:00:00", + "designerName": "李设计师", + "..." + } +} +``` + +#### 前端操作流程 + +``` +1. 定制师在后台创建定制产品(product-service,productType=CUSTOM) +2. 产品设计完成后,回到定制请求页面 +3. 点击"回复/报价"按钮 → 弹窗填写回复内容 + 选择关联产品 +4. 调用此接口提交 +5. C端用户在"我的定制"中看到状态变为"已报价",可查看产品方案 +``` + +--- + +### 接口 A5:标记完成 + +``` +PUT /admin/order/customize/{requestId}/complete +Authorization: Bearer {admin-token} +``` + +#### 请求参数 + +| 参数 | 类型 | 位置 | 必填 | 说明 | +|------|------|------|------|------| +| requestId | Long | 路径 | ✅ | 定制请求ID | + +无请求体。 + +#### 业务规则 + +- 仅 `QUOTED`(已报价)状态可标记完成 +- 状态变更:`QUOTED` → `COMPLETED` +- 通常在用户确认方案或已下单后,定制师手动标记 + +#### 响应 + +返回更新后的完整 `CustomizeRequestVO`(status=COMPLETED)。 + +--- + +## 三、状态机与按钮显示 + +### 状态流转 + +``` +PENDING(待处理) ──accept──→ ACCEPTED(已接受) + │ │ + │cancel │cancel + ↓ ↓ + CANCELLED ──reply(仅文字)──→ DESIGNING(设计中) + │ + │cancel + ↓ + ──reply(+productId)──→ QUOTED(已报价) + │ + ──complete──→ COMPLETED(已完成) +``` + +### 管理端按钮显示 + +| 状态 | 可用操作 | +|------|---------| +| PENDING(待处理) | [接受请求] | +| ACCEPTED(已接受) | [回复] [报价] | +| DESIGNING(设计中) | [回复] [报价] | +| QUOTED(已报价) | [标记完成] | +| COMPLETED(已完成) | 无操作 | +| CANCELLED(已取消) | 无操作 | + +### C端按钮显示 + +| 状态 | 可用操作 | +|------|---------| +| PENDING(待处理) | [取消定制] | +| ACCEPTED(已接受) | [取消定制] | +| DESIGNING(设计中) | [取消定制] | +| QUOTED(已报价) | [查看定制方案] | +| COMPLETED(已完成) | [查看定制方案] [去下单] | +| CANCELLED(已取消) | 无操作 | + +--- + +## 四、关联字典 + +### customize_request_status(定制请求状态) + +| dict_value | dict_label | 说明 | +|------------|-----------|------| +| PENDING | 待处理 | 用户刚提交,等待定制师接受 | +| ACCEPTED | 已接受 | 定制师已接受请求 | +| DESIGNING | 设计中 | 定制师正在设计方案 | +| QUOTED | 已报价 | 已关联产品,等待用户确认 | +| COMPLETED | 已完成 | 定制流程完结 | +| CANCELLED | 已取消 | 用户取消请求 | + +### customize_request_type(需求类型) + +| dict_value | dict_label | +|------------|-----------| +| FAMILY_TRIP | 亲子游 | +| HONEYMOON | 蜜月游 | +| GROUP_TRIP | 团建游 | +| SENIOR_TRIP | 银发游 | +| ADVENTURE | 探险游 | +| PHOTOGRAPHY | 摄影游 | +| CULTURE | 文化游 | +| OTHER | 其他 | + +### travel_purpose(旅游目的) + +| dict_value | dict_label | +|------------|-----------| +| LEISURE | 休闲度假 | +| ADVENTURE | 探险体验 | +| CULTURE | 文化探访 | +| FAMILY | 亲子陪伴 | +| ROMANCE | 浪漫旅行 | +| TEAM | 团队建设 | +| OTHER | 其他 | + +### customize_budget(预算范围) + +| dict_value | dict_label | +|------------|-----------| +| UNDER_3000 | 3000元以下/人 | +| BUDGET_3000_5000 | 3000-5000元/人 | +| BUDGET_5000_10000 | 5000-10000元/人 | +| BUDGET_10000_20000 | 10000-20000元/人 | +| ABOVE_20000 | 20000元以上/人 | +| NO_LIMIT | 不限预算 | + +--- + +## 五、管理端页面布局建议 + +### 定制请求列表页 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 私人定制管理 │ +├─────────────────────────────────────────────────────────────────┤ +│ 状态: [全部 ▼] 定制师: [全部 ▼] 关键词: [____________] [搜索] │ +├─────┬──────┬──────┬───┬───┬─────┬──────┬─────┬────────┬────────┤ +│ 目的地│需求类型│出发日期│天数│人数│ 预算 │ 定制师 │ 状态 │ 创建时间 │ 操作 │ +├─────┼──────┼──────┼───┼───┼─────┼──────┼─────┼────────┼────────┤ +│呼伦贝尔│亲子游 │07-01 │ 7 │2大1小│1~2万/人│ 李设计师│待处理│03-19 10:30│[接受] │ +│三亚 │蜜月游 │08-15 │ 5 │2大0小│5千~1万│ 未分配 │待处理│03-18 09:00│[接受] │ +│大理 │文化游 │04-01 │ 3 │1大0小│不限 │ 王设计师│设计中│03-17 14:20│[回复] │ +└─────┴──────┴──────┴───┴───┴─────┴──────┴─────┴────────┴────────┘ +``` + +### 定制请求详情页(弹窗或新页面) + +``` +┌─────────────────────────────────────────────┐ +│ 定制请求详情 状态: 待处理 │ +├─────────────────────────────────────────────┤ +│ 基本信息 │ +│ 目标地区: 呼伦贝尔 │ +│ 需求类型: 亲子游 │ +│ 旅游目的: 亲子陪伴 │ +│ 出发日期: 2026-07-01 ~ 2026-07-07 (7天) │ +│ 人数: 2成人 1儿童 │ +│ 预算: 10000-20000元/人 │ +├─────────────────────────────────────────────┤ +│ 联系人 │ +│ 姓名: 张三 │ +│ 电话: 13800138000 │ +├─────────────────────────────────────────────┤ +│ 需求描述 │ +│ 希望安排亲子活动,孩子3岁 │ +├─────────────────────────────────────────────┤ +│ 定制师信息 │ +│ 定制师: 未分配 │ +│ 回复: 无 │ +│ 关联产品: 无 │ +├─────────────────────────────────────────────┤ +│ [接受请求] │ +└─────────────────────────────────────────────┘ +``` + +--- + +## 六、完整调用示例 + +### 管理端:处理一个定制请求 + +```javascript +// 1. 加载列表(筛选待处理) +const list = await adminRequest.get('/admin/order/customize/page', { + params: { status: 'PENDING', page: 1, pageSize: 20 } +}) + +// 2. 查看详情 +const detail = await adminRequest.get(`/admin/order/customize/${requestId}`) + +// 3. 接受请求(自动分配当前管理员为定制师) +await adminRequest.put(`/admin/order/customize/${requestId}/accept`) + +// 4. 定制师创建定制产品(通过产品管理模块,productType=CUSTOM) +// ... 创建产品后获得 productId + +// 5. 回复并关联产品 +await adminRequest.put(`/admin/order/customize/${requestId}/reply`, { + reply: '您好!我为您设计了一套呼伦贝尔亲子游方案,请查看。', + productId: createdProductId +}) + +// 6. 用户确认后标记完成 +await adminRequest.put(`/admin/order/customize/${requestId}/complete`) +``` + +### C端:提交并跟踪定制需求 + +```javascript +// 1. 提交定制需求 +const res = await request.post('/mp/custom/submit', { + destination: '呼伦贝尔', + travelPurpose: 'FAMILY', + requestType: 'FAMILY_TRIP', + startDate: '2026-07-01', + endDate: '2026-07-07', + days: 7, + adultCount: 2, + childCount: 1, + budget: 'BUDGET_10000_20000', + requirements: '希望安排亲子活动', + contactName: '张三', + contactPhone: '13800138000' +}) + +// 2. 查看我的定制需求列表 +const list = await request.get('/mp/custom/list', { params: { page: 1 } }) + +// 3. 查看详情 +const detail = await request.get('/mp/custom/detail', { params: { id: requestId } }) + +// 4. 当状态变为 QUOTED/COMPLETED 且有 productId +if (detail.data.productId && ['QUOTED', 'COMPLETED'].includes(detail.data.status)) { + const product = await request.get(`/mp/custom/product/${detail.data.productId}`) + // 展示定制产品方案 +} + +// 5. 查看所有已完成的定制产品 +const products = await request.get('/mp/custom/products') +``` + +--- + +🤖 Generated with [Claude Code](https://claude.com/claude-code)