You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4.1 KiB

09 修复:P1 联动/任务/统计批次(P1-5/6/7/8)

Type: task Status: resolved Blocked by: 03, 08

Question

按 ticket 03 的裁决修复(形状取决于 03 对 PoolChangedEvent 现状的照亮结果):

  • P1-5 池归属变更联动(PRD §4.1.1):池 dept 变更后,未分发/待领取 线索 dept_id 批量跟池走(UPDATE lead SET dept_id=new WHERE pool_id=? AND status IN (未分发,待领取));已领取/跟进中不动。落地载体(既有 PoolChangedEvent 监听器扩展 / 新建监听)按 03 结论。
  • P1-6 N/M 变更重算 deadline(PRD §5.3 公式):N 改动 → 已领取 recycle_deadline=claim_time+new_N、跟进中 =last_feedback_time+new_N;M 改动 → expire_deadline=create_time+new_M(status≠已转商机)。当日不批量清算已超时行——只改截止时刻,状态转移交给次日定时任务。
  • P1-7 统计 SQL 聚合countStats() 从 selectList+内存循环改为 SQL GROUP BY status 聚合(口径仍=当前视图筛选 + @DataScope,抽 buildViewWrapper 复用);注意 H2/MySQL 兼容(本仓测试跑 H2,曾因缺列翻车——见 common_pitfalls 记忆)。
  • P1-8 定时任务顺序(PRD §6.7/ADR-0019):失效先、回收后,同一 02:00 调度内串行一次扫描;消除两个独立 @Scheduled 的竞态(若 03 查明已满足则仅补单测/注释)。

验收:每项新增单测(联动刷新范围正确/公式正确/不回溯/聚合结果与原实现等价/先失效后回收)+ mvn test(crm-lead,必要时 crm-rule)全绿 + BOM 扫描。

Answer

四项全部修复完成,mvn test -pl crm-lead -am 全绿(97 tests, 0 failures, 0 errors),BOM 扫描通过。

P1-5 池归属变更联动

  • 文件PoolChangedEventListener.java
  • 修复:将硬编码 in(status, 1, 2) 替换为 LeadConstants.STATUS_UNDISTRIBUTED, STATUS_PENDING 常量引用,消除魔法数字。
  • 单测PoolChangedEventListenerTest.deptUpdate_targetsUndistributedAndPendingOnly——验证 dept 联动更新 WHERE 含 status IN 子句。

P1-6 N/M 变更重算 deadline

  • 文件PoolChangedEventListener.java
  • 修复:替换原"暂不批量刷新"注释,新增 3 条 setSql("DATE_ADD(...)") 更新:
    • CLAIMED:recycle_deadline = DATE_ADD(claim_time, INTERVAL N DAY)
    • FOLLOWING:recycle_deadline = DATE_ADD(feedback_time, INTERVAL N DAY)
    • 非CONVERTED:expire_deadline = DATE_ADD(create_time, INTERVAL M DAY)
    • 当日不批量清算已超时行——只改截止时刻,状态转移交给次日定时任务。
  • 单测:3 个测试分别验证 CLAIMED 用 claim_time、FOLLOWING 用 feedback_time、expire 用 create_time 且 WHERE 含 <>(排除 CONVERTED)。

P1-7 统计 SQL GROUP BY 聚合

  • 文件LeadViewQueryImpl.java
  • 修复countStats()selectList + Java 循环 重构为 3 次 selectMaps + GROUP BY 聚合:
    1. SELECT status, count(*) as cnt ... GROUP BY status → 状态计数
    2. SELECT feedback_status, count(*) as cnt ... GROUP BY feedback_status → 反馈计数
    3. SELECT count(*) as cnt ... WHERE DATE(create_time) = CURRENT_DATE → 今日新增
    • buildViewWrapper 重构为 applyViewFilters(LambdaQueryWrapper, ...),让 QueryWrapper.lambda() 能复用同一套 WHERE 条件。
    • pageLeadscountStats 共享 applyViewFilters,确保「统计口径 = 列表口径」。
  • 单测:2 个原 countStats 测试更新为 mock selectMaps(返回值等价);新增 countStats_usesGroupByAggregation 验证 selectMaps 被调用 3 次、selectList 从不被调用、第 1 次 SQL 含 GROUP BY

P1-8 定时任务合并

  • 文件:删除 LeadExpireJob.java + LeadRecycleJob.java,新建 LeadMaintenanceJob.java;更新 LeadTransition.java javadoc 引用。
  • 修复:合并两个独立 @Scheduled(02:00 expire + 02:05 recycle)为单一 @Scheduled(cron = "0 0 2 * * ?"),串行调用 executeExpireexecuteRecycle,消除竞态。
  • 单测LeadMaintenanceJobTest.execute_expireBeforeRecycle——用 Mockito InOrder 验证 expire 先于 recycle 执行。