3.4 KiB
3.4 KiB
feat(wx-security): Phase 2C 出行人三层兜底
PR: #1666 Issue: #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.requireApprovedForBookinghelper- 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 后台)