unis_crm/%E6%B8%A0%E9%81%93%E6%8B%93...

11 KiB
Raw Permalink Blame History

渠道拓展 ⇄ CRM拓展 数据互移功能方案

版本V1.0  日期2026-08-28  适用范围CRM 系统渠道拓展 / CRM拓展

一、功能概述

  1. 在「渠道拓展详情」底部操作区新增「移至CRM拓展」按钮将整条渠道拓展数据主表 + 联系人子表 + 跟进记录)迁移为一条 CRM 拓展记录,删除源渠道记录,并同步更新所有引用该渠道的地方。
  2. 对称地在「CRM拓展详情」底部操作区新增「移至渠道拓展」按钮实现 CRM 拓展数据反向迁移为渠道拓展,逻辑对称。
  3. 点击按钮后先弹出「迁移前补填」表单,用户补填源数据中缺失的目标必填字段,确认后执行迁移。
  4. 按钮权限与现有「编辑资料」按钮保持一致:仅记录本人(负责人)可见可点。

二、权限控制

  • 复用前端 canEditSelectedItem = ownerUserId === currentUserId,与编辑按钮同一套权限逻辑,不新增权限点。
  • 非本人记录:按钮禁用并显示「仅本人可操作」,行为与编辑按钮一致。
  • 后端同样校验记录存在且 owner_user_id = 当前用户,防止越权调用。

三、后端接口设计

方法 路径 说明
POST /api/expansion/channel/{id}/move-to-crm 渠道 → CRM请求体携带弹窗补填字段
POST /api/expansion/crm/{id}/move-to-channel CRM → 渠道,请求体携带弹窗补填字段

服务层新增方法(均使用 @Transactional,任一步失败整体回滚):

Long moveChannelToCrm(Long userId, Long channelId, MoveChannelToCrmRequest payload);
Long moveCrmToChannel(Long userId, Long crmId, MoveCrmToChannelRequest payload);

迁移流程(以渠道 → CRM 为例):

  1. 校验记录存在且归属当前用户(复用 countOwnedChannelExpansion)。
  2. 查询源主表数据(复用现有单条查询)。
  3. 自动映射字段 + 合并弹窗补填字段,构造 CreateCrmExpansionRequest(不走表单校验)。
  4. insertCrmExpansion 创建目标主表,获取新 id。
  5. 联系人子表逐条复制(name / mobile / title / sort_order)。
  6. 引用同步详见第四节跟进记录、外勤打卡、日报消息迁移至新记录商机、其它CRM进货商引用置空。
  7. 删除源:先删联系人子表,再删渠道主表。

四、引用同步清单(决策①:删除源 + 同步引用)

4.1 渠道 → CRM删除渠道源记录后

引用表.字段 原值 处理后 说明
crm_opportunity.channel_expansion_id 源渠道id 置空 NULL 存在外键约束,删除前必须置空,否则删除失败
crm_crm_expansion.supplier_id 源渠道id 置空 NULL 存在外键约束,删除前必须置空
crm_expansion_followup.biz_type / biz_id 'channel' / 源id 'crm' / 新id 拜访/跟进记录随迁
work_checkin.biz_type / biz_id / biz_name 'channel' / 源id / 旧名 'crm' / 新id / 新名 外勤打卡关联同步
work_report_message.biz_type / biz_id / biz_name 'channel' / 源id / 旧名 'crm' / 新id / 新名 日报消息关联同步

4.2 CRM → 渠道删除CRM源记录后

引用表.字段 原值 处理后 说明
crm_expansion_followup.biz_type / biz_id 'crm' / 源id 'channel' / 新id 拜访/跟进记录随迁
work_checkin.biz_type / biz_id / biz_name 'crm' / 源id / 旧名 'channel' / 新id / 新名 外勤打卡关联同步
work_report_message.biz_type / biz_id / biz_name 'crm' / 源id / 旧名 'channel' / 新id / 新名 日报消息关联同步

补充说明

  • crm_channel_expansion_contact 子表外键为 ON DELETE CASCADE,删除渠道主表时联系人自动级联删除,无需单独处理。
  • work_todo(待办)仅用于日报「明日计划」待办(biz_type='report'),不涉及渠道/CRM拓展无需同步。
  • sys_activity_log(首页动态日志)为历史遗留表,当前代码无写入路径;如存在历史引用建议一并清理(可选)。
  • crm_crm_expansion.h3c_contact_id 指向销售拓展(crm_sales_expansion),与本次迁移无关,保持不变。

五、字段对应关系 + 弹窗补填范围(决策②:迁移前弹窗填写)

5.1 渠道拓展 → CRM拓展自动映射有对应关系

渠道拓展字段(列) 渠道拓展含义 CRM拓展字段 CRM拓展含义 / 说明
channel_name 渠道名称 end_user 最终用户
province 省份 office_name 代表处(按 tz_bsc 字典转换,未匹配保留原值)
channel_industry 聚焦行业 industry_attr 行业属性(按 tz_sshy 字典转换)
contact_established_date 建立联系时间 purchase_date 采购时间
contact_name / mobile / title 主联系人 contact_name / phone / title 冗余字段
crm_channel_expansion_contact(子表) 多联系人 crm_crm_expansion_contact(子表) 逐条平移
remark 备注 remark 写入DB列CRM表单无备注字段
owner_user_id 负责人 owner_user_id 保持不变

