From 65444d72e063440930b6ff3a68889fd9f9546794 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Tue, 5 May 2026 14:39:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(wx-security):=20Phase=202C=20=E5=87=BA?= =?UTF-8?q?=E8=A1=8C=E4=BA=BA=E4=B8=89=E5=B1=82=E5=85=9C=E5=BA=95=20(PR=20?= =?UTF-8?q?#1666=20/=20Issue=20#1663)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-05/05_feat_wx-security_phase2c.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 changelogs/2026-05/05_feat_wx-security_phase2c.md diff --git a/changelogs/2026-05/05_feat_wx-security_phase2c.md b/changelogs/2026-05/05_feat_wx-security_phase2c.md new file mode 100644 index 0000000..7394929 --- /dev/null +++ b/changelogs/2026-05/05_feat_wx-security_phase2c.md @@ -0,0 +1,62 @@ +# feat(wx-security): Phase 2C 出行人三层兜底 + +**PR**: [#1666](https://git.1814.love:8443/wx/HL/pulls/1666) **Issue**: [#1663](https://git.1814.love:8443/wx/HL/issues/1663) **合并**: 2026-05-05 + +按官方契约 §8 出行人姓名实名信息特殊处理:机审误伤代价高(真实姓「操/苟」、少数民族罕字、港澳台/外籍拼音),**前端不做硬拦截**,后端三层兜底。 + +## 三层兜底 + +### 第 1 层 入库静默机审(不阻塞业务) +- traveler.create/update + order_traveler.add/update **业务先成功** +- afterCommit + @Async 触发异步 msgSecCheck(scene=1 资料) +- 命中 risky/review/pass=false → **MANUAL_REVIEW**(不直接 REJECTED 避免误伤,运营 Phase 2D 人工裁决) +- 微信 5xx/异常降级 PENDING(不删数据不拒收) +- 命中违规落 traveler_audit_log 审计日志(正常用户不入,避免噪音) +- 同款适用 emergencyContact + user.realName(复用 Phase 1 nickname_audit_status 列) + +### 第 2 层 选用时校验(下单仅挡 REJECTED) +- `TravelerService.requireApprovedForBooking` helper +- REJECTED → BusinessException 「此出行人信息异常,请联系客服核实」 +- PENDING / MANUAL_REVIEW / APPROVED 全放行(误伤场景不影响出行) +- 注:admin 端下单(OrderCreateService.saveTravelers)受 spec 设计限制只走 Layer 3 验证(无源 traveler 联动),跨服务 Feign 留 Phase 2D + +### 第 3 层 本地正则(同步硬拦,防垃圾) +`TravelerNameValidator` 4 条规则: +- 长度 2-30(codePoint 字符数) +- 字符集白名单 `^[中文a-zA-Z·\-\s]+$` +- 黑名单(初始空,Phase 2D admin 维护) +- 重复字符 `.*(.)\1{4,}.*` 防 aaaaa/test + +误伤豁免(已单测覆盖):「操军」/ 「司马相如」/ 「张-李」/ 「a·b」 通过;「aaaaa」/ SQL 片段拒。 + +## 新表 + 配置 + +- `traveler_audit_log`(V20260505_004 增量 SQL + schema.sql 同步) +- `TravelerAuditAsyncConfig` 独立线程池(core=4/max=8/queue=200/CallerRunsPolicy) +- @Async qualifier 严格对齐 `@Bean("travelerAuditExecutor")` + +## 4 个新错误码(CommonErrorCode) + +- TRAVELER_NAME_LENGTH_INVALID 「姓名长度异常(2-30字符)」 +- TRAVELER_NAME_CHAR_INVALID 「姓名含非法字符」 +- TRAVELER_NAME_BLACKLISTED 「姓名含敏感词」 +- TRAVELER_NAME_REPEATED_CHAR 「姓名格式不正确」 +- TRAVELER_REJECTED 「此出行人信息异常,请联系客服核实」 + +## 前端契约要点(mmg) + +- 前端不再做硬拦截 — 4 个错误码配套 toast 文案即可 +- 出行人列表展示状态条:审核中 (PENDING/MANUAL_REVIEW) / 已通过 (APPROVED) / 已拒 (REJECTED 仅运营手动设置) +- 下单时若 traveler.audit_status=REJECTED 后端返业务码 100705,前端 toast 后引导联系客服 + +## 测试 + +- mvn compile 全工程 BUILD SUCCESS +- 235 单测全绿(TravelerNameValidator 44 + TravelerAuditService 22 + TravelerAuditAsyncConfig 1 + TravelerService 84 + OrderTravelerService 34 + 回归 50) +- CR 通过(5 P1 留 Phase 2D cleanup:Service Mapper 拆分 / @Async+@Transactional 分离 / 字段注入改构造器 / 审计日志吞异常改 ERROR / 文档 TODO 标注) + +## 不在本期范围 + +- order.contactName 同款审(无独立 SaveReqVO 入口) +- order_traveler.audit_status 跨服务字段(spec 设计跳过;admin 下单 Layer 3 已挡垃圾名字) +- 运营人工 REJECTED 裁决 + 黑名单维护(Phase 2D #1664 admin 后台)