自研轻量级CRM系统:从Excel到客户管理的设计实践与踩坑复盘

发布时间:2026/9/19 9:24:01

自研轻量级CRM系统:从Excel到客户管理的设计实践与踩坑复盘 1. 为什么我会动手做DeskcommCRM从Excel表格到一套能用的客户管理系统先说个背景。去年年初我接手了一个三十来人的销售团队支持工作当时整个公司的客户信息管理还停留在Excel阶段——销售各自维护一份客户表格管理层每周要花小半天时间汇总数据不同人填写的字段口径五花八门状态栏里有人写“跟进中”有人写“谈得差不多”还有人干脆留空。最麻烦的是销售离职交接几份关键客户的聊天记录、报价版本、历史沟通要点全都散落在个人邮箱和个人微信里交接完基本等于信息断层。当时也想过直接采购现成的CRM产品市面上主流的Salesforce、HubSpot、纷享销客、销售易都做过调研能解决核心问题但有两个绕不开的障碍一是费用按坐席收费的SaaS产品三十个人一年下来不是小数目而且越往后加功能越贵二是定制能力销售团队的业务流程和字段习惯跟系统预设差异很大真用起来需要大量配置有些还改不动。折腾了大概两周我决定自己动手做一个轻量级的CRM系统这就是DeskcommCRM的由来。整个项目从立项到第一版上线用了大约六周之后又迭代了三个月稳定支撑了团队大半年的客户管理工作。这篇文章我会把整个项目的来龙去脉、功能设计、技术选型、踩坑过程以及后期推给其他团队使用时遇到的实际问题完整拆给大家。如果你也在纠结“要不要自研CRM”“CRM应该包含哪些核心功能”“自研过程中容易翻车的地方在哪”那这篇内容应该能给你一个比较完整的参考答案。这个项目适合两类人看一类是正在做同类内部系统规划的技术负责人或产品负责人另一类是准备接CRM相关外包项目的开发者。前者能从中看到需求边界和推行策略后者能直接复制一套可落地的设计思路省得从零踩坑。2. DeskcommCRM核心功能设计不是功能越多越好而是要让销售愿意用我见过不少CRM项目失败原因不在技术而在产品设计过度复杂。厂商演示的时候看起来很全面客户上一线使用时发现光录入数据就要点七八个按钮坚持不了一周就没有然后了。所以做DeskcommCRM的时候我的核心原则只有一句话让销售花最少的时间完成信息沉淀同时让管理层获得足够准确的业务视图。2.1 客户库和联系人先想清楚这两张表怎么关联客户库是所有CRM的地基。DeskcommCRM里客户和联系人是两张独立的表客户指企业或组织联系人指企业里面的具体对接人两者是一对多关系。这里有个设计细节值得展开——很多自研项目会图省事把客户和联系人合成一张表结果某个客户有多个采购对接人的时候就傻眼了只能建多条重复客户记录后面统计商机转化率时数据全是虚的。所以第一版我就坚持拆分客户表存企业名称、行业、规模、来源渠道、区域、状态潜在/进行中/合作/流失联系人表存姓名、职位、电话、微信、邮箱、以及关联的客户ID和跟进偏好备注。字段设计上有个小建议不要一开始就把所有字段都铺上去。我见过有些团队设计客户表列了五六十个字段强制填写项二十多个结果销售录入一次要两分钟体验极差。DeskcommCRM第一版只保留了十二个核心字段更多细分信息放在跟进记录里自然沉淀等数据积累多了再决定哪些提升为结构化字段。2.2 商机管理为什么漏斗视图必须跟阶段强绑定商机是CRM里最有业务价值的模块因为它直接关联收入预测。DeskcommCRM的商机表结构是商机名称、关联客户ID、预计金额、赢率、阶段初步接触/需求确认/方案报价/商务谈判/赢单/输单、预计结单时间、负责人。这个模块最关键的逻辑是阶段与赢率的强绑定关系。新建商机默认赢率10%到需求确认阶段调整为30%方案报价50%商务谈判80%赢单100%。这个设计思路有两个好处第一销售不需要自己填一堆数字系统根据阶段自动算赢率管理层看的加权金额自然就准确第二阶段流转必须按顺序走不允许跳阶段这样可以强制销售记录完整的推进过程复盘的时候知道商机到底卡在哪一环。实际做的时候我踩过一个坑允许销售手动修改赢率结果不同销售对赢率的判断标准完全不一样有人明明刚开始接触就填了70%整个预测管线直接就失真了。后来改成只允许阶段驱动赢率特殊情况必须主管审批才能调整数据才恢复正常。2.3 跟进记录和待办提醒把信息沉淀的成本降到最低跟进记录是销售每天使用频率最高的功能也是整个系统能否被坚持用下去的关键。我的设计思路是跟进记录的录入方式必须快越快越好。DeskcommCRM的跟进记录支持三种录入方式一是进入客户详情页直接填写二是通过快速跟进入口选择客户后填写三是通话或现场拜访结束后从待办事项里一键跳转记录。正文支持纯文本和同事提及功能每条跟进记录自动带上创建人、创建时间和关联客户。同时允许对跟进记录打标签比如“电话沟通”“微信联系”“见面拜访”“邮件往来”方便后期做沟通渠道统计。待办提醒模块解决了“知道要跟进但忘了跟”的问题。销售可以给每条客户设置下次跟进时间系统会在当天早上推送当日应跟进客户清单。这里我特别注意了“不要过度打扰”这个点——很多系统会做成到期就弹通知、短信、邮件连环轰炸销售很容易产生对抗心理。DeskcommCRM只做每天早上一次汇总推送没有实时轰炸团队接受度明显更好。2.4 自动化能力系统主动干活而不是等销售想起来自研CRM相比Excel最大的优势就是自动化。DeskcommCRM做了几个实用的自动化场景大家如果做同类系统可以参考这几个优先级新客户分配通过API从公司官网表单和企微渠道进来的线索系统根据“轮流分配区域匹配”规则自动分配给对应销售实时通知对方跟进。超期未跟进提醒客户状态为“进行中”但超过设定的跟进周期默认7天没有新增跟进记录系统自动将该客户置顶到主管的“沉睡客户”列表同时给负责人发一条通知。赢单自动触发动作商机状态更新为“赢单”后系统自动生成感谢邮件草稿并通知财务录入合同信息减少各环节之间的人工转手。数据导出日报每天早上8点把昨日新增客户、新增商机、跟进次数、转化率汇总成一张表格自动发送到管理层邮箱省去手动做报告的时间。自动化的核心价值在于“让系统主动干活”。这些能力看着不难但需要提前规划好事件钩子和任务队列后续我会在技术架构部分详细说。3. DeskcommCRM技术选型与整体架构哪些决策影响了后面三个月的幸福指数项目启动时我对技术选型的原则只有一句话选团队最熟的技术栈而不是网上最热门的技术栈。当时团队主要做Python后端和Vue前端所以后端直接定了FastAPI前端定了Vue 3加Element Plus数据库用的PostgreSQL部署环境是内网服务器加Docker Compose。这套组合保证了一个人能同时驾驭前后端不用额外引入新的学习成本。3.1 数据模型设计一张图理清客户、联系人、商机、跟进记录的关系整个系统的核心数据模型其实不复杂关键是理清对象间的关系Client客户与 Contact联系人是一对多关系Client与Opportunity商机是一对多关系Client与FollowUp跟进记录是一对多关系User用户与上述所有业务表都有创建人关联owner_idDepartment部门和Role角色单独成表用于做权限隔离数据库建表时需要注意外键索引这一块我在项目初期偷过懒后面数据量涨上来之后被狠狠教训了一次具体问题在下一节的性能优化里展开。3.2 为什么用FastAPI而不是Django用FastAPI的核心原因是三个字够轻、够快。FastAPI天然支持异步接口配合SQLAlchemy 2.0进行ORM操作写起来很顺手。而且它自带OpenAPI文档前端联调的时候直接看Swagger UI就能知道每个接口的请求体和返回结构省了很多沟通成本。如果项目规模再大一些需要内置Admin后台和管理员站点Django会是更合适的选择。但对于DeskcommCRM这个体量三十人内部使用、几百条接口Django的重量感反而会成为负担——启动慢、模块多、很多功能用不上还要注意安全问题。选型时候一定先问清楚“这套系统未来到底要跑多大”再决定上不上Django这类全家桶框架。3.3 权限模型设计这是自研CRM最容易翻车的地方权限模型我花了整个项目的三成时间来做事实证明这部分绝对不能省。DeskcommCRM的权限模型分三层系统级权限是否允许登录、是否可以进入系统管理后台数据级权限分为“仅本人数据”“本部门数据”“全部数据”三种范围操作级权限对某个模块是否允许创建、查看、编辑、删除、导出具体的实现方式是这样的用户表关联角色表角色表关联权限策略表权限策略里以JSON格式存放每个模块的访问级别和操作范围。后端每个接口在处理请求时都会先解析当前用户的策略再决定数据查询时的过滤条件。这里有一个从实际项目中得到的经验千万不要用“前端隐藏按钮”的方式来做权限控制。按钮虽然看不见了但只要懂点开发者工具的人一样可以发起请求操作数据安全漏洞非常严重。后端接口必须做二次校验前端隐藏按钮只是体验优化不是安全措施。后来项目推广到其他部门时权限模型又做过一次升级增加了“共享客户”的概念也就是A销售可以把某个客户共享给B同事临时跟进共享期间B同事拥有该客户的全部操作权限到期自动收回。这个需求是实际业务中冒出来的原先的简单权限模型支撑不了后期改动花了不少成本。3.4 集成方案想要推广CRM先从干掉Excel开始DeskcommCRM上线之后遇到的最大阻力不是销售不爱用而是历史数据怎么迁移。团队过往几年积累了一千多名客户的数据散落在七八份Excel里字段口径各不相同有的填了电话有的只填了微信有的客户名还是简称。我做了两个动作解决这个问题一是写了一个数据清洗脚本用pandas读入所有Excel字段映射统一后自动去重合并通过公司名称或联系电话判重冲突的记录生成人工审核清单二是在系统里预留了手工导入模板支持后续随时从Excel导入新的客户名单。集成这块还做了一件事对接企业微信的客户群机器人商机状态更新、超期未跟进提醒都会自动推送到相关群里。这个集成虽然简单但实实在在地提升了团队感知因为工作场景里大家习惯挂在企微上系统信息能直接触达就意味着“用了系统有反馈”这一步对推广期特别重要。4. 实测中踩过的坑权限越权、性能退化与并发覆盖的完整排查链路任何系统只有上线跑真实业务才会暴露问题DeskcommCRM上线后我也踩过几个比较有代表性的坑。这里把完整排查过程写出来方便大家遇到类似问题时有迹可循。4.1 权限越权漏洞换了个ID就能看别人的客户上线第三周的某天下午一个销售同事跟我反馈说遇到个怪事——他在浏览器地址栏里改了客户详情页URL最后的数字ID竟然打开了另一个人的客户记录。我第一反应是权限校验有没有漏掉哪个接口但仔细查了同一套代码列表页和数据详情页明明都是用了同一个依赖函数怎么会漏掉详情页呢排查链路是这样的先看访问日志确认异常请求走的确实是我以为的那个通用查询函数接着看后端代码发现问题出在一个叫“get_client_detail”的接口上这个接口为了兼容某种特殊场景在查询时直接调了另一个内部函数绕过了权限过滤装饰器。当时我为了快速实现功能写了这个“快捷通道”函数结果变成越权漏洞的源头。修复方案很粗暴也很有效把权限过滤逻辑下沉到数据查询层的最底层函数不让任何一个上层接口跳过。具体做法是写了一个get_client_queryset(user)函数所有需要查询客户的接口都强制从这个函数拿数据用户在查询条件里传入任何不属于自己权限范围的client_id都会被WHERE条件挡掉。这也成了一个原则性的教训权限过滤必须在数据库查询层做而不是在应用层做。4.2 数据量增长后的性能退化一次没建索引引发的连锁问题系统上线两个月后数据量上涨到一定规模——客户的跟进记录从原来的一千多条涨到了五六万条查询开始明显变慢。最典型的是打开客户列表页要等三秒才出数据销售在跟进记录里翻聊天历史更是卡到让人抓狂。用EXPLAIN分析慢查询日志定位到两个核心SQL一个是对跟进记录表按client_id和时间排序的查询另一个是对客户表按负责人和更新时间排序的查询。前者因为我在预留“灵活筛选”的时候给表加了很多OR条件的筛选组合完全没考虑索引优化后者是因为订单排序字段的排序规则和索引顺序不一致导致数据库放弃了索引走了全表扫描。修复方案分两步走第一步给所有外键字段client_id、owner_id和常用的排序列created_at、updated_at加上合适的单列索引第二步把几组高频查询条件做成联合索引确保SQL能走覆盖索引。优化之后列表页首屏时间从三秒降低到三四百毫秒跟进记录的翻页速度也从秒级变成毫秒级。这次踩坑给我最深的体会是不要等到“系统变慢了”才开始优化。项目上线前就应该预估数据增长速度在核心表上一次性把索引设计完整后面再补索引容易导致表锁定时间长影响线上使用。4.3 并发的跟进记录覆盖同一条客户记录两个人同时编辑会怎样这个问题是在一个真实场景里爆发的。有一天上午销售A和销售B同时打开同一个客户的详情页A先保存了一段跟进记录B相隔十几秒后也保存了结果A一刷新发现自己的记录不见了只剩B写的那段。根因很明确详情页采用了“整行保存”的方式前端把整条客户记录的字段全部重新提交后端用整条UPDATE覆盖原始行。A先写入B的后写入把A提交过来的旧字段值覆盖掉了。这属于典型的并发编辑冲突问题。解决这个问题我用的是字段版本号机制也就是乐观锁。在客户表加一个version字段前端编辑后提交时带上当前看到的version值后端更新时执行“UPDATE...WHERE id? AND version?”如果版本号不匹配说明数据已经被其他人改过接口直接返回冲突提示前端弹窗让用户决定是强制覆盖还是重新加载。同样的机制也应用在跟进记录的更新上从那之后再没出现过数据被静默覆盖的情况。另外跟进记录本身我做了只追加不可改的设计从产品逻辑上就杜绝了“改历史记录”的可能——想更正信息就再加一条新记录历史留痕。这种设计理念在审计类需求里非常推荐后续如果要接外部审计或合规检查能省非常多的事。4.4 导出大数据量时内存爆掉一次性全量查询不可取还有一个坑出在Excel导出上。某次管理层要拉全量客户和商机数据一次性导出一万多行后端处理到一半直接报内存溢出的错误整个服务重启了。问题在于我用的是ORM的all()方法一次性把全部记录加载进内存再转成pandas DataFrame写出Excel数据量小的时候没问题数据量一大就翻车。修复方案是改成流式查询使用yield_per分批从数据库读取数据每批500条处理后写入临时文件最后再合并输出。后来考虑到使用场景管理层通常只关心当前状态而不是全量历史还给导出功能加了筛选条件控制默认导出数量上限只有明确勾选“导出全部”才会走流式批处理通道。这个细节如果不在实际场景里跑一遍确实很难提前预判。5. 自研CRM的决策建议、MVP功能清单与团队推广经验如果你看完前面的内容正在犹豫要不要自己动手做一套CRM这一部分会比较实用。我会把项目总结之后的判断标准、功能优先级和推广心得一次性讲清楚。5.1 什么情况下适合自研什么情况千万别碰先说不适合自研的情况。如果你们的客户管理需求高度标准化业务流程跟市面上成熟产品差异很小直接买SaaS产品一定更省钱省事。自研系统的真实成本远不止开发那几周——后续的维护升级、权限调整、人员流动交接、服务器运维每一项都是持续的人力投入。适合自研的情况我总结成三条一是预算有限但团队规模够大买正版SaaS坐席费用一年远超一个开发人力成本二是业务流程有独特之处现有CRM产品需要大量定制才能适配三是对数据安全要求较高客户信息不能放第三方平台必须落在内网。DeskcommCRM当时三条全占三十人的坐席费用一年至少七八万而自研投入大约一个开发两个月的工作量销售团队的跟进逻辑确实很个性化客户数据库存在自己内网服务器上也让管理层更放心。三者叠加自研的ROI就非常清晰了。5.2 最小可行功能清单第一版应该做什么、不做什么自研CRM最容易犯的错误就是想把功能一步做全。DeskcommCRM第一版我只做了四个模块客户库、联系人、商机管理、跟进记录。系统管理后台只做了用户管理和角色权限连高级统计分析都没上。后来事实证明这个MVP思路是对的。前两周上线后团队先把日常客户记录用起来数据积累了两周之后我再看后台日志和实际使用的场景才理解哪些报表是真的高频需求哪些只是“听起来有用”的功能。比如客户来源渠道分析确实是管理层每周必看的数据而商机赢率趋势分析实际使用率就很低因为销售团队的业务周期短趋势分析看不出太多东西。给大家一个MVP功能优先级参考优先级功能模块说明P0客户库、联系人、跟进记录日常信息录入和查询的基础不可缺失P0权限模型数据隔离和操作鉴权安全底线P1商机管理与漏斗视图决策层最关注的业务数据P1简单报表新增/跟进/转化满足管理层的基本数据需求P2自动化触发超期提醒等提升使用黏性的关键但不能晚于P1上线P2Excel导入导出降低历史数据迁移和日常使用成本P3客户公海、共享机制等团队规模变大后按需补充P3对接企业微信、邮件等外部系统有明确连接需求再集成不要过度设计5.3 团队推广的经验技术做好只占一半另一半在运营策略CRM项目最终能否成功系统本身只占一半推动团队用起来的策略占另一半。我第一次推广时犯过一个严重错误只发了一封上线通知邮件就走了结果一周后打开后台登录率不到三成很多人还是继续用Excel。后来我调整了策略效果明显好很多。核心是三个动作第一从管理层切入让领导每周一在例会上直接看系统里的客户数据销售发现“领导是在看系统里的数据而不是听口头汇报”使用意愿马上不一样第二设定最低使用底线比如跟进记录每周至少一条、商机必须录入状态一开始标准定得很松等大家养成习惯再逐步收紧第三找一个“标杆销售”先行试点让高绩效销售的跟进记录和商机管理成为团队参考模板同事之间互相学习的扩散效率比自上而下要求高得多。另外一个心得是一定要给系统留出“暂时不好用但可以改”的余地。上线初期一定会有各种小问题和不顺手的地方当时我的做法是建了一个需求反馈群每周整理所有意见能改的快改、不能改的说明理由。团队看到提的意见真的会被采纳配合意愿会提升很多。这类细节操作写代码的时候是预料不到的但项目成败往往就取决于这些细节。DeskcommCRM这套系统至今还在团队内部稳定运行考虑到当前的功能边界和团队规模接下来的迭代方向会更集中在报表自动化和移动端适配这两个方向线上数据驱动流程优化已经初见成效。整个项目做完再回头看最大的收获其实不是代码量或技术难度而是深刻理解了一件事企业内部工具产品只有当使用者觉得“用它比不用它更轻松”时才是真正的成功。希望大家在自研或二次开发CRM时也能把这句话放在心里。
延伸阅读

更多相关文章

2026/9/19 9:24:01

401 导致 OpenCode 白烧 Token?TaoToken + OpenCode 这样验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 9:24:01

百度UE编辑器Word格式粘贴技术解析

1. 项目概述作为一名长期奋战在前端开发一线的工程师,我深知富文本编辑器中格式粘贴这个"老大难"问题有多让人头疼。特别是当产品经理要求实现"从Word直接粘贴保留所有格式"时,很多开发者都会倒吸一口凉气。今天,我就以百…

2026/9/19 10:39:06

Hi3531 uboot移植实战:DDR3参数配置与板级移植详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 10:39:06

压控振荡器电路设计:从指标到可流片的EDA路径

简介:这份PDF面向电子信息工程、自动化等专业学生及电子设计入门者,围绕压控振荡器(VCO)的电路设计展开,解决从原理分析到EDA仿真验证的完整学习需求。内容涵盖压控锯齿波、矩形波、三角波与方波发生器的设计任务与要求…

2026/9/19 10:39:06

6S锂电转24V/9A:H6801升降压芯片驱动无刷电机稳压

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 10:34:06

Claude Code vs Codex:同一把 TaoToken Key 跑 PR 评审

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码