桌面CRM系统设计与实现:基于Electron、Vue与SQLite的实战拆解

发布时间:2026/9/16 13:52:25
桌面CRM系统设计与实现:基于Electron、Vue与SQLite的实战拆解 做销售管理系统的朋友应该都有体会客户资料放在哪永远是个老大难问题。我最近把一个内部项目完整梳理了一遍名字叫 DesкcommCRM。简单说这就是一个把客户资料、沟通记录、任务提醒和业绩统计揉到一起的桌面端客户关系管理系统重点解决“销售跟进动作不透明、员工离职客户蒸发、月底统计全靠手工”这三类最头疼的问题。整套系统的设计核心就三句话数据尽量留在本地录入速度要快老板想看报表的时候不用求人。如果你正在考虑自建CRM或者团队规模不大但客户管理流程开始变得混乱又或者你单纯想了解一个真实的CRM项目从零到落地的过程这篇拆解都值得你看看。我不会只讲功能列表更多会讲“当初为什么这么设计”“实际落地时哪里容易翻车”这些文档里不怎么会写的东西。1. 项目背景与整体设计思路1.1 为什么叫DeskcommCRM它到底解决什么问题DesкcommCRM 这个名字是我自己起的拆开看很直白Desk 表示桌面端Comm 是 Communication 的缩写CRM 就是客户关系管理。连在一起这个项目的定位就清楚了一个跑在桌面上的、以沟通记录为核心的客户关系管理工具。先说痛点。我之前待过的一家团队销售每天都在用企业微信、邮件、电话和客户沟通客户资料散落在每个人的聊天记录、Excel 表格和名片夹里。老板问“这个月这个客户聊到哪一步了”没人能立刻回答销售离职以后客户资源直接断档新接手的人连客户之前报过什么价都不知道。这种状态一旦持续团队表面上是做了很多事实际上所有信息都在流动中流失了。DesкcommCRM 要解决的就是四件事把客户资料全部集中到一个地方打开就能查到每一次电话、邮件、微信沟通都留痕形成完整的时间线销售每天该跟进哪些客户、哪些商机快到期系统主动提醒主管和老板随时看到团队跟进量、成交金额和转化率不用等月底手工汇总。这套东西听上去不复杂但实际做起来坑很多。为什么要强调“桌面端”而不是直接买一个在线SaaS我在下面一节详细说。1.2 为什么不做成Web版而选择桌面端确定做自研以后第一个被反复讨论的问题就是做成网页版还是桌面应用市面上成熟的CRM基本都是在线SaaS网页版开发也方便。但我最终把DesкcommCRM定成了桌面端应用理由有三条。第一数据主权。团队客户数据包含手机号、报价、合同等敏感信息销售出差时还可能在没有稳定公网的环境下使用。如果做成纯云端的Web应用网络不稳定时基本没法干活数据也等于全部放在第三方服务器上。第二录入效率。销售的实际使用场景是打完一个电话手头还有下一个客户等着根本没时间打开浏览器等页面加载。桌面应用可以做到常驻托盘、全局快捷键唤起、窗口即开即用整个录入动作在两三秒内完成。这个体验差异直接影响员工愿不愿意用。第三成本门槛。维护一套带登录鉴权、数据库、文件存储的Web服务对一个小团队来说是不小的运维负担。而桌面端应用只需要在每台电脑上装一个客户端数据库文件也落在本地没有服务器费用没有并发崩溃对IT基础薄弱的团队非常友好。当然桌面端也有它的代价比如无法在手机上随时查看、多人协作要靠后面加同步机制。实际方案是“先本地化后逐步加共享同步”这也是我认为最稳妥的演进路径。2. 核心功能模块拆解与设计考量2.1 客户档案CRUD只是起点字段设计才是关键客户档案是CRM的地基。DesкcommCRM 的客户表在设计时参考了销售业务里的常见需求核心字段不算多但每一个都要经过业务语义确认。基本的客户表包含客户名称、联系人姓名、职务、手机号、微信号、邮箱、客户来源转介绍/展会/网络咨询/自拓、所属行业、客户等级A类重点客户/B类普通/C类潜在、跟进状态新客/初步沟通/方案洽谈/成交/流失、下次计划跟进日期、备注。听起来都是常规字段但有两个设计细节特别重要。一是“客户名称必须唯一”。很多团队会在Excel里把同一个客户写成“某某科技有限公司”和“某某科技公司”导致后续重复发资料、重复跟进。DesкcommCRM 在导入和手工新建时都会做去重校验系统提示疑似重复后由操作人决定合并还是保留。二是“客户等级要和跟进动作联动”。一个客户如果被标成A类系统会默认要求销售每三天至少有一次沟通记录如果超过七天没有新记录主管看板里就会高亮提示。这样客户分级就不再只是一个标签而是真正驱动行为的管理工具。另外客户档案模块还支持给客户打自定义标签比如“关注价格”“决策周期长”“技术型客户”等。标签可以多选后面统计看板会按标签维度做聚合分析。这种设计比单纯固定字段灵活得多也是后续做精细化运营的基础。2.2 沟通记录与商机推进把跟进过程串成时间线沟通记录是 DesкcommCRM 最核心的部分。每个客户页面下面都有一条时间线按照时间倒序列出所有动作打过电话、发过邮件、见过面、报过价、改过需求。每一条记录还能绑定一个“商机阶段”。商机阶段我做成标准的销售漏斗线索 → 初次接触 → 需求确认 → 方案输出 → 报价谈判 → 赢单/输单。每一条商机记录都包含预测金额、预计成交日期、赢单概率。系统会根据阶段自动调整赢单概率比如进入“方案输出”阶段默认50%进入“报价谈判”默认75%。为什么要把沟通记录和商机阶段放在一起因为在真实业务里销售说“最近在跟一个大客户”但你看不到他具体做了什么。有了时间线和阶段联动主管扫一眼就能知道这个客户一个月前就进入报价阶段了到现在还没推进可能卡在价格上也可能销售根本没跟进。这样就倒逼销售必须把动作记录下来。这里有一个实操心得不要让销售写长篇记录。DesкcommCRM 的沟通记录设计成“模板补充”的形式比如“电话沟通”模板里只要填沟通要点和下一步动作其余细节可选填。降低记录成本员工才愿意坚持使用。如果做成开放式的长文本日记两个月后大概率没人用。2.3 任务提醒让系统追着销售跑CRM用不起来的另一个常见原因是“没到时间想不起来跟进”。DesкcommCRM 做了一个任务提醒模块每天的待办列表自动从两个来源生成一是客户字段里的“下次计划跟进日期”二是手工创建的任务比如“周三前给客户发方案”“下周一预约演示”。到时间以后客户端会在系统托盘弹出提醒并滚动显示今天必须完成的事项。提醒机制是这套系统里做得比较细的地方。第一版只做成应用内弹窗结果很多销售直接把客户端最小化提醒根本看不见。后来改成调用系统原生通知并且在应用标题栏和托盘图标上同时显示未完成数量关闭客户端之前还会二次提示“你还有3条任务未完成是否确认退出”。另外任务提醒还做了“超滞”判断逻辑预定跟进日期超过三天没执行这条记录自动升级为红色警告并在主管的看板上显示。这样做的好处是销售比较忙的时候优先级最高的客户不会因为忘记跟进而凉掉。2.4 团队看板统计报表自动化销售管理的最后一步是看结果。DesкcommCRM 的团队看板分成三个层级销售个人看板、团队看板、管理层汇总看板。每个层级的数据权限不同销售只能看到自己的业绩主管能看到团队所有成员的客户和跟进量老板看到的是全局汇总。统计维度包括各阶段的商机数量和金额本周新增客户数量、有效跟进次数销售个人成交金额排名客户来源渠道转化率平均成交周期从建立客户到赢单的天数流失客户原因分布。这里最关键的其实是口径统一。很多团队在Excel里统计时经常因为“什么叫有效跟进”“成交金额按回款还是按合同金额”吵架。我在表结构里把这些指标都做成了固定的计算字段比如有效跟进的定义是单条记录超过50字或包含下一步动作的跟进记录成交金额按合同金额计。口径固定以后不同人看数得到的结果完全一致不再有扯皮空间。3. 技术选型与数据模型3.1 客户端技术栈怎么选才稳DesкcommCRM 的客户端技术栈最终定为 Electron Vue 3 SQLite。这套组合可能不是最炫的但一定是最稳的。Electron 的优势在于生态成熟系统级通知、托盘常驻、全局快捷键都有现成方案前端开发人员上手快。缺点我也承认安装包大、内存占用高。如果你特别在意安装包体积可以考虑 Tauri但当时团队对 Rust 不熟业务又在快速迭代没有必要为了省一两个百兆字节去折腾编译链。数据层用了 SQLite。CRM的数据量以单机为标准一个销售一年撑死几千个客户几万条沟通记录SQLite 处理这些完全没压力。而且 SQLite 是单文件数据库备份、迁移都特别简单整个过程就是复制一个.db文件。前端框架选择 Vue 3 是因为组件化开发友好加上 Element Plus 组件库表格、表单、弹窗这些后台管理页面常见元素都是现成的两周时间就能搭出一个能用的原型。这里建议界面开发经验不多的团队一定要选一个成熟组件库不要自己造轮子。3.2 核心数据表与关键字段DesкcommCRM 的数据库结构围绕业务设计核心表有7张用户表、客户表、联系人表、沟通记录表、商机表、任务表、操作日志表。下面挑重点说。用户表 (users)用户ID、姓名、角色admin/manager/sales、账号状态、密码哈希。密码采用加盐哈希存储不要用明文这是数据安全的第一条底线。客户表 (customers)客户ID、客户名称、客户来源、所属行业、客户等级、跟进状态、负责人ID、下次跟进日期、创建时间、更新时间。负责人ID关联用户表用来做数据权限隔离。联系人表 (contacts)联系人ID、客户ID、姓名、职位、手机号、微信号、邮箱、是否主要联系人。一个客户可以挂多个联系人但主要联系人只能有一个。沟通记录表 (interactions)记录ID、客户ID、商机ID可空、类型电话/邮件/微信/拜访/其他、内容摘要、下一步动作、创建人、创建时间。这条表和商机关联起来就是完整的时间线。商机表 (deals)商机ID、客户ID、商机名称、阶段线索/初次接触/需求确认/方案输出/报价谈判/赢单/输单、预测金额、预计成交日期、赢单概率、创建人、更新时间。任务表 (tasks)任务ID、负责人ID、客户ID可空、任务类型、内容、截止日期、完成状态、完成时间。客户表里的“下次跟进日期”其实是这条任务的冗余字段单独建表是为了支持更多维度的任务管理。操作日志表 (audit_logs)日志ID、操作人、操作类型新建/编辑/删除/导出/登录、目标对象、时间。这表平时不起眼但到了排查问题、确认谁删了客户的时候它就是唯一的真相来源。建表的核心SQL我贴一段供参考CREATE TABLE customers ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, source TEXT, industry TEXT, level TEXT DEFAULT C, status TEXT DEFAULT new, owner_id INTEGER, next_follow_date DATE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (owner_id) REFERENCES users(id) ); CREATE TABLE interactions ( id INTEGER PRIMARY KEY AUTOINCREMENT, customer_id INTEGER NOT NULL, deal_id INTEGER, type TEXT NOT NULL, summary TEXT, next_action TEXT, creator_id INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (customer_id) REFERENCES customers(id), FOREIGN KEY (deal_id) REFERENCES deals(id), FOREIGN KEY (creator_id) REFERENCES users(id) );外键关系一定要建它能在数据库层面兜底防止页面代码逻辑出错时产生孤儿数据。3.3 本地存储、备份与扩展同步SQLite 默认的日志模式是 DELETE并发稍微一高就容易出现 database is locked。DesкcommCRM 第一次团队测试时三个销售同时录入就有人报错。解决办法是把数据库切到 WAL 模式并且在连接串里设置 busy_timeout。WAL 模式允许读和写在同一个文件里并发执行明显减少了锁等待。使用体验上最容易被忽视的是备份。我用了一个很简单的方案客户端设置里提供“数据备份”按钮点击后把当前.db文件复制一份到备份目录同时每日首次启动时自动做增量备份保留最近30天。这个功能在后面的实际使用中救过我好几次有一回同事电脑系统崩溃重装靠备份文件十分钟就恢复了数据。如果以后需要团队共享数据我建议不要做成本地直连同一个SQLite而是走“客户端写本地异步同步到中心库”的轻量架构。同步时以更新时间戳为准对同一条记录发生冲突时保留修改时间较新的那一份并把被覆盖的版本放到回收站里避免信息彻底丢失。4. 实操落地与关键配置4.1 搭建项目骨架从零到能跑起来如果你也想自己搭一个类似的桌面CRM我把 DesкcommCRM 的搭建过程拆成几步照着做就可以快速看到效果。第一步初始化前端项目。我的经验是用 Vite 创建 Vue 3 项目后续打包到 Electron 也比较顺畅。执行以下命令npm create vitelatest deskcomm-crm -- --template vue cd deskcomm-crm npm install第二步安装 Electron 和相关插件。注意要把 Electron 装到 devDependencies启动和打包分别用 electron 命令和 electron-builder。npm install electron --save-dev npm install electron-builder --save-dev第三步引入组件库和路由。Element Plus 和 Vue Router 都是必装项一个提供UI组件一个负责多页面切换。npm install element-plus vue-router4第四步在 Electron 主进程里创建应用窗口设置常驻托盘和最小化到托盘的行为。这里一个关键点是关闭窗口时不真正退出进程而是隐藏窗口这样后台实时数据和系统提醒才能持续生效。第五步接入 SQLite。在 Node 环境下我推荐用 better-sqlite3它是同步API写起来直观性能也很好。npm install better-sqlite3初始化数据库时先判断数据库文件是否存在不存在则执行建表语句存在就直接打开。这里建议把数据库文件路径放在用户数据目录不要放在程序安装目录否则安装路径有中文或权限限制时会出现打开失败。项目骨架搭好后再慢慢把客户管理、跟进记录和任务模块的页面填进去。这套原型开发周期大概在十天到两周核心功能就能通。4.2 从Excel批量导入客户数据清洗先行导入客户是系统上线的第一道坎也是体验最容易崩的地方。DesкcommCRM 里做了一个CSV导入器支持用户选择文件、预览数据、匹配字段再执行导入。整个过程最花心思的不是导入逻辑而是数据清洗。现实中从Excel拿过来的客户名单通常有一堆问题手机号被格式化成科学计数法手机号字段里混着“转-1001”这种分机号公司名称有几个变体还有不少重复项。导入器在后台按顺序做这几件事手机号清理去掉空格、横杠、括号统一成11位数字公司名标准化去掉“有限公司”“股份有限公司”等后缀后再比较去重重复客户自动合并必填字段检查客户名称、负责人必须存在其他字段为空则使用默认值。导入完成后系统会生成一份导入结果报告列出成功条数和失败原因。失败数据不进库会下载一份带错误说明的模板修改后再重新导入。这里提醒一句批量导入一定要先让一个人做测试导入一小部分看结果再全量导入否则很容易把几十万条脏数据带进来。4.3 权限与敏感数据保护CRM里存的是客户联系方式、跟进记录、报价信息权限设计不合理后面一定会出事。DesкcommCRM 的权限模型分成两层功能权限和数据权限。功能权限控制的是“能不能访问某个页面”比如普通销售看不到团队看板只有 manager 和 admin 能看到。数据权限控制的是“在同一张客户表里能看哪些行”普通销售只能看到自己负责的客户主管可以看到团队所有人的客户。实现上用了后端中间件拦截每次接口请求都会先判断当前用户的角色再拼上 owner_id 条件去查询数据。前端只是隐藏菜单关键还是后端防御。这里要特别注意权限校验不能只在数据库层做应用层也要重复判断否则接口可以直接被调。敏感数据方面我做了三件事手机号默认掩码显示比如“138****1234”点击“查看完整号码”需要权限导出功能只在管理员权限下开放且每次导出都会写入操作日志数据库文件用SQLCipher加密存储防止有人直接把数据库文件拷走然后脱机拆解。数据安全这件事不需要做到银行级别但基础防护一定要有。很多时候客户数据泄露不是因为技术强攻而是因为权限太宽松、文件没加密、日志没留存。4.4 业务流程参数配置系统上线前必做的事DesкcommCRM 虽然是一个工具但它也承载了业务流程。在上线之前需要把以下业务参数配置好跟进状态枚举新客 / 初步沟通 / 方案洽谈 / 成交 / 流失。这个列表按团队业务定制最好一次定清楚避免以后改菜单导致旧数据口径混乱。客户来源渠道转介绍 / 网络咨询 / 展会 / 电话拓客 / 邮件营销 / 其他。来源渠道会在看板里用来分析投放效果不要随便填一堆临时值。赢单概率规则不同阶段自动匹配概率比如线索阶段10%、需求确认30%、方案输出50%、报价谈判75%、赢单100%。这个规则可以由主管维护前端只是展示结果。自定义标签库提前定义好常用标签比如“预算充足”“决策链复杂”“即将招标”避免每个人各写一套风格。商机编号规则系统自动生成的商机编号比如“SO-2025-0001”给每个商机一个独立编号沟通和报价都引用编号后续检索特别方便。这些配置我建议用一个独立的“系统设置”页面来管理配置项存到一张 key-value 表里而不是写死在代码中。这样以后调整流程规则不需要重新发布版本管理人员在界面上就能操作。5. 常见问题与排查技巧实录5.1 高频问题速查表项目从上线到稳定运行肯定要踩不少坑。下面这张表是 DesкcommCRM 使用频率最高的一批问题问题现象、可能原因、解决思路我都列出来。问题现象可能原因排查与解决思路启动时报 database is locked多个进程同时写SQLite或日志模式未切换开启WAL模式设置busy_timeout检查是否有多开客户端系统提醒不弹窗系统通知权限未开启或客户端静默常驻后台检查操作系统通知权限调用系统原生通知API避免只用自绘弹窗导入Excel后日期变成数字Excel日期序列号在CSV里被转成数值导入前在Excel中把日期列设为文本格式导入器识别后统一转为YYYY-MM-DD搜索客户名非常慢客户量上万但没建索引给 name 字段建索引中文模糊查询量大时引入全文搜索功能升级新版本后数据不见了数据库路径被硬编码安装目录变化导致指向新文件把数据库路径统一放到用户数据目录升级前自动检测原数据库并迁移两个销售同时改一个客户信息被覆盖没有冲突检测后写覆盖先写增加更新时间戳字段编辑前校验版本号冲突时提示保留哪一版这张表成了团队的应急预案遇到问题不用从头摸直接按表格里的思路一步步查效率高很多。5.2 排查思路与复盘心得实际排查问题我的经验是“不看表象先看日志”。DesкcommCRM 从第一版开始就建立了统一日志模块所有登录、新增、编辑、删除、导入导出操作都会记录到操作日志表同时客户端本地也会生成运行日志文件。有一次销售反馈“客户明明在列表里点开详情却是空白”我第一反应不是去看前端组件而是打开日志文件发现详情接口返回了 500。再查原因是客户记录里有一条商机的 deal_id 指向了已删除的商机外键约束触发了错误。这种问题如果没有日志光靠猜可能要折腾一整天。排查过程中还有一条重要原则数据误操作恢复前先把数据库文件复制一份出来。我曾经在一次“清理重复客户”的批量删除中误删了部分正常客户幸好提前备份了才能完整恢复。现在我把“动手前先备份”作为所有管理操作的前置条件谁要清理数据先执行一遍备份再说。另外测试环境要准备好假客户数据别拿生产库演练。我们用了一个“演示数据生成器”能自动生成一批带随机公司名、手机号、跟进记录的模拟客户。新功能上线前先在这个数据集上跑一遍尤其是导入导出、权限过滤、看板统计这些容易出问题的场景。5.3 备份、恢复和升级的注意点备份策略这块上文提过做了每日自动备份和手动备份这里再补充三个容易忽略的点。第一备份文件要定期做恢复演练。备份不是“复制了一个文件”就算完要定期把备份文件恢复到一台干净的电脑上确认数据完整、能正常打开。否则真到灾难发生时才发现备份文件已经损坏就晚了。第二升级前必须确认数据库版本兼容。DesкcommCRM 后续更新过两次表结构增加过字段。数据库迁移用了简单的版本号机制数据库文件里存了一张 schema_version 表客户端启动时检查版本号如果发现旧版本就执行对应的迁移脚本。升级速度快还有一个好处不会出现新版本不识别旧数据库的兼容性事故。第三数据目录要避开系统权限限制。最初的版本把数据库放在安装目录下后来发现Windows更新后安装目录权限变化导致客户端无法写入。改成用户数据目录后这类问题彻底消失。建议所有桌面应用数据文件一律放系统定义的通用数据目录不要和程序目录混在一起。最后说一点我自己的体会这种内部工具一开始不用追求功能齐全先把“录入快、查得着、提醒准”三件事做好后面自然有人愿意用。DesкcommCRM 从第一版到现在迭代了快一年功能一直在加但最初那套客户表和跟进记录的时间轴设计一直没有推翻过因为那才是业务最底层的骨架。希望这篇拆解能给正准备做客户管理系统的人一些参考。