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.3 KiB

07 修复:P0-6/7 公海混合展示 + 新增线索归属约束

Type: task Status: resolved Blocked by: 02, 06

Question

按 ticket 02 的裁决修复(注意与 06 串行——同改 LeadServiceImpl):

P0-6 公海混合展示(PRD §7 已定稿(E)):

  • LeadViewQueryImpl.buildViewWrapper() PUBLIC_POOL 分支不再硬编码 status=PENDING,改为**"公海可见状态集"参数驱动**,默认 {待领取, 已领取, 跟进中},不硬编码(后续可能收窄/按池细分——留参数化缝)。
  • 参数放哪(常量类 / 配置项 / LeadPageParam 可选覆盖)由本 ticket 定,遵循"改规则不改代码"的定稿意图并写清注释。
  • 已被领走的行只读属前端职责;后端保证列表含这些行 + "领取人"字段回填正确。
  • LeadViewQueryImplTest 同步更新(现有 PUBLIC_POOL 断言会变)。

P0-7 新增线索归属约束(PRD §6.1 grill #6 定稿):

  • 销售新增:强制回填本人主部门的池(不给选、不可编辑),忽略前端传入 poolId;兼职部门有池也只落主部门池。
  • 主部门无池 → 报错拦截("本部门尚未配置公海池,请联系管理员"),不允许销售建挂空池线索。
  • 管理员新增:可指定任意池,或 poolId=null 建"未分发"(管理员导入专属中间态)。
  • 需要"当前用户是否管理员"判定:先查本仓既有实践(角色/权限点判定机制,参照 crm-auth 能力与既有 Controller 用法)再落地,不发明新机制。

验收:新增单测(销售回填主部门池/主部门无池拒绝/管理员可建未分发/公海视图含已领取跟进中行)+ mvn test(crm-lead)全绿 + BOM 扫描。

Answer

P0-6 公海混合展示

  • LeadConstants 新增常量 PUBLIC_POOL_VISIBLE_STATUSES = List.of(STATUS_PENDING, STATUS_CLAIMED, STATUS_FOLLOWING)(参数化缝——后续可按池细分或收窄,改常量不改代码)。
  • LeadViewQueryImpl PUBLIC_POOL 分支从 wrapper.eq(Lead::getStatus, STATUS_PENDING) 改为 wrapper.in(Lead::getStatus, LeadConstants.PUBLIC_POOL_VISIBLE_STATUSES)
  • 新增 LeadViewQueryImplTest.pageLeads_publicPoolView_usesInClause——验证 wrapper SQL 含 IN 子句。

P0-7 新增线索归属约束

  • SecurityUtils 新增 hasRole(String roleCode) 方法——遍历 Authentication.getAuthorities() 匹配角色码,不硬编码角色名;调用方传 AuthConstants.ROLE_CODE_ADMIN
  • ILeadService 新增 4 参 createLead(dto, claimOnCreate, followOnCreate, Long assignToUserId) 抽象方法;3 参版本改为 default 委托(assignToUserId=null)。
  • LeadServiceImpl.createLead 重构为 4 分支:
    1. 非管理员ownerSnapshotResolver.of(userId) 取主部门 → getPoolByDept(deptId) 强制回填池(忽略前端 poolId);无池→65001 拒;claimOnCreate 时校验 claim_rule + 额度,设置 CLAIMED;否则 PENDING。
    2. 管理员 + assignToUserId != null(选人即分配):getPoolByIdOrThrow(poolId) 取池 → ownerSnapshotResolver.of(assignToUserId) → 额度校验归属=被指派人 → CLAIMED + owner=被指派人。
    3. 管理员 + poolId=null:建未分发(UNDISTRIBUTED)。
    4. 管理员 + poolId 指定(不选人)getPoolByIdOrThrow(poolId) 取池 → claimOnCreate 时校验 claim_rule + 额度。
  • LeadController.create 端点加 @RequestParam(value = "assignToUserId", required = false) Long assignToUserId 参数。

单测(LeadServiceImplTest +3, LeadViewQueryImplTest +1)

  • createLead_salesUser_deptNoPool_rejected——主部门无池→65001 拒、不写库。
  • createLead_adminNoPool_undistributed——管理员不指定池→UNDISTRIBUTED。
  • createLead_adminAssignToUser_claimedOnCreate——选人即分配→CLAIMED + owner=被指派人 + 额度归属=被指派人 + ADMIN_ONLY 池不阻拦管理员分配。
  • pageLeads_publicPoolView_usesInClause——PUBLIC_POOL 视图 wrapper 用 IN 子句(非 eq 单值)。
  • 修复 4 个既有 createLead 测试(followOnCreate/noFollow/adminOnlyPool_rejected/limitExceeded)——适配非管理员路径的 stubUserLookup + getPoolByDept stub。

验证

  • BOM 扫描:8 个修改文件全部无 BOM。
  • mvn test -pl crm-base,crm-lead -am:86 tests, 0 failures, 0 errors, BUILD SUCCESS。