diff --git a/changelogs/2026-04/20260421-review-migrate-to-order-v2.md b/changelogs/2026-04/20260421-review-migrate-to-order-v2.md new file mode 100644 index 0000000..e8bd670 --- /dev/null +++ b/changelogs/2026-04/20260421-review-migrate-to-order-v2.md @@ -0,0 +1,230 @@ +# 评价模块迁移到 order-v2 服务(URL 不变 / 状态机对照 / Feign 链路变化) + +> **日期**:2026-04-21 +> **服务**:`hl-user-service` → `hl-order-service`(v2) +> **PR**:#1130(merge commit `cff993d12e3eb33f8c19d14bb18a9de001f5f971`) +> **类型**:后端跨服务迁移 / 重构 +> **前端调用影响**:✅ **REST 路径零变化,前端无需改代码**(本 changelog 只是告知 + 状态机对照,防止有硬编码状态常量踩坑) + +--- + +## 一、变更总览 + +评价(review)模块从 **hl-user-service** 整体搬到 **hl-order-service-v2**。 + +- **网关路由已同步切换**:`/admin/review/**` 原先由 gateway 转 `lb://hl-user-service`,现在转 `lb://hl-order-service`。前端用原 URL 直接调就行 +- **BFF(hl-mp-service)Feign 内部目标服务切换**:`MpReviewFeignClient(name="hl-user-service")` → `name="hl-order-service"`,小程序前端调 `/mp/review/**` 完全无感 +- **DB 真实表**从 `hl_user_service` / `hl_review_service`(VIEW + 废弃库)搬到 `hl_order_service_v2` +- **评价审核 5 状态 + 6 事件** 改用 cola 状态机(原先是 if-else 散写) + +--- + +## 二、受影响的 URL(全部路径不变) + +### 管理端(hl-ui)— 7 个 `/admin/review/**` + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/admin/review/list` | 评价列表(分页) | +| GET | `/admin/review/{reviewId}` | 评价详情 | +| POST | `/admin/review/{reviewId}/approve` | 人工审核通过 | +| POST | `/admin/review/{reviewId}/reject` | 人工审核拒绝 | +| POST | `/admin/review/{reviewId}/override-approve` | 覆盖通过(机审拒绝后管理员放行) | +| POST | `/admin/review/{reviewId}/reply` | 管理员回复 | +| PUT | `/admin/review/{reviewId}/keyword-tags` | 编辑评价关键词标签 | + +### 小程序端(hl-mp)— 14 个 `/mp/review/**` + 3 个 `/mp/like/**` + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/mp/review/rating-categories` | 评分类别字典 | +| GET | `/mp/review/filter-tags` | 过滤标签(支持 productCategory) | +| POST | `/mp/review/create` | 创建评价 | +| GET | `/mp/review/my` | 我的评价列表 | +| GET | `/mp/review/search` | 搜索评价 | +| GET | `/mp/review/target` | 按目标查(productId/customizerId 等) | +| GET | `/mp/review/product/{productId}` | 产品评价列表 | +| GET | `/mp/review/product/{productId}/highlights` | 产品精选好评 | +| GET | `/mp/review/stats` | 评价统计(平均分/好评率) | +| GET | `/mp/review/featured` | 首页/列表精选评价 | +| GET | `/mp/review/order/{orderId}/reviewed` | 订单是否已评价 | +| GET | `/mp/review/order/{orderId}/reviewable-targets` | 订单可评价目标列表 | +| POST | `/mp/review/{reviewId}/like` | 点赞 | +| GET | `/mp/review/{reviewId}/like/check` | 查询是否已点赞 | +| POST | `/mp/like/*`(3 个) | 透调评价点赞 Feign | + +### 其它端点(无变化) + +- 订单详情里"是否已评价"标记 `orders.is_reviewed`:由后端同事务内强一致更新(原本是 Feign + afterCommit 最终一致),前端字段取法不变 +- 评价图片/视频 OSS 链接字段 `images[].imageUrl` / `videos[].videoUrl`:位置、命名、协议不变 + +--- + +## 三、⚠️ 状态机改造 — 前端请核对硬编码状态常量 + +评价审核状态机重新梳理,**旧状态值有变**。如果前端存在状态字符串硬编码(status 字段 switch/判断),**必须参考下表确认取值是否还匹配**。 + +### 1. 状态对照表 + +| 老值(user-service 时代) | 新值(order-v2 时代) | 含义 | 前端处理建议 | +|---|---|---|---| +| `PENDING` | `PENDING_MODERATION` | 机审中(评价刚提交,异步跑阿里云绿网) | 若前端用此常量过滤"待审核",注意改名;建议改为判断 `status != 'APPROVED' && status != 'REJECTED'` | +| `MACHINE_PENDING` | `PENDING_MODERATION` | 同上(并入) | 老取值建议 fallback 兼容 | +| `MACHINE_BLOCKED` | `MACHINE_REJECTED` | 机审命中 block 级关键词,系统拒(但管理员可覆盖) | 改名 | +| `MACHINE_REVIEW` / 其他"待人工" | `PENDING_MANUAL` | 机审命中 review 级关键词,转人工复审 | 改名 | +| `APPROVED` | `APPROVED` | 审核通过 / 前台可见 | ✅ 不变 | +| `REJECTED` | `REJECTED` | 人工拒绝 / 前台不可见 | ✅ 不变 | +| `OVERRIDE_APPROVED` | 不再作为独立状态,覆盖后直接是 `APPROVED` | 原"管理员覆盖通过"独立状态 | ⚠️ 若前端用此判断"是否覆盖",改用 `machineResult.override == true` 或事件日志字段判断 | + +### 2. 新状态机(order-v2 侧实现) + +**5 个状态**(`ReviewStatus` 枚举): + +| 值 | 描述 | +|---|---| +| `PENDING_MODERATION` | 机审中(初始状态) | +| `PENDING_MANUAL` | 机审命中 review 级关键词,待人工复审 | +| `MACHINE_REJECTED` | 机审命中 block 级关键词,系统拒绝 | +| `APPROVED` | 审核通过(前台可见) | +| `REJECTED` | 人工拒绝(前台不可见) | + +**6 个事件**(`ReviewEvent`): + +| 事件 | 触发 | 转移 | +|---|---|---| +| `MACHINE_PASS` | 阿里云绿网回调通过 | `PENDING_MODERATION` → `APPROVED` | +| `MACHINE_FAIL_REVIEW` | 命中 review 级关键词 | `PENDING_MODERATION` → `PENDING_MANUAL` | +| `MACHINE_FAIL_BLOCK` | 命中 block 级关键词 | `PENDING_MODERATION` → `MACHINE_REJECTED` | +| `MANUAL_APPROVE` | 管理端 `/admin/review/{id}/approve` | `PENDING_MANUAL` → `APPROVED` | +| `MANUAL_REJECT` | 管理端 `/admin/review/{id}/reject` | `PENDING_MANUAL` → `REJECTED` | +| `ADMIN_OVERRIDE_APPROVE` | 管理端 `/admin/review/{id}/override-approve` | `MACHINE_REJECTED` → `APPROVED` | + +### 3. 状态显示建议(供 hl-ui / hl-mp 参考) + +```javascript +// 管理端列表筛选建议 +const ADMIN_FILTER = { + 待审核: ['PENDING_MODERATION', 'PENDING_MANUAL'], // 需要管理员关注 + 机审拒绝: ['MACHINE_REJECTED'], // 可覆盖通过 + 已通过: ['APPROVED'], + 已拒绝: ['REJECTED'], +}; + +// 小程序端(只关心是否已审核通过) +if (review.status === 'APPROVED') { + // 正常展示 +} else { + // 一般不展示或隐藏 +} +``` + +--- + +## 四、前端无感但内部链路变化 + +### 1. 创建评价:订单"已评价"标记改为强一致 + +- **老链路**(最终一致):`createReview` 成功 → afterCommit 调 `user-service.OrderReviewFeignClient → hl-order-service.PUT /internal/mp/order/{id}/mark-reviewed`(Feign 跨服务一次) +- **新链路**(强一致):review 与 order 同库同事务,`createReview` 同事务内直接更新 `orders.is_reviewed = 1` +- **前端体感**: + - 创建评价响应时间预计快 **50~100ms**(省一跳 Feign) + - 创建成功立刻查订单 `/mp/order/{orderId}` 的 `isReviewed` 字段就是 `true`,**不再有短暂不一致窗口**(老版本偶发 50ms 内查到 false) + +### 2. 管理端审核(approve / reject / override-approve) + +- 老:user-service 本地写 review.status → Feign 调 order-v2 → order.is_reviewed 更新 +- 新:order-v2 本地写 review.status + orders.is_reviewed(同事务) +- 响应时间预计 **快 30~50ms** + +### 3. 精选评价缓存键(Redis 内部实现,前端无直接感知) + +- 前缀保持 `review:featured:limit:{limit}`,TTL 600s±60s +- MP 侧兼容层前缀 `mp:review:featured*` 保持不变 +- 迁移后首次访问缓存 miss 约 1~3 秒回源,后续正常(业务调用量低,不影响体验) + +--- + +## 五、响应字段清单(仅列前端需要关注的 VO) + +### 管理端 `ReviewVO` / `ReviewListVO`(`/admin/review/**` 返回) + +| 字段 | 类型 | 说明 | 变化 | +|---|---|---|---| +| `reviewId` | Long | 评价 ID | - | +| `orderId` / `orderNo` | Long / String | 订单 | - | +| `userId` / `userName` / `userAvatar` | Long / String | 用户 | - | +| `productId` / `productName` / `productType` | Long / String | 产品 | productType 新增 `CUSTOM` 取值(已在 PR #935 生效,本 PR 无变化) | +| `targetType` / `targetId` | String / Long | 评价目标(PRODUCT/CUSTOMIZER/SCENIC 等) | - | +| `ratingItinerary` / `ratingAccommodation` / `ratingDriver` / `ratingDining` / `ratingOverall` | Integer (1~5) | 五维评分 | - | +| `ratingLevel` | String (GOOD/MEDIUM/BAD) | 评分等级 | - | +| `ratingAvg` | Decimal(2,1) | 平均分 | - | +| `content` | String | 评价内容 | - | +| `images[]` / `videos[]` | List | 图片/视频 | 字段名不变 | +| `specialAnswers` / `keywordTags` | JSON | 特殊问题 / 关键词标签 | - | +| `status` | String | ⚠️ 取值改,见第三节 | **改** | +| `rejectReason` | String | 拒绝原因 | - | +| `auditorName` / `auditedAt` | String / DateTime | 审核员/审核时间 | - | +| `adminReplyContent` / `adminReplyBy` / `adminReplyAt` | - | 管理员回复 | - | +| `likeCount` | Integer | 点赞数 | - | +| `createdAt` | DateTime | 创建时间 | ✅ **保持驼峰 `createdAt`**(虽然 DB 底层列改为 `create_time` 对齐 BaseDO,但 VO 对前端零变化) | +| `updatedAt` | DateTime | 更新时间 | ✅ 同上 | + +### 小程序端 `MpReviewVO`(`/mp/review/**` 返回) + +字段与 `ReviewVO` 核心一致,含 `reviewId / userName / userAvatar / productName / content / ratings* / images / videos / likeCount / createdAt / liked`(当前用户是否点赞)。 + +### `ReviewStatsVO`(统计接口返回) + +| 字段 | 类型 | 说明 | +|---|---|---| +| `totalCount` | Long | 总评价数 | +| `avgRating` | Decimal(2,1) | 平均评分 | +| `goodCount` / `mediumCount` / `badCount` | Long | 好/中/差评数 | +| `goodRate` | Decimal(5,2) | 好评率(百分比) | +| `hasImageCount` / `hasVideoCount` | Long | 有图/有视频评价数 | + +--- + +## 六、错误码对照 + +| HTTP | code | 说明 | 触发 | +|---|---|---|---| +| 200 | 200 | 成功 | - | +| 200 | 400 | 参数错误 | 评分不在 1-5 / 必填漏传 | +| 200 | 401 | 未登录 | `/mp/review/create` 等需 userId 的接口 | +| 200 | 403 | 无权限 | 管理端非管理员访问 `/admin/review/**` | +| 200 | 404 | 评价不存在 | review 已被软删或 ID 错误 | +| 200 | 409 | 状态非法转移 | ⚠️ **新增**:cola 状态机拒绝非法流转(例:对 `APPROVED` 再 `reject`) | +| 200 | 500 | 系统错误 | 保底 | +| 200 | 50001 | 机审服务暂不可用 | 阿里云绿网 SDK 超时/限流 | + +> 本项目 HTTP status 始终返回 200,业务码在 `Result.code`。 + +--- + +## 七、前端 TODO(如有硬编码) + +- [ ] **hl-ui 管理端**:搜索项目里硬编码的评价状态字符串(例如 `status === 'PENDING'`),按第三节对照表替换 +- [ ] **hl-mp 小程序端**: + - 大概率无需改(大部分地方直接取 `status === 'APPROVED'` 判断是否展示) + - 如有"审核中"状态展示(例如"我的评价"列表),状态值需从 `PENDING` / `MACHINE_PENDING` 替换为 `PENDING_MODERATION` / `PENDING_MANUAL` +- [ ] **无其它改动**:网关路径、字段命名、认证头(`X-User-Id` / `X-Admin-Id`)全部不变 + +--- + +## 八、回归验证建议(前端自测) + +- [ ] 提交评价 → 我的评价列表能看到(`status=PENDING_MODERATION` 或 `APPROVED`) +- [ ] 订单详情"已评价"标记立即刷新(不再有延迟窗口) +- [ ] 产品详情/精选评价列表加载正常 +- [ ] 评价点赞/取消点赞能实时更新 +- [ ] 管理端审核通过/拒绝 → 小程序端立即可见/隐藏 +- [ ] 管理端覆盖通过(机审拒绝后)→ 评价重新可见 + +--- + +## 九、联系人 + +- 后端负责人:wx / AI 协作(管理者) +- 相关任务文档:`docs/tasks/20260421_设计_评价模块迁移到order-v2.md` +- 重启服务清单(后端):hl-user-service / hl-order-service-v2 / hl-mp-service / hl-product-service-v2 / hl-gateway