ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

自研通信型CRM系统实践:从需求拆解到技术落地全复盘

自研通信型CRM系统实践:从需求拆解到技术落地全复盘 DeskcommCRM这个名字听起来不像常见的内部项目代号它其实是我们最近大半年从零开始搭建的一套面向销售团队的CRM系统。团队内部一直在讨论“这套系统到底应该叫什么”后来定成了DeskcommCRM理由也很直白Desk代表销售每天要看的那块桌面工作台Comm则取communication沟通与通信。做系统的这段时间我踩了不少坑也推翻过两版设计方案整个过程挺有代表性的所以抽空把它复盘成一篇长文。如果你正打算给团队选型CRM或者被领导安排去调研“客户系统怎么做”又或者是想了解一个带通信留痕能力的销售管理系统从需求到落地需要经历哪些环节这篇文章应该有参考价值。它里面没有那种“上系统就成功”的鸡汤只有具体的数据模型、技术选型、部署细节还有一个个真实的翻车现场。1. 项目背景与需求拆解1.1 为什么需要一个“带桌面工位的CRM”我们团队做的是企业级销售不算特别大但客户一多问题就藏不住了。最典型的场景是客户在哪儿答案散落在业务员的个人邮箱、微信聊天记录、本机通话记录和Excel表格里。一个客户发来的报价需求可能上周在邮件里讨论过一轮这周换人在微信上又追了一遍但新人进来根本看不到历史上下文只能靠老同事回忆。这种状态最怕的就是人员流动。销售一旦离职和客户之间的邮件往来、沟通记录、跟进进展全部跟着个人账号一起消失了。公司在客户资产这个层面没有沉淀所有的“关系”都变成了销售的个人资产这是管理层完全无法接受的。所以项目启动之初最大的目标就一句话把销售跟客户之间所有能留下的沟通痕迹统一收到一个客户数据池里。传统CRM其实也试图解决这个问题但我们在选型市场走了一圈后发现市面产品普遍偏“重”功能像瑞士军刀里面一半功能用不上而通信能力又是销售最看重的部分普遍没有做深。要么是邮件接入要单独买插件要么是外呼通话记录根本无法和客户详情页打通。在真实销售场景里销售不可能一边开着CRM一边又开一个网页邮箱、再装一个呼叫中心客户端来回切换本身就是对效率的巨大伤害。所以我们要做的不是又一个客户信息台账而是一个在通信和客户管理之间天然贯通的系统。销售点开一个客户就能看到这个客户的所有邮件、通话、短信记录顺手就能在原位上记录下一步跟进计划。这是DeskcommCRM整个产品逻辑的核心。1.2 产品定位与命名逻辑项目代号是DeskcommCRM本质上就是“带桌面工位的通信型CRM”。这里的Desk并不是说它是一个桌面软件而是强调销售登录系统后第一眼看到的就是一个“销售工作台”——左侧是客户和商机列表中间是客户详情和业务数据右侧是通信时间线。所有信息一屏可见不需要跳来跳去。拆开来看我们把这套系统的能力收敛成四个模块客户与联系人管理公司级客户档案一个客户下面可以挂多个联系人避免“只在某一条微信消息里找到一个人名”商机与跟进管理把客户从线索到成交的完整过程拆成阶段配合跟进记录形成决策链通信留痕邮件、电话、短信统一接入按客户和联系人自动归Id数据看板从线索量、商机金额到成交转化率给销售管理做决策依据这四个模块并不是同时开工的。在项目管理上我们用了优先级排序通信留痕和客户管理是第一优先级商机推进和看板后续跟上。因为客户数据一旦沉淀不完整商机模块建得再漂亮也是空中楼阁。1.3 目标用户与边界范围从一开始我们就把目标用户钉死在“销售业务人员”身上没有贪多。管理层要看的数据看板其实是后置需求在数据沉淀还不到位的时候做再多图表也是无米之炊。边界范围也很明确不做财务、不做进销存、不做售后工单。这些业务系统虽然和客户有交集但每个领域都有自己的业务逻辑硬塞进一个CRM里只会让系统变得臃肿。项目启动时我们和业务方开了三次范围确认会核心议程就是砍需求。很多失败项目的原因不是功能太少而是范围失控把自己做成了一个谁都不满意的“大杂烩”。明确边界的好处在后来的开发中体现得很明显。技术团队可以集中精力把通信留痕这条主链路打磨好业务方也能直观地感知到“系统每天都在解决问题”而非“系统每天都在增加我不懂的按钮”。2. 技术选型与架构设计2.1 为什么不直接买SaaS CRM有人可能会问既然市面SaaS CRM那么多为什么还要自己做这个问题我们内部也辩论过最终有三个因素让我们彻底放弃采购路线。第一是成本。按坐席数收费的SaaS产品50人团队每年的订阅费累计起来非常可观而且随着人数增长还是一笔长期开支。自研虽然前期有人力成本和研发周期但从我们的使用规模来算一年半差不多就能收回成本。长期来看自研的经济账是划算的。第二是定制局限。我们需要深度集成邮件收发、外呼通话记录、短信记录还要能接企业内部某些特殊的销售流程。SaaS大多只提供标准API真的要打通这些通道很多厂商要求购买更贵的版本甚至需要走商务流程申请白名单。有些通信功能SaaS产品压根没做比如“客户邮件本地归档”这种需求几乎要把我们推到和第三方邮件服务商单独对接的境地。第三是数据安全。客户数据是我们最核心的资产一旦放在第三方平台上虽然对方也承诺安全但从风险控制角度讲把核心客户数据和通信内容放到自己可控的服务器里显然是更稳妥的选择。这一点也是业务方和法务同事最在意的诉求。自研不是否定SaaS产品的价值而是我们在评估自身业务特点后给出来的结论。如果你的业务形态比较标准、销售流程简单、也不强依赖通信留痕那买一套成熟的SaaS产品可能反而更高效。2.2 技术栈与团队能力匹配技术选型这件事我一直坚持一个原则选团队最熟悉的技术而不是选社区最热门的技术。我们团队以Java和Vue为主所以后端选了Spring Boot前端选了Vue 3数据库用了PostgreSQL另外砍掉了原本考虑过的微服务架构服务之间走的是最简单的HTTP接口和同一套MySQL。一整套核心技术的选型决定我做成了表格方便复盘层次选型选择理由后端框架Spring Boot 2.7团队Java技能栈稳定生态成熟遇到问题容易找到资料持久层MyBatis-Plus单表CRUD效率高复杂查询可以手写SQL成员上手迅速数据库PostgreSQL 14JSONB字段适合保存呼叫记录、邮件元数据的扩展信息缓存Redis登录会话、验证码、热点列表缓存性能兜底前端框架Vue 3 Element Plus中文文档完善表单和表格组件丰富开发效率高对象存储MinIO邮件附件、通话录音文件自托管数据不经过第三方中转计划任务XXL-Job邮件定时收取、数据统计预计算支持失败重试和日志部署方式Docker Compose服务器规模不大Compose足够避免K8s带来的维护负担这里想特别说一下为什么没用MySQL。其实我们原本就准备用MySQL团队成员对它也更熟但后来在设计客户表和通信记录表时发现呼叫详单、邮件原始头信息这类数据有多态字段比如不同渠道的通信记录属性差异很大用MySQL要么建一堆冗余列要么拆出一堆从表。PostgreSQL的JSONB字段正好能解决这个问题既能存结构化字段做索引又能存半结构化的扩展信息。对于这种“主体字段稳定、扩展字段灵活”的场景PG明显更合适。2.3 通信模块的集成思路通信留痕是整个系统最核心的差异化能力但也是集成复杂度最高的部分。我们从三条线并行推通信接入。邮件这块用的是标准的IMAP协议收信、SMTP协议发信。每位销售在系统里绑定自己的业务邮箱后后端会定时到邮件服务器拉取新邮件然后解析正文和附件按照发件人邮箱识别关联到对应的客户和联系人。邮件同步要特别注意不要重复收取我们的做法是记录每封邮件的Message-ID在数据库建立唯一索引。电话和短信这块我们选了云通信服务商。外呼电话会发起一个呼叫请求通话结束后服务商把通话时长、录音文件地址、挂断时间等通过回调接口推送给CRM。短信则简单一些发送成功或失败会有状态报告回调。回调接口本质上就是一个HTTP接口难点在于保证成功率因为第三方服务商的重试策略和延迟都比内部服务靠网络更不可控。站内信和Web推送这样一条内部沟通通道则用WebSocket实现。不过这块走后端实时研发的同学应该也很熟悉重点是做好掉线重连和消息幂等。通信模块打通后才能真正实现“一个客户一个ID所有沟通都在ID下面”。这个ID就是customer_id它在客户表、联系人、商机、通信记录之间扮演着核心关联角色所有模块的业务都是围绕它展开的。3. 核心模块与数据模型设计3.1 客户与联系人模型客户和联系人的数据模型我们设计了得非常细。很多人把客户和联系人混成一张表这是设计上最忌讳的事情。一个公司客户下面会有采购、技术、财务等多个角色分别参与不同的决策环节。如果所有角色都堆在客户这一层后续做权限控制、通信归Id都会非常麻烦。我们的核心表结构大致是这样的CREATE TABLE customer ( id BIGSERIAL PRIMARY KEY, name VARCHAR(200) NOT NULL, industry VARCHAR(100), source VARCHAR(50), owner_id BIGINT NOT NULL, owner_department_id BIGINT, external_ref VARCHAR(100), data_scope VARCHAR(20) DEFAULT PRIVATE, status VARCHAR(20) DEFAULT ACTIVE, created_at TIMESTAMP WITH TIME ZONE DEFAULT now(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() ); CREATE TABLE contact ( id BIGSERIAL PRIMARY KEY, customer_id BIGINT NOT NULL REFERENCES customer(id), name VARCHAR(100) NOT NULL, phone VARCHAR(50), email VARCHAR(200), position VARCHAR(100), is_primary BOOLEAN DEFAULT false, created_at TIMESTAMP WITH TIME ZONE DEFAULT now(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() );在这个模型里customer是客户主体contact是客户下面的联系人。每个联系人通过customer_id关联回客户这样通信记录通过联系人找到客户商机也通过客户汇总。需要说明的是owner_id这个字段它是数据权限的关键。我们定义了三种数据范围个人PRIVATE、本部门DEPARTMENT、全公司COMPANY。默认情况下普通销售创建的客户是PRIVATE销售主管可以看部门的客户管理员可以看全公司的。这个设计在后续也给我们带来了不少权限排查的工作量后面专门讲。3.2 商机与跟进记录设计商机简单说就是一个可能成单的机会对应销售漏斗里的一个条目。商机表相对直接核心字段是金额、阶段、预计成交日期。阶段我们做了固定枚举暂定为新线索、已联系、需求确认、方案报价、商务谈判、成交、失败。销售每次更新商机阶段系统会记录一条阶段变更历史方便管理者回溯成单或丢单的原因。跟进记录的业务价值很容易被低估。很多团队觉得跟进记录就是给销售自己写日记用的其实它是整个系统时间线上最重要的一环。因为客户详情页左侧是客户主信息右侧线程就是跟进记录和通信记录混合排序未来任何一个接手这个客户的人都必须靠这条时间线来快速了解上下文。跟进记录的设计使用多态关联CREATE TABLE follow_up ( id BIGSERIAL PRIMARY KEY, related_type VARCHAR(20) NOT NULL, -- CUSTOMER / CONTACT / OPPORTUNITY related_id BIGINT NOT NULL, content TEXT NOT NULL, next_action VARCHAR(500), next_action_time TIMESTAMP WITH TIME ZONE, creator_id BIGINT NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT now() );related_type和related_id组合在一起意味着一条跟进记录可以挂在客户、联系人或者商机下面。这样做的好处是当销售在客户详情页写了跟进记录如果此时这个客户下面正好有一个商机处于“方案报价”阶段我们就能自动把这条记录挂到商机上。销售不需要重复录入时间线和商机阶段都能串起来。3.3 通信留痕设计通信留痕是我们这套系统的招牌也是设计难度最高的模块。需要屏蔽邮件、电话、短信三种渠道的差异对外提供一个统一的查看入口。业务上通信记录和客户、联系人、商机都可能相关所以我们采用了一张主表加一张扩展表的方案。主表结构是这样的CREATE TABLE communication_log ( id BIGSERIAL PRIMARY KEY, channel VARCHAR(20) NOT NULL, -- EMAIL / CALL / SMS / CHAT direction VARCHAR(10) NOT NULL, -- IN / OUT from_addr VARCHAR(200), to_addr VARCHAR(200), subject VARCHAR(500), content TEXT, duration_seconds INT, file_url TEXT, message_id VARCHAR(300), customer_id BIGINT, contact_id BIGINT, opportunity_id BIGINT, occurred_at TIMESTAMP WITH TIME ZONE NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT now(), UNIQUE (channel, message_id) );这张表最关键的字段是message_id和唯一约束。对于邮件message_id就是邮件本身的Message-ID对于电话message_id由服务商回调里的会话ID转换而来对于短信message_id是短信记录ID。靠这个唯一约束我们才能确保重试回调不会产生重复的通信记录。通信“归Id”是这里的核心逻辑。收到一封邮件系统会按如下顺序尝试关联客户精确匹配根据发件人邮箱到contact表里精确匹配联系人命中则通过联系人找到customer_id域名匹配如果发件邮箱是company.com而客户表里有一个客户的域名恰好也是company.com则关联到该客户线程匹配根据邮件的References和In-Reply-To头找到历史邮件的message_id沿用历史邮件的客户关联关系人工认领以上都未命中就进入“未认领邮件”池由销售手工标记客户这个四层归Id逻辑是我们在实操过程中反复打磨出来的最初只做了精确匹配结果大概有三分之一的历史邮件都进不了客户详情页。加上域名匹配和线程匹配后归Id准确率提升到了90%以上剩下的靠人工补录已经可以接受了。3.4 桌面工作台的交互设计信息架构确定之后交互设计就顺理成章了。我们的桌面工作台遵循三栏式布局这是借鉴了很多主流邮箱和CRM产品的设计经验因为销售一天里有很大一部分时间是和邮件、客户记录打交道三栏式符合他们的思维模式。左栏是客户列表和事业部筛选支持按负责人、行业、来源筛选同时有一个“本周待跟进”的快捷入口销售一进来就能知道今天要跟进哪些客户。中栏是客户详情上面是客户基本信息、所属联系人、当前商机下面默认展示最近跟进记录。右栏是通信时间线把所有邮件、电话、短信按照时间倒序铺排开每条通信记录都可以展开查看正文电话还能直接播放录音文件。三栏布局最大的好处就是销售不再需要开两个浏览器标签页来对照邮件和客户信息。右栏通信时间线展示它们是同一个客户的不同沟通维度这比单纯“客户详情里能看到几封邮件”的体验要自然得多。另外右栏提供“新增跟进记录”的快捷按钮系统会把当前客户和联系人的ID自动带到表单里减少了手动输入的步骤。4. 实操部署与关键配置4.1 环境准备与初始化项目从代码到可用的过程我们选的是Docker Compose作为部署方案。原因很简单服务器不多Docker Compose足够管理好所有依赖组件而且配置可以写进Git仓库环境一变随时重建。下面是一份简化但完全可用的docker-compose配置version: 3.8 services: postgres: image: postgres:14 container_name: deskcomm-postgres environment: POSTGRES_DB: deskcomm POSTGRES_USER: deskcomm POSTGRES_PASSWORD: change-me ports: - 5432:5432 volumes: - pg_data:/var/lib/postgresql/data redis: image: redis:7 container_name: deskcomm-redis ports: - 6379:6379 minio: image: minio/minio:latest container_name: deskcomm-minio command: server /data --console-address :9001 environment: MINIO_ROOT_USER: deskcomm MINIO_ROOT_PASSWORD: change-me ports: - 9000:9000 - 9001:9001 volumes: - minio_data:/data app: build: . container_name: deskcomm-app depends_on: - postgres - redis - minio environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/deskcomm SPRING_REDIS_HOST: redis MINIO_ENDPOINT: http://minio:9000 ports: - 8080:8080 frontend: build: ./frontend container_name: deskcomm-frontend depends_on: - app ports: - 80:80 volumes: pg_data: minio_data:这里面有两个容易栽跟头的地方。第一个是PostgreSQL的时区必须在数据库连接串里明确设置时区否则服务器时间是UTC业务看到的时间就会相差8小时。向日葵式的“到点了没记录”十有八九就是这个原因。第二个是MinIO的访问地址容器内部用的是服务名minio但前端或服务端如果需要生成外网访问链接得配置一个外部可达的域名否则邮件附件和录音文件在前端打不开。4.2 应用配置中的常见问题部署层面有很多细节是文档里不会特别强调的这里挑几个直接影响生产可用性的重点展开。数据库连接串时区问题。默认的PostgreSQL驱动会跟JVM时区保持一致如果JVM没有设置为Asia/Shanghai那么所有时间字段在读取时都会出现偏移。我们的做法是在两个地方都设上时区一是在JVM启动参数里加-Duser.timezoneAsia/Shanghai二是在连接池URL里加上sessionVariablestime_zone08:00。两个都设置之后全链路时间才统一。对于邮件收取不建议设置过短的同步周期也不要直接用一条for循环逐个拉取每个账号信件。我们初期用的是固定30秒轮询后来随着邮箱账号增多30秒周期根本拉不完。最终改成XXL-Job定时任务每个邮箱单独一个任务任务间错峰执行并且增加了“上一轮任务未完成则本轮跳过”的分布式锁防止任务重叠。文件上传大小限制这个问题会隐藏得很深。Nginx默认允许的请求体大小是1MB而我们上传邮件附件、录音文件时经常超过这个值导致前端报了一个“接口找不到”的错误。排查了半天才意识到服务端根本没有执行到业务代码。解决方式是在Nginx的server块里增加client_max_body_size 20m同时Spring Boot里的spring.servlet.multipart.max-file-size也要配套改。还有一个关于回调地址的坑。第三方通信服务商的回调地址必须是公网可访问的HTTPS接口而我们初期用了测试服务器的HTTP地址结果对方平台一直报签名校验失败。后来在网关层配置了HTTPS证书并在服务端对回调请求做好验签才真正稳定下来。这个过程中需要强调的是回调接口必须保证幂等因为服务商可能同一回调重复推送很多次。4.3 关键功能的配置流程在客户系统正式上线之前有几个关键配置必须提前完成否则销售团队第一天使用体验就会崩掉。第一是权限初始化。在我们系统里系统超级管理员、部门管理员、普通销售这三类角色权限差异很大。普通销售默认只能看到自己名下的客户部门管理员能看全部门超级管理员可以跨部门看。初始化时我们把每个角色对应的数据权限和功能权限都录进权限表然后给每个销售分配了唯一的业务邮箱地址这样才能在邮件归Id时准确定位到责任人。第二是外部客户导入。销售团队手里都有大量历史Excel客户数据我们提供一个统一的导入入口上传Excel后系统会异步处理。导入模板需要严格校验邮箱格式、手机号格式和必填字段。导入过程中采用“先清洗后入库”的方式在临时表里做去重和格式校验再写入正式表。这一步如果不做好线上就会涌入大量错误和重复数据后面数据质量很难修。第三是通信渠道授权。每位销售需要在自己的账号设置里授权CRM读取邮箱收信权限和发送邮件权限。这一步我们采用邮箱账号密码方式但我们并不推荐收集明文密码而是建议走OAuth授权码模式。不过因为我们主要自建邮箱系统可以通过应用授权码来规避明文密码泄露的风险。授权完成后系统会做一次全量历史邮件回拉之后进入增量同步。第四是公海客户自动分配。我们把公共池里的客户称为公海客户一旦某个销售符合领取条件或管理员指派客户就会自动绑定到对应销售名下并立即记录在操作日志里。这个步骤别看简单如果不做操作留痕后续销售之间因为“这个客户是谁先拿的”产生扯皮就会消耗大量管理精力。所以上线前我们特意把客户领取、转交、丢弃的操作追踪日志完整接好了。5. 常见问题与排查实录5.1 客户数据导入又慢又重复上线第一次大批量导入公司给了我们一份将近12000条客户的Excel。我们写了一个循环逐条INSERT并查重结果跑了30多分钟还没结束而且导进去的数据里还出现了很多重复项。原因是业务同事给的Excel里同一家企业被录入了多次只是联系人电话和邮箱不一样。后面我们彻底改掉了逐条导入的方式采用三步策略先把Excel解析进临时表字段保持原始字符串其次在临时表里按企业名称、域名、电话号码做标准化和去重最后再把清洗后的数据批量写入正式表写入时使用PostgreSQL的COPY命令或INSERT批量多值语句整体速度提升了近百倍。为了确保数据质量我们在正式表上还建立了以customer.deleted_at、customer.name为主体的唯一索引方案防止后续手工导入时再次产生重复。5.2 邮件重复收取与漏收邮件模块上线第二天就发现同一个客户回复的邮件在系统里出现了两份。一开始以为是IMAP同步的多线程问题后来排查发现我们的拉取逻辑是把每次轮询结果都当全量处理了但是邮件服务商对一条新的邮件在第一次拉取时会标记为未读第二次拉取时又会返回一次导致重复插入。解决方法是在邮件模块里记录每封邮件的UIDVALIDITY和UID并通过message_id在communication_log表里做唯一约束。这样即使重复拉取插入时也会因为唯一键冲突而失败。与此同时针对漏收问题我们调整了邮件拉取的调度逻辑不再只依靠增量标记而是每天凌晨结合全部邮件做一次兜底全量对比找出那些标记异常但实际存在的邮件再补拉进来。5.3 权限越权与性能问题权限问题是在上线一周后由销售主管反馈的。有一位普通销售在系统里搜索客户名称时竟然搜到了其他部门正在跟进的客户。当时大家第一反应是“是不是搜索接口没拼权限字段”事实也确实如此。我们最初的代码在查询客户列表时使用了一个公共的search方法直接依据名称字段做模糊查询漏掉了data_scope权限判断导致任意登录用户都能搜到全表客户。后来我们把数据权限过滤下沉到了一个统一的MyBatis拦截器里在每次执行SQL时自动注入当前用户的可见客户范围。这种方式虽然对SQL有一定侵入性但能确保所有查询入口都带上权限条件开发人员在写新接口时也不容易遗漏。性能问题紧随权限问题曝光客户列表越查越慢从最初的500毫秒慢慢爬到了4秒以上。抓了慢SQL日志发现列表查询把客户表、联系人、跟进记录做了大量LEFT JOIN结果每一行还带了全文大的content字段。优化方式很简单列表只查主表和必要的聚合列详情接口才去加载完整内容。同时给customer表的owner_id、name加上了索引把模糊查询从开头% LIKE改成了pg_trgm的相似度索引性能立刻改善了很多。5.4 通信回调偶发丢失电话录音回调丢失这个问题困扰了我们将近两周。第三方通信平台显示呼叫记录正常但我们CRM里偶尔会有某几条录音始终没有写入。后来在平台侧查日志发现回调接口偶发返回5xx错误第三方平台按策略重试了两小时仍然失败最终丢弃了回调。排查下来是两个原因一是我们的回调接口缺少幂等逻辑同一条回调重复推送时因为message_id唯一约束产生了冲突接口返回了SQL异常导致平台认为推送失败二是对部分第三方平台的JSON签名校验不兼容验签失败时会拒绝请求。修复方案分三层在接口最外层增加一个分发器先做验签验签通过后再进入业务逻辑业务逻辑加幂等判断message_id已存在时直接返回成功不操作数据库在Redis里维护一个回调处理队列不让第三方平台的请求长期占用HTTP连接先把回调放进队列再异步落库修复之后回调的丢失率从1%降到了几乎为零。这里的经验是所有第三方回调接口都应该默认对方是不可靠的幂等、验签、异步落库这三件事必须齐活。6. 上线之后的经验复盘项目上线并稳定运行了两个月业务方的反馈整体是积极的但我也必须说CRM这类系统真正的挑战不在开发期而在使用习惯养成的过程。系统功能再强大销售就是不录、不更新数据池就永远是空的。我们初期为了鼓励录入做了很多运营侧的动作。比如“跟进记录周冠军”排行榜每周统计每个销售的跟进和通信数比如把“客户下一次联系时间”作为周会必问项让销售形成使用习惯。这比单纯在系统里加提醒按钮管用得多。另外一定要安排一个“数据治理专员”的角色负责监控重复数据、未认领数据和无主客户每两周做一次数据质量报告。没有这个角色CRM的数据会随着时间推移缓慢腐烂最后变成一个没人愿意打开的垃圾堆。还有一个容易被忽视的点通信留痕涉及合规上线前务必和法务确认数据保留时长、用户授权告知、录音提示语等细节。我们最开始忽略了录音提示语后来在合同评审时才补上改动了云通信服务商的录音文件号配置折腾了不少时间。最后再分享一个小技巧。做类似系统时不要一上来就把所有字段做成必填项。销售在新增客户时你让他填公司名称、行业、来源、负责人、下一次跟进时间他大概率会烦。我们的做法是必填只有客户名称和负责人其他全部选填。随着使用深入、团队规范建立再逐步把关键字段设为必填。系统是为人服务的录入成本越低数据才会越真实。这一点是一次次被真实用户教育出来的。
返回列表