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.
 
 
 
 
 

7.0 KiB

四视图卡片口径映射表定稿

Type: grilling Status: resolved Blocked by: 04

Question

原问题:

产出一张权威的「视图 × 卡片 → 口径」映射表,作为 spec 的核心。每格给出 status 集合或派生条件(含今日新增的时间口径、销售持有的合并口径)。初稿如下,需逐格确认/修订:

卡片 口径 公海 我的线索 我的关注 线索管理
线索总量 视图内 count(*)
待领取 status=2
今日新增 DATE(create_time)=今天
已领取 status=3
跟进中 status=4
已转商机 status=5
线索作废 status=7(口径见 #01)
过期失效 status=6
未分发 status=1
销售持有 status IN (3,4)

待确认要点:

  • 「线索总量」在各视图分母是什么?是视图内全部可见线索,还是全部 7 态?(尤其 公海 现只见 2/3/4,我的线索 只见有 owner 的)——直接受 #01 结论影响。
  • 各卡片口径是否要吃 /page 的动态筛选(keyword/channel/…),还是固定视图口径?
  • 「销售持有」= 已领取 + 跟进中,与 我的线索/我的关注 里的拆分字段是同源计算。

Answer

核心口径公式

所有分卡口径 = applyViewFilters(viewType, param, currentUserId) + 该 status 条件。无逐格特判、无额外 owner 断言。

其中 applyViewFilters 保持现状语义(不改):

  • PUBLIC_POOLstatus IN (2,3,4)
  • MY_LEADowner_user_id = 当前用户(不加 status 过滤,天然含作废 owner=我 —— 由 ticket 01/04 保证)
  • MY_FOLLOWid IN (SELECT lead_id FROM lead_follow WHERE user_id = 当前用户)(不看 owner、不看 status)
  • MANAGE:无业务过滤,仅靠 @DataScope 注入部门/OWNER 天花板

@DataScope 由 MyBatis 拦截器自动叠加在同一 wrapper 上(Lead 实体注解),四视图 stats 天然吃到。

视图 × 卡片 → 口径映射表(权威定稿)

卡片 口径(在 applyViewFilters 之上再叠加) 公海 我的线索 我的关注 线索管理
线索总量 count(*)(视图内全部可见)
今日新增 create_time >= todayStart AND create_time < tomorrowStart
待领取 status = 2
未分发 status = 1
已领取 status = 3
跟进中 status = 4
销售持有 status IN (3, 4)
已转商机 status = 5
过期失效 status = 6
线索作废 status = 7

决策来源(7 格 grilling 结论)

  1. 总量分母(Grill 1,甲):「线索总量」= 视图 applyViewFilters 之后 count(*),四视图一致。允许“分卡覆盖不全 7 态、之和 ≠ 总量”(如「我的关注」缺 status=1 分卡是允许的)。
  2. 动态筛选吃不吃(Grill 2,甲):卡片吃 /page 全部动态筛选(keyword/channel/brand/product/province/statusIn/poolId/deptId/isUrgent/feedbackStatus)。现状 countStats 复用完整 applyViewFilters,零改动。
    • 副作用(留给 03 前端契约处理):若用户传 statusIn=[3],则「已领取」=「线索总量」、其他分卡=0。这是甲的必然、非 bug;前端是否把 statusIn 从卡片计算里剔除属于 03 决策。
  3. 今日新增时间口径(Grill 3,甲)
    • 时区 = JVM 本地 LocalDate.now()(与 ClaimLimitChecker 同源)。
    • SQL 用范围条件 create_time >= todayStart AND create_time < tomorrowStart(索引友好),不再用 DATE(create_time) = CURRENT_DATE
    • 时间字段 = create_time(入库时间)。不看当前 status——今日入库又今日作废也算 1 条。
  4. 销售持有(Grill 4,甲)status IN (3,4),纯 status 判据。与 ClaimLimitChecker/ConvertibleLeadCatalogPortImpl 同源。不加 owner IS NOT NULL 防御——状态机不变式(status ∈ {3,4} ⇒ owner 非空)由状态机保证,统计层不重复兜底。加法关系:销售持有 = 已领取 + 跟进中
  5. 「我的关注」的分卡是否叠 owner(Grill 5,甲):不叠。所有分卡 = follow 表内 + 该 status。产品语义支持——“关注 = 盯着这条线索的动向”,别人 owner 的线索被作废,也要计入「我的关注」→「线索作废」。
  6. MANAGE 视图数据范围(Grill 6,甲):MANAGE 无业务过滤 + @DataScope 天花板。数字随角色变化(ALL_VISIBLE / DEPT / OWNER),入口权限由 LeadPermissionInitializer 的 catalog 权限点控制,spec 里注明此点。
  7. 需求✗格严格按原清单(Grill 7,甲):✗ 就是 ✗,不向产品发起补卡建议。以下三处✗ 不追问,按需求原样交付:
    • 「我的线索」/「我的关注」无「今日新增」。
    • 「线索管理」无「已领取(3)」「跟进中(4)」独立卡,只有合并的「销售持有」。
    • 「线索管理」无「线索作废(7)」卡。

交付给 03 的接力

03(DTO 字段形态与前端契约)需要处理:

  • DTO 字段命名
    • 新增 following(跟进中 status=4)、expired(过期失效 status=6)、voided 或类似(作废 status=7,void 是 Java 关键字禁用)。
    • 现有 claimed 语义歧义(当前 =3+4)——建议改名 sellerHolding(对应「销售持有」),或将 claimed 收窄为仅 status=3、另增 sellerHolding 字段。由 03 定。
  • DTO 是否全量返回:后端一次算 total/undistributed/waiting/claimed/following/converted/expired/voided/todayNew/sellerHolding 全套,前端按视图渲染 —— 还是按 viewType 裁剪只返回该视图卡片对应字段?现状「全量返回」;由 03 定。
  • statusIn 与卡片的交互:如 Grill 2 副作用所述,前端点卡片下钻 = 加 statusIn 筛选;若卡片本身又吃 statusIn,会出现“点了「已领取」后所有其他卡=0”的观感—— 03 定前端在卡片计算的 payload 里是否剔除 statusIn
  • 测试口径重写LeadViewQueryImplTest#countStats_* 全部按上表重写。断言矩阵 = 4 视图 × 上表勾选卡片,覆盖:
    • 视图 filter 生效
    • @DataScope 生效(OWNER/DEPT/ALL_VISIBLE 三档)
    • 今日新增按 JVM 时区、范围条件
    • 「我的关注」含别人 owner 的作废/过期(Grill 5)
    • 加法关系:sellerHolding = claimed(3) + following(4)(若 DTO 拆到这个粒度)

明确不属于本 ticket 的

  • DTO 字段名 & 数量(03)。
  • 前端契约(03)。
  • 后端实现改动(新起 session)。
  • 需求✗格是否补卡(甲:不追问)。