# CUSTOM 定制模块迁移到 hl-product-service-v2

**日期**: 2026-04-19
**PR**: [#895](https://git.1814.love:8443/wx/HL/pulls/895)（v2+order+user 基础设施）+ [#897](https://git.1814.love:8443/wx/HL/pulls/897)（gateway 切路由）→ dev → 测试环境
**影响端**: 小程序 (hl-ui-mp)
**部署服务**: hl-order-service-v2 + hl-product-service-v2 + hl-user-service + hl-gateway

## 总体变化（对前端**完全透明**）

小程序 `/mp/custom/**` 7 个接口的后端实现从 `hl-mp-service` 迁移到 `hl-product-service-v2`。**接口路径、请求参数、响应字段完全保持兼容**（通过 v2 端新 `MpCustomizeController` 7 个 endpoint 1:1 适配 + 镜像 DTO 字段 1:1 对齐实现）。

## 受影响的 7 个接口

| 路径 | 功能 | 鉴权 |
|---|---|---|
| `POST /mp/custom/submit` | 提交定制需求 | 登录 |
| `GET /mp/custom/list?page=&pageSize=` | 我的定制需求列表（分页） | 登录 |
| `GET /mp/custom/detail?id=` | 定制需求详情 | 登录 |
| `POST /mp/custom/{requestId}/cancel` | 取消定制需求 | 登录 |
| `GET /mp/custom/product/{productId}` | 已完成定制产品详情 | 免登录 |
| `GET /mp/custom/products` | 我的已完成定制产品列表（按手机号+定制需求聚合） | 登录 |
| `GET /mp/custom/products/all?page=&pageSize=` | 全部已完成定制产品分页浏览 | 免登录 |

## 字段/结构一致性保证

- 所有 Long ID 用 String 序列化（防 JS 精度丢失）— 与原 mp-service 行为一致
- 所有 BigDecimal 金额用 String 序列化 — 不变
- 日期格式 `yyyy-MM-dd HH:mm:ss` — 不变
- 分页结构 `{records, total, page, pageSize}` — 不变
- 定制需求字段：id / userId / status / travelPurpose / requestType / departureDate / returnDate / days / adultCount / childCount / budget / destination / requirements / contactName / contactPhone / designerId / designerName / designerAvatar / reply / replyAt / createdAt / updatedAt — **全部一致**
- 定制产品字段：复用原有 `MpCustomProductDetailVO` / `MpCustomProductListVO` 字段设计

## 修复（顺便）

本次迁移**顺便修复了数据丢失级 bug**：定制需求提交（POST /mp/custom/submit）之前丢失 7 个字段未映射到数据库（`requestType` / `startDate` / `endDate` / `days` / `childCount` / `contactPhone` / `contactName`），迁移后这些字段正确持久化。**此前提交的定制需求可能缺这些字段，后续提交正常**。

## 不影响

- 接口路径、请求参数、响应字段结构、HTTP code、业务码完全不变
- mp 端 VO（`MpCustomProductDetailVO` / `MpCustomProductListVO` 等）字段不变
- 鉴权流程不变（`X-User-Id` header 透传）

## 需要前端做的事

**无需任何代码改动**。如发现具体接口异常请反馈 productId/requestId/参数。

## 后端实现要点（供前端排障参考）

- gateway 路由：`Path=/mp/product/**,/mp/product-line/**,/mp/custom/**` 统一走 `hl-product-service-v2`
- v2 新建 `MpCustomizeController` + `MpCustomizeAggregatorService` 编排 3 个下游 Feign：
  - `CustomizeOrderFeignClient`（调 hl-order-service-v2 customize_request）
  - `CustomizeUserProfileFeignClient`（调 hl-user-service 拿手机号）
  - 复用 v2 已有 `InternalMpCustomProductService`（PR #883）+ `RefundPolicyFeignClient`
- 手机号 PII 4 层防御：VO Javadoc 约束 + 自建 RateLimiter(100 QPS/phone) + Hutool DesensitizedUtil 日志脱敏 + 越权校验
- 42 单测（7 + 14 order-v2 + 12 v2 + 9 user-service）全过

## 测试环境实测

```bash
curl https://api.test.1814.love:9443/mp/custom/products/all?page=1&pageSize=2
# HTTP 200, 返回 2 条真实 CUSTOM 产品, 字段结构与旧接口 1:1 一致
```

## 已知未修项（独立工单）

1. order-v2 admin 端 `CustomizeRequestVO` 字段名错（travelCount / budgetRange / remark / replyContent）与 DB + mp 端不一致，为避免破坏 admin 前端**暂保留**，待独立工单专项修复
2. mp-service 的 `MpCustomizeController` 已成死代码（路由不经过），将通过 PR-3 单独清理（24h 稳定期后）

🤖 Generated with [Claude Code](https://claude.com/claude-code)
