# feat(wx-security): Phase 2B 评价举报子系统

**PR**: [#1667](https://git.1814.love:8443/wx/HL/pulls/1667) **Issue**: [#1662](https://git.1814.love:8443/wx/HL/issues/1662) **合并**: 2026-05-05

按官方契约 §8.7 实现评价举报闭环 — 用户举报 + 阈值自动隐藏 + 命中再机审。

## 新接口 POST /mp/review/report

请求体 `ReviewReportReqVO`：

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| reviewId | Long (前端 String 序列化) | 是 | 评价 ID |
| reason | String | 是 | 字典 review_report_reason: SPAM/INSULT/PORN/POLITICS/FAKE/LEAK_PRIVACY/OTHER |
| detail | String (≤500) | 否 | 补充说明 |

返回：成功 200，失败业务码：
- `551001` REPORT_REASON_INVALID — 举报原因无效
- `551002` REPORT_RATE_LIMIT — 今日举报次数已达上限
- `551003` REVIEW_NOT_FOUND — 评价不存在
- `551004` REPORT_SELF_NOT_ALLOWED — 不能举报自己的评价
- `551005` REPORT_DUPLICATE — 您已举报过该评价

## 阈值聚合（异步）

- `count >= 3` → `report_status=PENDING_REVIEW`（人工队列）
- `count >= 10` 且 24h 内 → 自动 **HIDDEN** + hidden_reason
- 命中举报触发再机审：msgSecCheck v2 → risky 强制 HIDDEN

## 公开列表过滤

8 个公开 Mapper 方法叠加 `report_status != 'HIDDEN'`（Phase 2A 已有 audit_status='APPROVED' 过滤）：
- selectTargetApprovedPage / selectAllReviewsPage / selectFeaturedReviews / selectTargetsApprovedPage / selectSearchPage / selectTopRatedByProduct / selectTopLikedByProduct / selectGoodWithImageByProduct / selectCustomizerReviewsPage

`/mp/review/my` 私有列表**不**过滤，VO 加 `reportStatus` + `hiddenReason` 字段供前端展示状态条文案。

## 表结构变更

- `order_review` 加 4 字段（V20260505_005）：report_count + report_status + hidden_at + hidden_reason
- `review_report` 新表（V20260505_006）：uk_review_reporter（含 deleted_at 软删幂等）
- `review_report_reason` 字典初始化（V20260505_007，hl_user_service）

## 前端契约要点（mmg）

- `POST /mp/review/report` 调用：
  ```js
  http.post('/mp/review/report', { reviewId: '101', reason: 'SPAM', detail: '...' })
  ```
- `/mp/review/my` 私有列表响应新增 `reportStatus` + `hiddenReason`：
  - `NORMAL` → 正常展示
  - `PENDING_REVIEW` → 状态条「举报审核中,仍展示」
  - `HIDDEN` → 状态条「该评价已下架」+ hidden_reason
- 公开列表（`/mp/review/target`、`/mp/review/featured` 等）后端已自动过滤 HIDDEN 内容，前端无需特殊处理

## 测试

- mvn compile 全工程 BUILD SUCCESS
- mvn test 59 + 22 全绿（含 P1 修复后回归）
- CR 通过：无 P0；2 P1 全修（错误码段位 548xxx → 551xxx 避免与 OrderInsuranceErrorCode 重叠 / textCheck @RequestParam → @Valid @RequestBody DTO 避免 414）

## ⚠️ 部署注意事项（运维）

### SQL 顺序
1. V20260505_005 → V20260505_006（hl_order_service_v2 schema）
2. V20260505_007（hl_user_service schema）

### 字典缓存清理（必做）
V007 部署后立即执行：
```bash
redis-cli DEL cache:dict:data:list cache:dict:data:by-type cache:dict:data:review_report_reason
```

### 字典 ID 校验
V007 部署前确认 `dict_type_id=10080` 和 `dict_data_id 100801-100807` 无冲突。

## Phase 2D 后续 (#1664)

- 运营人工 review_report.status=HANDLED/IGNORED 处理
- HIDDEN 评价人工恢复 + 清零 report_count
- 恶意举报识别（高频但通过率低）
- admin 后台举报队列 + 统计
