SpringBoot3+Vue3+UniApp CRM:线索转客户、商机推进、合同回款怎么一条链落地
🌐 文档地址:https://ruoyioffice.com
📦 源码1·GitHub:https://github.com/yuqing2026/ruoyi-office
📦 源码2·GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office
📦 源码3·Gitee:https://gitee.com/yqzy1688/ruoyi-office
💬 微信:17156169080(备注「RuoYi Office」)
两个销售同时打一家公司,跟进写在微信里,合同过了回款还能超。根因不是少一张客户表,是线索、商机、合同、回款各写各的。RuoYi Office 把客户当成主数据:转化带着跟进走,金额逐级校验,审批通过才算合同,回款加总不能超过合同额。PC 管理端和 UniApp 移动端读同一套接口、同一条客户 id,不是两套台账。
▲ 演示客户 id=17。左边 PC /crm/customer/detail/17,右边手机「客户详情」。跟进、商机、合同、回款是同一组 Tab,不是各写各的
▲ 线索转客户 → 商机推进 → 合同审批 → 回款核销。客户是主数据,审批才认合同,回款不能超
引言:CRM 难在「链断了,表还在」
缺的不是客户字段,是对象之间谁改谁、什么时候改。
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
本文只讲这一条链:线索 → 客户 → 商机 → 合同 → 回款。产品目录、漏斗统计、公海 Job 细则是旁边的能力,这里只点到和链有关的规则。
菜单:CRM → 线索 / 客户 / 商机 / 合同 / 回款。合同流程 key:crm-contract-audit。回款流程 key:crm-receivable-audit。
一、产品能力:客户是主数据,别的都挂上去
销售、主管、财务看的不是五张孤立列表,而是同一个客户身上发生了什么。
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
owner_user_id
|
列表上三个视图:我负责的 / 我参与的 / 下属负责的。同一份数据,不用复制三套表。
详情页才是工作台。客户详情把跟进、联系人、商机、合同、回款收在一组 Tab,不要让销售在五个菜单之间来回切。PC 是宽屏 Tab,手机是顶栏滑动 Tab,字段和审批状态对得上。
二、业务怎么走:转化、推进、审批、核销
开发库可以对照这几条:线索 演示线索(id=8)已转到客户 16;客户 演示客户(id=17)下有合同 HT20240225000001、回款 HK20240225000017 全额 16016。
1. 线索:未验证,不要进客户库
/crm/clue 录的是还没确认的需求。负责人、下次跟进时间和客户一样,但没有公海。线索不进公海,避免市场名单被回收规则误伤。
转化按钮只给 OWNER。点「转化为客户」后:用线索字段建客户、写 OWNER 权限、线索打上 transformStatus=true 和 customerId。线索上的跟进记录复制一份到客户,bizType 从线索改成客户。已经转化过的再点,直接报错。
▲ /crm/clue/detail/8 基本信息。名称「演示线索」,最后跟进已写回。已转化后顶栏不再露出「转化为客户」
转化不是改个状态那么简单。客户页必须立刻能看见上次聊了什么,否则主管打开客户会以为没人跟。
2. 客户:中枢页,跟进写回最后联系时间
/crm/customer/detail/:id 顶栏是负责人、成交、距公海天数。下面 Tab 才是链:跟进、联系人、商机、合同、回款。
写一条跟进,服务会回写 contactLastTime、contactLastContent、contactNextTime,并把 followUpStatus 置真。公海的「未跟进天数」读的是这几个字段,不是看有没有打开过详情。
公海页 /crm/customer/pool 看到的是 owner_user_id 为空的客户。领取 / 分配走同一套:必须没负责人、没锁定、没成交,新负责人不能超领取上限。放入公海则清空负责人,并删掉 OWNER 权限。
锁定和成交是豁免:占着不跟也不该被收回。这是产品规则,不是 Job 写漏了。
▲ PC /crm/customer/detail/17 基本信息。负责人、成交、锁定都在这张卡上;商机 / 合同 / 回款是同一页的 Tab
▲ UniApp #/pages-crm/customer/detail/index?id=17。名称、来源、手机、负责人与 PC 一致;底部是编辑 / 删除,Tab 滑到合同、回款
3. 商机:阶段自己推,赢单不等于合同
商机挂在客户上,创建时落到状态组的第一阶段,并算产品明细总额。推进阶段走 updateBusinessStatus:已经有终态(赢单 / 输单 / 无效)就不能再改。
前端「变更商机状态」弹窗:正数 statusId 是阶段;负数取反后当 endStatus。赢单是销售过程的结论,审批通过的合同才是财务认的单。创建合同时可以带 businessId,回调里不会自动把商机改成赢单——两件事不要绑死,避免「赢了但合同被拒」或「合同过了商机还停在谈判」。
4. 合同:草稿才能提交,通过才能收钱
合同挂客户,可选挂商机。提交时必须是草稿,流程 key crm-contract-audit,状态改成审批中。只有审批中的单允许回写审批结果。通过后 onContractApproved:有合同中心就可选推送正式合同,没有就写主数据台账。
开发库 HT20240225000001(id=13)已是审核通过,金额 16016,客户 17。详情 Tab「回款」能同时看到计划和实收。
▲ PC /crm/contract/detail/13 基本信息。客户「演示客户」、金额 16016、审核通过。未通过的合同建回款会被拦
▲ UniApp #/pages-crm/contract/detail/index?id=13。编号 HT20240225000001,审批通过,已回款 16016。外勤看的是同一张单
5. 回款:加总不能超过合同
回款必须挂已通过的合同。金额校验把「已通过 + 审批中」都算进去,编辑时扣掉自己,剩余额度不够就抛错。审批中的回款也占额度,防止两张单同时超。
HK20240225000017(id=29)金额 16016,刚好等于合同额,审批已通过。再录一笔就会被拦。
▲ PC /crm/receivable/detail/29。编号 HK20240225000017,审批通过。超额在保存时拦,不是对账时才发现
▲ UniApp #/pages-crm/receivable/detail/index?id=29。合同 HT20240225000001、金额 16016、审批通过。手机上改金额,后端额度校验一样拦
回款也走 crm-receivable-audit。计划占用:一个计划期只能挂一张回款,避免两笔核销同一期。
三、设计怎么落地
设计思路
|
|
|
|
|---|---|---|
|
|
|
customer_id
|
|
|
|
|
|
|
|
|
|
|
auditStatus=20
|
|
|
|
|
|
|
|
crm_permission
|
|
客户负责人空着就是公海。权限表和业务表并行,不要只靠 owner_user_id 判断能不能编辑——参与人走 WRITE / READ。
转化先建客户再改线索,避免半转化。回款保存时就算额度,审批中也占坑。
// 线索转化:只能一次;建客户后回写 customerId,并复制跟进public void transformClue(Long id, Long userId) {CrmClueDO clue = validateClueExists(id);if (clue.getTransformStatus()) {throw exception(CLUE_TRANSFORM_FAIL_ALREADY);}Long customerId = customerService.createCustomer(BeanUtils.toBean(clue, CrmCustomerCreateReqBO.class), userId);clueMapper.updateById(new CrmClueDO().setId(id).setTransformStatus(Boolean.TRUE).setCustomerId(customerId));// 跟进 bizType 从线索改成客户,bizId 换成 customerId}
合同提交只接受草稿。通过回调才改 20,驳回 / 取消不会打开回款入口。
public void submitContract(Long id, Long userId) {CrmContractDO contract = validateContractExists(id);if (ObjUtil.notEqual(contract.getAuditStatus(), DRAFT)) {throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT);}String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey("crm-contract-audit").setBusinessKey(String.valueOf(id))).getCheckedData();contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId).setAuditStatus(PROCESS));}
回款超额在保存时拦。审批中的回款也算占用,避免两张单同时过。
private void validateReceivablePriceExceedsLimit(CrmReceivableSaveReqVO reqVO) {CrmContractDO contract = contractService.validateContract(reqVO.getContractId());List<CrmReceivableDO> receivables = receivableMapper.selectListByContractIdAndStatus(reqVO.getContractId(),Arrays.asList(APPROVE, PROCESS));BigDecimal remain = contract.getTotalPrice().subtract(sum(receivables, CrmReceivableDO::getPrice));if (reqVO.getPrice().compareTo(remain) > 0) {throw exception(RECEIVABLE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT, remain);}}
权限切面:CRM 管理员放行;无团队成员时公海允许 READ;OWNER 拥有全部操作;WRITE 才能改。转化、转移要求 OWNER,避免参与人把别人的客户转走。
四、和「Excel + 微信」差在哪
|
|
|
|
|---|---|---|
|
|
owner_user_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
crm-contract-audit |
|
|
|
|
|
|
|
crm_permission
|
|
|
|
|
|
合同中心是可选下游。CRM 合同过了,可以推正式合同草稿,不是必须上第二套合同模块才能收钱。
五、快速体验
PC:https://ruoyioffice.com/web/
移动端 H5:https://ruoyioffice.com/app/
账号 admin / admin123,两端看同一条客户。
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
源码仓库:GitHub:https://github.com/yuqing2026/ruoyi-office | GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office | Gitee:https://gitee.com/yqzy1688/ruoyi-office
常见问题
线索转化后,原来的跟进还在吗?
在。服务按线索 id 查出跟进,批量改成客户 bizType / bizId。线索页仍能看历史,客户页也能看,不是挪走一条。
商机赢单会不会自动生成合同?
不会。合同要销售自己建,再走 crm-contract-audit。赢单只是商机终态,避免「过程赢了、合同被拒」两边状态打架。
为什么审批中的回款也算额度?
两张回款同时审批,如果只算已通过,两张都能过,加总超合同。审批中先占坑,驳回后再释放。
没负责人的客户谁能看?
公海客户没有团队成员时,READ 放行,才能打开详情点领取。WRITE / 转化仍要权限,避免路人改资料。
CRM 合同和合同中心是不是同一张单?
不是。CRM 合同是销售链上的金额单据。通过后可以推送到合同中心补全用印、履约。只上 CRM 也能回款,不必绑第二套模块。
结语
这条链能跑住,靠的是三句话:客户是主数据,审批才认合同,回款不能超。 线索转化带着跟进走,商机自己推阶段,合同和回款各走一条 Flowable。PC 详情和 UniApp 详情读同一条 id,外勤改金额也会被额度拦住。权限按单据成员拦,公海只收没人跟、没锁定、没成交的卡。
同一套「主数据 + 过程单 + 金额单」还可以用在项目台账对合同、进销存对客户出货。先把销售链走通,再谈漏斗图和排行榜——图是结果,链才是产品。
💡 想要体验 RuoYi Office 的强大功能?
🌐 在线演示:https://ruoyioffice.com/web/(账号 admin / admin123)
📦 源码仓库:GitHub:https://github.com/yuqing2026/ruoyi-office | GitCode:https://gitcode.com/zhouzhongyan/ruoyi-office | Gitee:https://gitee.com/yqzy1688/ruoyi-office
💬 技术咨询:添加微信 17156169080,备注「RuoYi Office」
⭐ 如果觉得不错,请给个 Star 支持一下!

