资讯动态

自研CRM系统实践:从数据模型到权限设计,打造贴合业务的客户管理闭环

发布时间:2026/9/16 5:05:23 来源:尧图企业网站定制
从「DeskcommCRM」这个名字说起这个项目可能很多人第一眼会以为是某个商业CRM产品的名字但实际它是一个自建的客户管理系统实践项目。说白了就是围绕客户信息、跟进流程、团队协同这三件事从零搭一套属于自己的CRM系统。这个标题为什么值得拆解因为CRM这个领域看起来到处都是成熟产品但真正落到自己业务里总会发现各种别扭要么字段改不动要么流程跟你的实际打法对不上要么数据导来导去根本没法沉淀。所以我很早就想自己动手做一个DeskcommCRM就是在这个诉求下慢慢长出来的。这篇内容适合这几类人看被市面CRM产品字段绑死的中小团队想从Excel表格升级到系统化管理但不知道从哪下手的销售管理者以及正在做企业内部系统、想看看CRM模块该怎么设计的开发者。我会把我在设计和落地这套系统时踩过的坑、做过的取舍、确认过好用的思路尽量原原本本讲清楚。1. 项目整体设计与思路拆解CRM这个品类的核心价值从来都不是能记联系方式而是把客户生命周期里的关键节点管起来。市面上的免费CRM、付费CRM那么多为什么还要自研一套我在动手之前认真梳理过这个问题我觉得想清楚这一点比直接写代码重要得多。1.1 为什么自己构建一套CRM系统第一个原因是业务弹性。通用CRM的字段、状态机、审批流都是预设好的你要想调整客户阶段的命名为初步沟通、方案确认、合同谈判、回款完成这种贴合自己业务的节奏往往要花大功夫去配置甚至根本做不到。自研系统的核心优势就是改字段成本极低今天觉得跟进状态少了一个环节改一行数据字典就完了。第二个原因是数据归属感。SaaS免费的CRM数据放在别人的服务器上随着业务量起来你会越来越没有安全感。热词里不断出现永久在线的CRM网站和免费CRM与私人网站的区别本质上就是在问数据到底是放在自己手里安心还是用现成的省心我的回答是如果客户数据是你公司最核心的资产那就必须放在自己可控的范围内。第三个原因是系统打通。销售手里的客户不会只存在于CRM里还有合同、工单、财务回款甚至邮件、企微的沟通记录。自研系统意味着你可以随意做接口、写同步任务、做数据仓库这些在封闭SaaS里很难做到干净体面。1.2 功能边界的划定MVP该做什么、不该做什么很多个人项目死在功能越做越多。我做DeskcommCRM时给第一条铁律就是不做ERP不做OA更不做BI大屏只做好客户管理闭环这四件事。这四件事分别是客户档案统一管理、跟进记录留存、商机阶段推动、团队协同与权限隔离。像合同审批、财务开票这些我宁可先用别的工具处理也不塞进第一个版本里。原因很简单CRM首要任务是解决销售的客户数据散落在个人Excel和微信聊天记录里的问题先把这一个痛点打透才有资格谈扩展。我还刻意做了一个取舍不做复杂的销售漏斗统计页面只提供三个最基础的数字看板新增客户数、跟进次数、本月成交额。因为MVP阶段团队最需要的是用起来、把数据录进来而不是看着一个花哨的仪表盘自我感动。2. 核心细节解析与实操要点确定了边界之后接下来就是最折磨人但也最重要的事怎么设计数据模型和业务流程。这里充分考虑了两点一是业务方销售和销售主管的真实操作习惯二是技术实现上的简洁可靠。2.1 客户数据模型的重新思考客户数据怎么存不同系统差别很大。有的把客户简简单单当成一个公司名联系人有的会把公司、联系人、商机彻底拆开。我在设计时采用了公司-联系人-商机-跟进记录四层结构这也是目前业内相对成熟的CRM模型。为什么不能把公司和联系人压成一张表因为一个大型客户可能同时有采购负责人、技术负责人、财务负责人他们背后的公司是同一个。把公司和联系人分开意味着你可以管到这家公司目前有3个联系人在跟进每个联系人的决策角色不同。表面看这是多了一张表实际上它救了你后续很多报表和数据的命。商机层是我觉得最容易被新手忽视的。很多刚做CRM的人会把意向客户简单标成一个状态字段但这会导致一个问题你只能看到客户现在有没有意向却看不到它是怎么进阶来的。商机表存在的意义就是把一个客户从初步接触到成交的过程拆成多个可量化的阶段并且每个阶段可以关联预计金额、预计成交时间。这样销售主管一眼就能看出哪些单子有可能月底签约。跟进记录表的设计有两个细节值得分享。第一是永远不能删改只能追加。第二是每一条跟进记录必须关联跟进人、跟进时间、跟进方式以及下一步计划这个额外字段。为什么要单独做下一步计划因为只有强制销售写下下一步动作他下周才不会不知道该跟谁这个细节直接决定了CRM是真有用还是假摆设。2.2 线索到成交的业务流设计在DeskcommCRM里我把客户生命周期分成了5个标准状态线索、潜在客户、意向客户、成交客户、已流失。这套状态机和市面上的CRM大同小异但关键在于每个状态之间的转换条件必须在系统里体现出来。比如线索转潜在客户我设置的条件是至少完成一次有效沟通。这个条件不是靠代码硬判断的而是靠系统自动检测跟进记录里有没有有效联系这个标记。如果销售想把一个客户从线索直接拖到意向客户系统会弹窗提示缺少有效跟进记录是否确认跳级这个提示能在很大程度上防止销售拍脑袋改阶段。潜在客户升级到意向客户我要求必须填写客户需求概述和预计成交时间两个字段。这两个字段是非常好的销售过程指标。事后复盘时你会发现很多单子之所以迟迟不成交就是因为销售人员对客户要什么始终说不清楚——而系统用必填字段把这个模糊地带照亮了。2.3 公海池与客户分配的落地姿势公海池这个词是CRM体系里很有价值的设计。通俗讲就是系统里有一片客户池子销售可以主动捞取但如果一段时间没有跟进客户会被自动释放回池子里。我在第一版就把这个机制实现了规则定得很简单普通客户15天内无跟进自动释放重点客户放宽到30天。这个机制解决了一个很常见的问题员工离职或者调岗后那些被遗忘的客户数据如何重新激活。以前用Excel时人走了客户也就死了。有了公海池之后客户资源真正回归成了公司资产。落地这个规则时有个小技巧释放客户前一周系统会给负责人发送站内信提醒3天后该客户将被回收如有跟进请尽快填写记录。用温和提醒代替突然回收团队接受度会高很多。2.4 字段定制与产品灵活性的平衡做自研CRM最吸引人的点就是可以随意加字段。但我后来发现随意加是双刃剑谨慎设计字段类型非常关键。我给系统做了内置的字段类型支持包括单行文本、多行文本、下拉选择、日期、金额、关联客户、关联联系人。这样技术团队或管理员通过后台就给增加字段不需要每次都改数据库表。但毕竟不能做成一上去就能随便折腾。我在字段定制上做了权限区分业务管理员可以加字段普通销售只能填写内容。这样既保证了灵活性又不至于被某个同事手滑搞乱数据。3. 实操过程与核心环节实现这一部分我按实际落地顺序来写。支撑DeskcommCRM跑起来的核心模块整体技术栈不复杂但每一步都有值得注意的地方。3.1 系统架构与技术选型的实战记录做这类系统核心架构就一条Spring Boot 做后端MySQL 存业务数据Redis 做缓存和登录态前端用 Vue 3。这套组合很常规但它最大的好处是招人容易、资料多、踩坑有迹可循。很多热词里提到ruoyi office crm也说明了国内团队对这类基于基础框架快速搭建CRM的关注度。我是直接在自研框架上组织的不做无谓的重构但如果你从零开始用成熟的快速开发框架打底确实能省很多基建时间。为什么选MySQL而不是PostgreSQL怎么说呢MySQL对团队而言最熟悉尤其在Windows环境部署运维上少操很多心。数据量不大的情况下它稳定扎实完全够用。整个系统的核心表加起来大概有14张最大的客户表上万条记录时查询依然毫无压力。3.2 数据库表设计的细节-- 客户表company CREATE TABLE crm_company ( id BIGINT PRIMARY KEY AUTO_INCREMENT, company_name VARCHAR(200) NOT NULL, industry VARCHAR(100), company_size VARCHAR(50), source VARCHAR(50), status TINYINT NOT NULL DEFAULT 0, level TINYINT DEFAULT 3, owner_id BIGINT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_owner_status (owner_id, status) );这个表算是系统的主干。company_name一定要做唯一索引吗我实际测试过中国重名公司真的太多了所以我放弃了强唯一索引改成查重提示录入同名客户时系统会自动列出已有客户提醒销售确认是否重复。这是更务实的做法。联系人表contact要存姓名、电话、微信、职位、决策角色。决策角色这个字段很有用集成了决策人、使用者、技术把关人、商务对接人几个枚举值。有了这个字段你就能知道一个客户公司里到底是谁在真正推动这个采购。跟进记录表follow_up_record是另一个核心表需要重点说明CREATE TABLE crm_follow_up_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, company_id BIGINT NOT NULL, contact_id BIGINT, follow_type VARCHAR(20) NOT NULL, follow_content TEXT NOT NULL, next_step VARCHAR(500), next_time DATETIME, creator_id BIGINT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_company_created (company_id, created_at) );这张表看起来很朴素但是如果你要做销售过程复盘数据都靠它。我在实际开发中给这个表加了全文检索索引针对follow_content字段方便后面统计上周哪些客户聊过价格。这个功能很实用因为销售查询历史沟通记录时最烦的就是一条条翻。商机表business_opportunity则要设计得更贴合实际销售节奏商机名称类似某某公司年度SaaS采购项目商机金额预估价预计成交日期成交概率销售自己评估主管可以修改阶段用作下拉类型例如初步接触/需求确认/方案演示/商务谈判/赢单/输单每次商机阶段变化我会在表里留一个阶段变更历史JSON字段存下每次变更的操作人、时间和备注。虽然这不算最高级的做法但是实现简单复盘时也够用。3.3 权限体系与数据隔离的实现思路CRM最敏感也最麻烦的就是权限。我参考了永久在线的CRM网站里常见的企业级做法把权限分为三层功能权限、数据权限、字段权限。功能权限最简单就是RBAC角色有管理员、销售主管、销售、访客。数据权限稍微复杂它的核心是你能看到哪些客户。我采用了私有、部门内、全公司三种数据范围组合普通销售只看自己和公海池的客户销售主管能看到本部门所有人的客户管理员看全公司。实现这种数据权限我没有用太重的方案而是在SQL查询中动态拼接数据权限条件。通过当前登录人ID查出他的角色和部门然后拼接where条件比如普通销售只看owner_id 当前用户的数据。这套逻辑容易理解就算后面换人维护也好接手。字段权限在第一个版本我只用在成交金额和客户联系方式两个地方。这两个字段对销售是可见的但是对某些角色比如访客是不可见的。说白了不同角色看同一个客户详情页时展示的字段是不同的。做到这个其实也不复杂后台配置字段可见性前端根据接口返回渲染。3.4 跟进提醒与自动化任务的实现做CRM最怕的就是销售把客户跟丢了。所以我做了一个很轻量的自动化提醒方案每天上午9点给每个销售推送一份当天待办提醒内容包括三部分——今天该跟进的客户根据next_time判断、本周公海池即将释放的客户、已超期未跟进的客户。这个功能本质就是一个定时任务Spring Boot里的Scheduled注解就搞定了。核心是写好查询逻辑尤其是今天该跟进的客户别按next_time等于今天查那样如果销售昨晚把5单都录成明天跟进明天他就要被打爆。我最终用的方案是 next_time between now and 23:59:59 以及 overdue_count 统计。这套规则上线后团队的执行力提升是肉眼可见的。销售不再需要靠脑子记哪天要联系谁系统每天早上都会把作业送到眼前。4. 常见问题与排查技巧实录系统上线一段时间后一定会遇到各种奇怪的问题。我把我在DeskcommCRM里踩过、修过的几类典型问题列出来希望能帮你节省一点排查时间。4.1 客户数据重复录入排查发现很多重复是录入者使用不同关键词导致的比如北京某某科技有限公司和某某科技北京有限公司其实是同一家。我的应对措施是录入时实时查重但要把查重做得聪明一些不能只做完全匹配而是把公司名中的括号、空格、有限公司后缀做归一化后再比对能过滤掉大部分重复。归一化后再去重准确率会高不少。注意 查重不要试图一次性解决所有问题。重复客户是CRM的常态与其追求录入时严格拦截不如提供一个疑似重复客户审核列表让管理员定期合并。4.2 登录会话失效过快自建CRM最容易被吐槽的一件事就是用着用着刷新一下就退出了或者去开个会回来又要重新登录。我在排查登录态问题时发现主要原因是Redis会话超时设置太短还有前后端每次请求没有做静默续期。解决办法很简单登录态过期时间设置为8小时同时每次请求过来时刷新过期时间。前端再做一个拦截器在接口返回401时弹出友好的登录已过期请重新登录提示而不是白屏报错。这样体验就顺滑多了。4.3 导入Excel客户数据乱码Excel数据导入这个问题几乎每个团队都会遇到。导入一个500行的Excel跑完一看中文全部变成乱码。原因多半是编码格式不对通常Excel文件是GBK编码Java默认读取UTF-8这中间就出问题了。更隐蔽的情况是导入虽然成功但电话被识别成了科学计数法后几位变成0这是Excel自身的坑。我的解决方式是统一上传CSV文件并且在上传时让用户选择编码格式UTF-8或GBK。同时在导入模板里把电话、金额这类字段先行设置为文本格式避免被Excel自动转换。模板上多一行提示语导入成功率直接提升了一大截。4.4 客户数量大了之后页面变卡刚开始几百个客户时很快等数据涨到几万条之后列表分页就出现了明显卡顿。排查后发现问题不在数据库而在于列表页每次都要做多表关联查询统计每个客户的跟进次数和最后跟进记录。优化起来有两个技巧。第一在客户表上冗余最后跟进时间和最后跟进内容摘要两列用异步任务更新列表查询就不用去join子表了。第二列表页默认只展示当前用户有权限的客户而且先按最近跟进时间倒序走索引。优化完几万条数据翻页查询基本能保持在百毫秒级别。4.5 员工离职后客户归属如何安全转移这个问题很现实也不难处理。我做了离职交接功能操作上分两步一是把该员工名下所有客户归还公海池二是他曾经跟进但商机尚未关闭的客户自动转移给销售主管。这个操作在下线账号时必须强制完成否则那些商机数据就成了无主数据。另外离职员工的跟进记录、历史操作日志必须保留绝对不能删。作为公司资产所有操作痕迹都要留存这也是CRM系统的一个底线原则。5. 部署环境与运维安全实践系统上线只是开始持续稳定运行才是硬道理。我在这个项目里最看重的不是某个功能有多炫而是数据别丢、账号别泄、服务别挂。5.1 基础环境要求与部署步骤以一个小型团队实际使用为例服务器配置建议是2核4G起步如果团队超过20人或者并发访问量较高升到4核8G会更从容。服务器推荐使用Linux环境。部署步骤分这几步安装JDK配置MySQL和Redis打包后端jar包编译前端用Nginx做反向代理并托管静态文件。我在第一次部署时遇到一个很典型的坑前端页面能打开接口却全部报错。排查发现是因为前端项目里的API域名写的是localhost后端在服务器上前端却跑在本地浏览器导致跨域请求失败。这个问题的根源是环境配置分离没做好。所以这里提醒大家前端的接口地址一定要分别配置开发环境和生产环境变量不要写死。5.2 数据安全的三重策略第一重是数据库定期全量备份每天凌晨3点跑一次mysqldump保留最近7天的备份文件。第二重是操作日志留痕所有的登录、查看客户、修改客户、删除记录都写入操作日志表。第三重是敏感字段加密联系人的手机号不能明文存库。加密我推荐使用AES对称加密把密钥放在服务端配置中心不放到前端代码里。手机上显示号码时解密数据库里存的是密文。哪怕数据库备份被人拷走了光靠备份文件他也拿不到联系方式。这一点在执行时很容易被忽略但等真出问题的时候它就是你唯一的防线。5.3 运维监控的轻量实现小团队没必要上复杂的监控系统。我用的是一个轻量方案后端项目里写一个健康检查接口每隔1分钟由服务器定时任务去访问这个接口如果连续3次访问失败就发一封告警邮件到管理员邮箱。再加一个磁盘空间检测脚本当磁盘使用率超过85%时自动发出告警。这套监控成本极低但价值很高。它能在用户还没发现系统崩溃时就先把问题暴露在管理员面前。跑了一年后总结90%的故障预警都是靠这个简单机制发现的。6. 后续演进的几个方向CRM不是做完就完了业务变了系统就得跟着变。我个人认为DeskcommCRM后续最重要的演进方向有三个。第一个方向是把商机阶段与合同、回款打通。当前版本的成交动作非常粗只是在商机上点一个赢单按钮。真正跑起来之后你会发现赢单之后还需要合同台账和回款计划否则财务和销售之间又得靠Excel私聊。把这一环打通系统才算真正覆盖客户全生命周期。第二个方向是做轻量级销售分析报表。在积累足够多的数据和跟进记录之后可以开始分析几个关键指标不同渠道的客户转化率、平均成交周期、每个销售的商机金额预估准确率。这几个数字对经营决策特别有价值而且基于现有数据结构统计起来并不难。第三个方向是接入企业微信或钉钉的客户联系功能。这个方向灵活性比较强因为有的团队习惯用企业微信沉淀客资。让销售在企微里添加的客户能自动同步到CRM并在首页看到今日待跟进列表会对使用体验有明显提升。不过这个方向工作量不小一定要先评估自己的精力再动手。做这类系统我个人最大的体会是别想着一口气做完美CRM的本质是让数据流动起来让过程有迹可循而不是功能大而全。初期哪怕有阵痛先让业务跑起来比关起门来写完美代码重要得多。把一套客户数据从个人Excel和聊天记录里抽离出来变成一个团队共享、权限清晰、过程可追溯的系统资产这件事本身就是巨大的管理升级。DeskcommCRM这个项目目前已经稳定跑了半年多团队没有一天停止使用它——对我而言这就是这个项目最大的成功了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价