hl-api-changelog/changelogs/2026-05/25_feat_review_revert_status_switch.md
API Changelog Bot 4d914be807 feat(评价): admin 已通过↔已拒绝评价可互转 + 必填理由 (HL #2983/PR #2985)
- 新增 POST /admin/review/{id}/revert body={targetStatus, remark}
- 仅允许 APPROVED↔REJECTED 互转, MACHINE_REJECTED 仍走 /override-approve
- ReviewVO/ReviewListVO 加 revertRemark 审计字段(MpReviewVO 不加)
- 错误码 551076 REVERT_STATUS_NOT_ALLOWED
- 现有 /approve /reject /override-approve 完全不动
2026-05-25 11:18:43 +08:00

5.1 KiB

feat(评价): 已通过↔已拒绝评价可互相切换(必填理由) — admin 端新增反转按钮

类型: feat (后端 + 前端均需改动) 关联 PR/Issue: PR #2985 (Closes #2983) 已合 dev,测试服已部署 日期: 2026-05-25 影响范围: admin 端「评价审核」(详情/列表),小程序端无影响 接收方: mmg 前端: admin 端需改造(已通过/已拒绝状态新增反转按钮 + 必填理由弹窗)


🎯 背景

现状管理员审核错了不能回退 —— APPROVED/REJECTED 都是终态。本次:

  • 已通过的评价可改为已拒绝
  • 已拒绝的评价可改为已通过
  • 互转必填理由(写入新字段 revertRemark 审计)
  • 机审拒绝(MACHINE_REJECTED)不在本次范围,仍走原有「覆盖通过」按钮 → /override-approve(不变)

📊 新增 1 个接口 POST /admin/review/{reviewId}/revert

Request body

{
  "targetStatus": "APPROVED",         // 必填,枚举 APPROVED / REJECTED
  "remark": "经核实评价内容真实,改为通过"  // 必填,1-500 字
}

Response

成功:{ "code": 200, "message": "成功", "data": null }

失败:

场景 code message
remark 空 400 反转备注不能为空
targetStatus 不是 APPROVED/REJECTED 400 目标状态仅支持 APPROVED 或 REJECTED
当前状态非 APPROVED/REJECTED 551076 评价状态不允许反转,仅 APPROVED ↔ REJECTED 可互转
targetStatus 与当前相同 551076 同上
评价不存在 404(NotFoundException) 评价不存在

允许的状态转换

当前 targetStatus 结果
APPROVED REJECTED ✓ 走 ADMIN_REVERT_TO_REJECT
REJECTED APPROVED ✓ 走 ADMIN_REVERT_TO_APPROVE
PENDING_MANUAL * ✗ 仍走 /approve/reject
MACHINE_REJECTED * ✗ 仍走 /override-approve
PENDING_MODERATION * ✗ 机审中,不操作
APPROVED APPROVED ✗ 同状态

📊 现有 3 个接口完全不动

接口 允许态 body 说明
/approve PENDING_MANUAL → APPROVED 维持现状
/reject PENDING_MANUAL → REJECTED rejectReason 必填 维持现状
/override-approve MACHINE_REJECTED → APPROVED 维持现状

📊 VO 新增字段 revertRemark

ReviewVO(详情)和 ReviewListVO(列表)新增:

{
  "reviewId": 100001,
  "status": "REJECTED",
  "rejectReason": "原始拒绝原因",
+ "revertRemark": "经核实评价内容真实,改为通过"   // 反转备注(可能 null)
}

MpReviewVO 不加(小程序无需展示)。

rejectReason 字段语义保持「PENDING_MANUAL → REJECTED 时的初次拒绝原因」,不动。revertRemark 是「终态反转操作的备注」,独立字段。


🎨 admin 前端期望改造

按钮联动

当前状态 → 显示的操作按钮:

status 显示按钮
PENDING_MANUAL 「通过」(/approve) / 「拒绝」(/reject 必填 rejectReason)
MACHINE_REJECTED 「覆盖通过」(/override-approve) — 不变
APPROVED 新增「改为拒绝」按钮 → 必填理由弹窗 → /revert {REJECTED, remark}
REJECTED 新增「改为通过」按钮 → 必填理由弹窗 → /revert {APPROVED, remark}
PENDING_MODERATION 无操作按钮(机审中)

详情展示

如果 revertRemark 非空,展示「最近一次反转备注:xxx(由 xxx 于 xxx 时间操作)」。审计字段 auditedAt / auditorName 现有接口已返回。


后端验证记录

本地 (gateway 8080, order-v2 8094)

[1] APPROVED→REJECTED        code=200  DB: REJECTED + revert_remark 写入
[2] REJECTED→APPROVED        code=200  DB: APPROVED + revert_remark 更新
[3] 缺 remark                code=400  Bean Validation
[4] APPROVED→APPROVED        code=551076
[5] PENDING_MANUAL→APPROVED  code=551076
GET /admin/review/list       响应字段含 revertRemark

测试服 (api.test.1814.love:9443)

[1] APPROVED→REJECTED  code=200 msg=成功
[2] REJECTED→APPROVED  code=200 msg=成功
[3] APPROVED→APPROVED  code=551076 msg=评价状态不允许反转,仅 APPROVED ↔ REJECTED 可互转
[4] 缺 remark          code=400 msg=反转备注不能为空(Bean Validation)
[5] GET /admin/review/list  响应字段含 revertRemark ✓

🔒 业务规则细节

  1. 反转不联动定制师评价:产品评价反转时,不会自动同步 PENDING_MANUAL 状态的定制师评价(避免反向操作意外波及)。/approve 仍保留 cascadeApproveCustomizerReviews 联动逻辑。
  2. 精选评价缓存:反转后清 featuredReviewCache,防止已拒绝的评价仍在精选中显示。
  3. 审计字段:反转会更新 auditorAdminId / auditorName / auditedAt 为最新操作人,不更新 rejectReason(语义保留)。

🗂️ Schema

ALTER TABLE `order_review`
ADD COLUMN `revert_remark` VARCHAR(500) NULL COMMENT '终态反转备注(APPROVED↔REJECTED 互转时填)';

Flyway: V20260525_002__add_revert_remark_to_order_review.sql,测试服已落库 success=1。