渠道特有、CRM 无对应 → 不迁移: channel_codecityoffice_addresscertification_levelannual_revenuestaff_sizeintent_levelhas_desktop_expchannel_attributeinternal_attributestagelanded_flagexpected_sign_date

弹窗补填CRM无来源的必填字段

弹窗字段 默认值 说明
extension_type(类型) 字典 crm_extension_type 单选,必填
online_status(在线情况) 字典 crm_online_status 单选,必填
has_expansion_opportunity(是否有扩容机会) 字典 sys_is 单选,必填
supplier_id(进货商) AdaptiveSelect 选渠道,必填(不能选自身)
h3c_contact_id(新华三对接人) AdaptiveSelect 选销售拓展,必填
warranty_expiry(过保时间) 采购时间+3年 预填可改

5.2 CRM拓展 → 渠道拓展:自动映射(有对应关系)

CRM拓展字段 CRM拓展含义 渠道拓展字段(列) 渠道拓展含义 / 说明
end_user 最终用户 channel_name 渠道名称
office_name 代表处 province 省份(反查 tz_bsc未匹配保留原值
industry_attr 行业属性 channel_industry 聚焦行业
purchase_date 采购时间 contact_established_date 建立联系时间
contact_name / phone / title 冗余联系人 contact_name / mobile / title 主联系人
crm_crm_expansion_contact(子表) 多联系人 crm_channel_expansion_contact(子表) 逐条平移
remark 备注 remark 直接映射
owner_user_id 负责人 owner_user_id 保持不变

CRM特有、渠道无对应 → 不迁移: extension_typewarranty_expiryonline_statussupplier_idh3c_contact_idhas_expansion_opportunity

弹窗补填(渠道无来源的必填字段):

弹窗字段 默认值 说明
city(市) 必填
office_address(办公地址) 必填
certification_level(认证级别) 字典单选,必填
annual_revenue(年度营业额·万元) 数字>0必填
staff_size(人员规模) 正整数,必填
channel_attribute(渠道属性) 字典单选,必填
internal_attribute(内部属性) 字典单选,必填
intent_level(合作意向) medium 可改
has_desktop_exp(桌面扩展能力) false 可改
stage(阶段) initial_contact 预填
landed_flag(是否落地) false 预填
expected_sign_date(预计签约时间) 可空

说明:渠道表单编辑时校验 province / city / certificationLevel / officeAddress / channelIndustry / annualRevenue / staffSize / channelAttribute / internalAttribute 等字段非空,因此迁移弹窗将这些字段设为必填,确保迁移后的记录完整、可继续编辑保存。

六、并发与重复防护

迁移为「删除源 + 创建目标」的复合写操作,必须保证并发安全与幂等,防止重复迁移、竞态丢失或脏数据。

6.1 后端并发控制

  • 迁移接口在事务内对源记录执行 SELECT ... FOR UPDATE(行锁),锁定源记录,避免与并发的编辑/其它迁移操作产生竞态。
  • 若源记录已被其它事务迁移或删除,SELECT FOR UPDATE 返回空 → 抛出「记录不存在或已被迁移」提示。
  • 引用同步、目标创建、源删除均在同一个事务内完成,任一步失败整体回滚,不产生中间态。

6.2 幂等与重复提交防护

  • 迁移成功后源记录即被删除;重复调用接口时源记录不存在,后端返回明确错误(「记录不存在或已被迁移」),不会重复创建目标。
  • 前端提交后立即进入 loading 态并禁用按钮,防止用户重复点击。

6.3 迁移与编辑的互斥

  • 迁移期间源记录被行锁锁定,其它用户的编辑操作(updateChannelExpansion / updateCrmExpansion)在锁释放前等待,避免「迁移了旧数据」的脏读。
  • 弹窗补填的字段在后端二次校验(必填、数值范围、进货商/对接人不能为空),校验失败整体回滚。

七、前端实现

  • 按钮位置:详情页底部操作区(现有「编辑资料」按钮旁),按 selectedItem.type 显示:type='channel' 显示「移至CRM拓展」type='crm' 显示「移至渠道拓展」,type='sales' 不显示。
  • 样式与交互:与编辑按钮同款按钮样式;点击后弹「迁移前补填」表单(复用现有表单字段组件与字典选项),校验通过后二次确认,再调用接口。
  • 状态处理:提交时 loading 态(按钮禁用防重复提交);成功后刷新列表、关闭详情并切换到新记录;失败时 toast 展示错误信息(如「记录不存在或已被迁移」)。

八、实现清单(后续开发步骤)

  1. 后端:新增 MoveChannelToCrmRequest / MoveCrmToChannelRequest DTOExpansionController 新增两个接口;ExpansionService 新增两个 @Transactional 方法。
  2. Mapper新增按源 id 更新 work_checkin / work_report_messagebiz_type / biz_id / biz_name、商机 channel_expansion_id 置空、其它CRM supplier_id 置空、删除渠道/CRM主表等 SQL。
  3. 并发防护:迁移查询源记录时使用 SELECT ... FOR UPDATE 行锁;重复迁移返回「记录不存在或已被迁移」;后端对弹窗补填字段二次校验。
  4. 前端:新增两个补填表单弹窗组件 + 两个迁移按钮 + 二次确认与成功刷新逻辑,提交时 loading 禁用防重复点击。
  5. 验证渠道→CRM 与 CRM→渠道 各执行一遍,核对主表、联系人、跟进记录、打卡/日报关联、商机引用均正确迁移或置空。