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

05 · 平台形态偏好:user_view_form 表 + 端点,客户/商机双接入

  • Status: resolved
  • Type: task
  • Blocked by: 01-ag-checklist

目标

crm-preference 新增「形态偏好」平台能力(R6),客户三页签 + 联系人 + 商机三菜单接入(R7)。用户上次选择的视图形态(list/split/board)跨会话记忆。

平台侧(crm-preference)

  • 实体 UserViewForm:表 user_view_formUNIQUE(user_id, scope_key)view_form varchar(16),无 create_by/update_by(同 UserColumnPreference 范式:author 恒为 user_id);
  • ViewFormController
    • GET /api/preference/view-form/get?scopeKey=Result<String>(null = 未设置);
    • POST /api/preference/view-form/save(form 绑定,@RequestBody);
  • 值域白名单 list / split / board,非法值 67001 口径拒绝;
  • tags 双归属(方法级多值):客户侧 A4 客户管理/客户总览A4 客户管理/我的客户A4 客户管理/客户公海A4 客户管理/联系人;商机侧 A3 商机管理/销售机会A3 商机管理/商机管理A3 商机管理/商机公海

接入侧(零端点,只加常量,参考线索列偏好范式)

  • crm-customer 常量:VIEW_FORM_SCOPE_OVERVIEW/MINE/POOL/CONTACT = customer.overview/mine/poolcontact.list
  • crm-opportunity 常量:opportunity.sales/manage/public_pool(与 saved-view opportunity.sales 对齐);
  • 前端调平台端点读写,未设置 → 默认 list。

验收

  • crm-preference + 两接入模块 mvn test 绿;
  • 单测覆盖:存取往返、白名单拒绝、UNIQUE 覆盖更新;
  • knife4j 分组出现双归属页面。

同步动作

.scratch/customer-module/map.md 增补决策条目(形态偏好平台化);crm-preference CONTEXT 若有"形态偏好规划"段落则补实现指针。

Answer

平台侧(crm-preference) — 已实施,对称 UserColumnPreference 范式:

  • PreferenceConstants 新建:错误码 68xxx 段启用(61 auth / 62 file / 63 dict / 64 rule / 65 lead / 66 opp / 67 cust 之后顺延;平台模块自持段位,不引业务模块码——依赖方向恒为业务 → preference 单向)。票面"67001 口径"落地为平台同款守卫形态CODE_VIEW_FORM_INVALID = 68001(字面借 67001 会语义错位 + 引入平台→业务反向依赖)。
  • UserViewForm:表 user_view_formUNIQUE(user_id, scope_key)(uk_user_scope),view_form varchar(16),无 create_by/update_by(author 恒为 user_id),五字段对称 UserColumnPreference。
  • ViewFormService/Impl:get → Optional(null=未设置);save = upsert 覆盖 + 白名单 list/split/board 平台校验(非法/null → 68001)。校验归平台的理由:形态是平台语义值,非业务字段池——与列偏好"不做业务校验"边界不同(CONTEXT.md 词条已记)。
  • ViewFormControllerGET /api/preference/view-form/get?scopeKey=Result<String> + POST /api/preference/view-form/save(表单绑定,零 @RequestBody);方法级多值 tags 双归属 A4×4(总览/我的客户/公海/联系人)+ A3×3(销售机会/商机管理/商机公海);不种子化权限点(fail-open,对称列偏好)。

接入侧(零新端点,只加常量)CustomerConstants.VIEW_FORM_SCOPE_OVERVIEW/MINE/POOL/CONTACT = customer.overview/mine/poolcontact.list(注释块对称 LeadConstants L46-50 写法,含依赖方向说明);OpportunityConstants.VIEW_FORM_SCOPE_SALES/MANAGE/PUBLIC_POOL = opportunity.sales/manage/public_pool(sales 与 saved-view 同码位)。前端直调平台端点,未设置 → 默认 list。

测试与验收mvn test -pl crm-preference,crm-customer,crm-opportunity -am 全绿——preference 23(+7:存取往返/白名单三值/非法值 68001/null 拒绝/upsert 插入/UNIQUE 覆盖更新)、customer 144、opportunity 242。BOM 扫描 clean。knife4j 双归属由方法级 tags 直接保证(票 07 bruno-sync 落产时同构验证)。

中途修复@Operation(tags = PAGE_TAGS) 引用 static final String[] 不是编译期常量表达式(JLS 4.12.4,数组非 constant variable)→ mvn 报 String[] 无法转换为 String,且 lombok 级联失效带崩同模块 ColumnPreferenceServiceImpl 编译;改回项目既有形态——每个 @Operation 内联数组字面量(对称 ColumnPreferenceController)。

同步动作.scratch/customer-module/map.md 已增补 [D30] 形态偏好平台化;crm-preference/CONTEXT.md 已加「形态偏好」词条(scope 命名空间与列偏好共用、两表互不干扰、白名单平台校验边界)。