简介:面向企业信息化建设人员、产品经理与需求分析初学者,这份CRM客户关系管理需求分析设计文档围绕客户关系管理系统的立项与设计展开,可用于梳理销售自动化、客户信息整合、数据分析支持等业务场景,并为开发团队提供统一的需求基线。压缩包内共1个doc文件,约1.66MB,内容按引言、任务概述、功能需求、性能需求等章节组织,包含用例描述、数据概念结构图与ER图、系统业务流程图等设计材料。已有189人学习下载,适合作为CRM项目需求调研、方案撰写与功能拆分时的参考样本。文档对用户组织结构、运行环境、条件与限制及术语定义也有交代,读者可据此快速理解从业务目标到功能落地的分析路径,并借鉴其章节框架与建模表达方式。
1. 一份 60 页的文档,就是整套 CRM 的说明书
接手一个只留下文档的项目,比接手一堆烂代码更难受。上个月我手上就多了这么一份资源:一份 60 页的 crm客户关系管理需求分析设计文档,版本 1.0,密级标着“限制”,历史记录里孤零零一行制定记录。没有源码、没有建库脚本、没有原型文件,只有目录、用例描述、实体关系图、25 条界面清单。这类东西在客户关系管理项目里太常见了——交付时留下的需求基线,后来成了二次开发唯一的依据。它适合两类人:要照着文档补出一套可运行 CRM 的后端,和接手存量系统、得先搞清角色与数据范围的维护者。下面按我拆它的顺序讲:先看骨架,再抠权限,然后把用例落到表结构,最后说几个当年就能躲开的坑。
2. 文档骨架拆解:六章目录对应哪六种读法
拿到一份几十页的 Word,最忌讳从第一页顺着读。需求文档的价值密度是极不均匀的,引言和参考资料基本是走流程,真正的信息集中在功能划分表、用例描述和界面清单三块。我的习惯是先翻目录,把章节按“决策信息 / 实现信息 / 验收信息”三类打个标,再决定读哪几段。
这套文档的六章结构是相当标准的模板:引言、任务概述、功能需求、性能需求、运行需求、参考资料。模板本身没什么可讲的,可讲的是每一章里真正能拿来干活的东西藏在哪。
2.1 六个章节的实际信息密度
第 1 章引言里,1.1 编写目的和 1.3 术语定义是给评审看的,但 1.2 项目背景这四小节值得逐字读:用户基本情况、开发目标、用户组织结构、用户相关业务。尤其是“用户组织结构”和“用户相关业务”,它们直接决定了后面权限模型长什么样。这套文档里,组织结构写的是销售部门、就业部门、系统维护部门三块,业务范围列了统一消息管理、工作日志安排、客户分组、客户信息管理、统一邮件平台——这五项基本就是全部功能模块的源头。
第 2 章任务概述是技术选型和约束的集中地。2.1 目标里有一句关键的话:这套系统“为客户关系管理系统的基础模块,提供完善的用户管理和授权管理”,并且“通过标准的 WebService 为其他软件系统提供统一的权限管理服务”。这句话的份量比它看起来重得多——它意味着这不是一个孤立的 CRM,而是整个平台的身份底座,后面所有业务系统都要来调它的鉴权接口。2.2 运行环境给的是当年的服务器配置清单,2.3 条件与限制则写了三条硬约束:机构管理员只能在自己机构下建用户;需要单点登录但不使用任何目录服务;“能做成下拉列表的选项一定做成下拉列表”。
第 3 章是主体,占了全文一多半。3.1 总体功能需求用一张角色协作图讲清三类角色的分工,3.2 功能划分用表格把二十多个用例编号和优先级列全,3.3 功能描述再逐个展开成用例、实体关系图、业务流程图。第 4 章性能需求只有三小节,数据精确度、时间特性、适应性,写得比较薄。第 5 章运行需求里最有价值的是 5.2 那一长串界面清单,从添加发送短信一直排到客户信息管理。第 6 章参考资料,跳过。
2.2 功能编号体系:从 CRM1.01 到 CRM305 的编码规则
3.2 那张功能划分表是我最先抄进笔记的东西。编号看着乱,其实规则很清晰:第一位数字代表模块大类,1 是业务协作类,2 是主管专属动作,3 是系统管理;后面的两位是序号。优先级一列 5 最高,标 5 的基本都是核心链路。
| 编号 | 用例名称 | 优先级 | 归属模块 | 备注 |
|---|---|---|---|---|
| CRM1.01 | 日程安排 | 5 | 日程 | 日/周/月三层视图 |
| CRM1.02 | 日常事务 | — | 日程 | 增删改查 |
| CRM1.05 | 写邮件 | 5 | 邮件 | 销售与主管共用 |
| CRM1.06 | 收件箱 | 5 | 邮件 | 查看/回复/删除/导出/打印 |
| CRM1.07 | 废件箱 | 5 | 邮件 | 恢复/永久删除/清空 |
| CRM1.14 | 我的审批 | — | 审批 | 仅主管 |
| CRM1.15 | 我的申请 | — | 审批 | 仅业务员 |
| CRM2.05 | 指派员工 | — | 主管动作 | 主管才能指派 |
| CRM3.01 | 客户分类管理 | 4 | 系统管理 | 分类树节点增删改 |
| CRM3.02 | 数据库操作 | 5 | 系统管理 | 备份与还原 |
| CRM3.03 | 设置用户权限 | — | 系统管理 | 管理员专属 |
这张表的用法不是拿来当目录,而是当工作量估算和迭代切分的依据。优先级 5 的用例构成最小可用闭环:能登录、能管客户、能发邮件、能看日程、能备份。二次开发时我一般先按这张表把接口清单拉出来,一个用例至少对应一组 CRUD 接口,标 5 的先做。
注意:编号里有个小坑,3.2 表格写的是 CRM114、CRM115 这种连写形式,而 3.3 用例正文里写的是 CRM1.03、CRM1.04,两种写法指的是同一批用例。做需求追溯矩阵的时候要统一成一种,不然对不上号。
2.3 非功能需求:2009 年的硬件清单今天还能用吗
2.2.1 网络及硬件环境那段写得很实在:2U 机架式服务器、双路四核 2.66GHz 处理器、2GB 内存、RAID 卡、独立光纤盘柜、SAN 交换机、万转 300GB 硬盘、冗余电源。放在当年这是一套正经的中小企业配置,放到今天,一台 4 核 8G 的云主机加一块 SSD 就能把同样的原型跑起来,数据库和应用的分离部署甚至可以直接合成单机。
真正有价值的是 2.2.2 支持软件环境:操作系统是那个年代的桌面版 Windows,数据库是 2000 年前后那一代商业关系库,编译环境 JDK 1.5,应用服务器是商用 J2EE 容器 6.1 版。这一套组合决定了代码风格——没有注解驱动的框架,没有 Spring Boot,事务靠容器管理,接口对外暴露走 SOAP 而不是 REST。二次开发如果直接照着这个栈重建,会很痛苦;稳妥的做法是保留业务语义、换掉技术载体,JDK 升到 17、容器换成内嵌 Tomcat、数据库迁到 MySQL 8 或 PostgreSQL 14,把 SOAP 接口包一层 REST 门面。
第 4 章性能需求的三小节里,“数据精确度”和“时间特性”写得比较笼统,没有给出具体的响应时间指标和并发量。这是这份文档的短板,也意味着二次开发时必须自己补一份非功能基线,否则压测阶段没有验收依据,容易变成玄学调优。
3. 角色与权限模型:谁能看谁的客户,得在文档阶段就定死
CRM 类系统翻车,八成不是功能没做出来,而是数据看串了。业务员看见同事的客户,机构管理员改到别的机构的人,主管审批列表里冒出不属于自己部门的申请——这些问题的根都不在代码,在需求阶段权限边界没写清。这份文档在这一点上做得比多数同类文档好,因为它把权限拆成了“功能权限”和“数据范围”两层。
3.1 组织—岗位—用户三层结构,与两种管理员的分界线
1.3 的术语表先把概念钉住了:用户是销售人员或就业部门人员,管理员是负责系统管理的人员,组织机构是对外机构,岗位在系统里表示为工作组。这四个词构成了权限模型的骨架:机构下面挂部门,部门下面挂岗位,岗位上面挂人。
系统管理员和机构管理员的差别,文档里有一句原文写得很明确:系统管理员可以在任何机构下创建用户,机构管理员只能在自己机构下新建用户。这句话只写了“新建”,没写查询、修改、删除、禁用。这就是典型的文档模糊地带——实现的时候如果只按“新建”做限制,接口一旦被构造请求打,机构管理员照样能改别人机构的数据。
我的处理办法是在设计阶段补一张权限矩阵,把每种角色的每个动作都列成格子,空格一律填“否”,而不是默认放行:
-- 权限矩阵落库:主体 + 资源 + 动作 + 数据范围 CREATE TABLE sys_privilege ( id BIGINT PRIMARY KEY, role_code VARCHAR(32) NOT NULL, -- SALES / SUPERVISOR / ORG_ADMIN / SYS_ADMIN resource VARCHAR(64) NOT NULL, -- crm_customer / crm_mail / sys_user action VARCHAR(16) NOT NULL, -- read / create / update / delete scope_type TINYINT NOT NULL, -- 1 本人 2 本部门 3 本机构及以下 4 全部 UNIQUE KEY uk_role_res_act (role_code, resource, action) );这段 DDL 的关键在scope_type这一列。功能权限(能不能点这个菜单)和数据范围(能看哪些行)如果只用一张角色表表达,后面必然要在业务代码里到处写 if-else。把范围抽成枚举,鉴权拦截器只认这四个值,代码会干净很多。UNIQUE KEY是为了防止同一角色同一资源同一动作被重复授权,这个坑我在别的项目里踩过——授权表有重复行,鉴权时按第一条匹配,结果和预期完全相反。
3.2 数据范围三档:机构、部门、本人,SQL 层怎么落
文档里散落的业务规则其实已经把范围说清楚了。日程安排那条写的是“销售人员只能对自己的日程安排信息进行查询、添加、修改、删除”;我的审批那条写的是“销售主管只能对自己审批的内容进行审批”;申请那条写的是“销售人员的申请只能对销售主管进行申请”。三条规则分别对应本人、本人待办、上级审批三种范围。
落到实现上,最省事也最不容易出错的做法是在服务层统一拼条件,而不是让每个 DAO 自己写 where:
// 按登录人角色拼数据范围条件,alias 是主表别名 public String buildScopeClause(LoginUser user, String alias) { switch (user.getRoleCode()) { case "SALES": // 业务员:只看自己名下的数据 return alias + ".owner_id = ?"; case "SUPERVISOR": // 主管:看本部门,含自己名下 return alias + ".dept_id = ?"; case "ORG_ADMIN": // 机构管理员:看本机构及下级 return alias + ".org_id = ?"; case "SYS_ADMIN": return "1 = 1"; default: // 没有匹配到角色,一律拒绝,不给默认放行 return "1 = 0"; } }方法体内是拼接用的占位符,实际执行时按顺序绑定 userId、deptId、orgId 三个参数,不要用字符串拼接真实值。这里最容易翻车的是default分支——很多实现习惯写成放行,一旦角色编码改了名或者新加了角色忘了配,后果就是全量越权。宁可返回1 = 0让页面空着,也别让数据漏出去。
主管范围还有一层隐含逻辑:主管本身也是业务员,能看到自己的日程和本部门的日程,但修改只能改自己的。所以查询用范围条件,写操作用归属判断,两套判断不能混。文档在“我的审批”用例里写了后置条件“审批只能选择同意或不同意”,这其实也是在收窄主管的动作集合——主管对下属的数据是只读加审批,不是全权代管。
3.3 统一授权接口:不用目录服务时,单点登录怎么自建
2.3 条件与限制里有一句很硬的话:用户不需要且不要使用目录服务。2.2.3 又要求单点登录。这两条放在一起,等于把“接现成认证中心”这条路堵死了,必须自建票据体系面对接其他系统的鉴权。
当年这套接口是用 SOAP 暴露的,报文结构大致是这样一套语义:
{ "appId": "crm-portal", "ticket": "ST-9f2c1e7a4b8d", "action": "checkPermission", "payload": { "userId": 10231, "resource": "crm_customer", "operation": "read" }, "timestamp": 1712300400, "sign": "md5(appSecret+ticket+timestamp)" }字段含义得说清楚:appId标识调用方,不同接入系统分配不同密钥;ticket是登录后签发的一次性凭证,带过期时间;action区分是校验登录态还是校验具体权限;sign是防重放和防篡改的签名,服务端要用同一套规则重算一遍再比对。响应体只需要返回code、message和data.allowed三个关键字段。
这套设计的要点在于:票据由主系统签发,业务系统不存用户表,只认票据。好处是用户管理只有一份,坏处是主系统一旦挂了全部系统跟着登录不了。所以我一般会加两级兜底——票据本地缓存一份带有效期的登录态,主系统不可达时降级为只校验本地缓存;同时给票据接口单独做限流,避免某个接入系统异常刷爆鉴权服务。文档里 5.4 故障处理及恢复要求那节写得很简略,这几条属于必须自己补的。
4. 用例到表结构:日程、邮件、审批、短信怎么落库
3.3.2 里有一张实体—关系图,3.3.3 里是一批业务流程图和活动状态图。图在 Word 里是截图,看不清细节,但结合 3.3.1 的用例正文能把实体和字段反推出来。这一章我按四个业务对象讲落库思路,每个都给出可执行的建表语句和几个容易想当然的地方。
4.1 客户主数据:所有业务对象都靠 customer_id 挂上来
文档 5.2.25 单独列了“客户信息管理”这个界面,1.2.4 又把客户分组列进了业务范围,说明客户是这套系统的主数据。日程的新增弹窗里有关联客户字段,日常事务里也有关联客户,邮件虽然没有明写,但销售给客户发邮件必然要能挂上客户。
-- 客户主数据:数据范围判断的三个字段都在这里 CREATE TABLE crm_customer ( id BIGINT PRIMARY KEY, cust_name VARCHAR(100) NOT NULL COMMENT '客户名称', cust_level TINYINT NOT NULL COMMENT '分类节点,对应 CRM3.01 分类树', org_id BIGINT NOT NULL COMMENT '归属机构', dept_id BIGINT NOT NULL COMMENT '归属部门', owner_id BIGINT NOT NULL COMMENT '归属业务员,范围判断主字段', phone VARCHAR(32), create_time DATETIME NOT NULL, del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '0 正常 1 已删', KEY idx_owner (owner_id), KEY idx_dept (dept_id) );三个归属字段org_id、dept_id、owner_id是刻意冗余的。理论上通过owner_id关联用户表就能推出部门和机构,但每次列表查询都多一次 join,数据量上来以后性能会很难看。冗余的代价是用户调岗时要同步刷客户表——这个动作必须做成一个明确的功能点,而不是靠定时任务悄悄跑。我在另一个项目里就吃过这个亏:人员调整后客户归属没刷,主管的部门视图直接空了一半,排查了半天才发现是冗余字段没跟着走。
del_flag用逻辑删除而不是物理删除,是因为客户下面挂着日程、邮件、审批一堆关联数据,物理删除会留一堆孤儿记录。文档 3.2 功能划分里虽然没写客户删除,但 5.2.25 客户信息管理界面通常包含这个动作,做的时候按逻辑删除处理。
4.2 日程的日、周、月三级视图:一张表还是三张表
3.3.1.1 日程安排那条用例写得很细:点“日程安排”,页面菜单里有日常事务、日日程、周日程、月日程四项;日日程点进去新增,弹窗里填主题、起始时间、内容、关联客户;周日程是点周日期块;月日程点月日期块。三种视图的操作流程几乎一模一样,区别只在时间粒度和展示方式。
见过不少实现会老老实实建三张表:日日程表、周日程表、月日程表。这样做的后果是查询“这个客户相关的所有日程”要 union 三次,改字段要改三处。正确的做法是一张表加类型字段:
-- 日程与日常事务共用一张表,靠 schedule_type 区分 CREATE TABLE crm_schedule ( id BIGINT PRIMARY KEY, schedule_type TINYINT NOT NULL COMMENT '2 日日程 3 周日程 4 月日程 9 日常事务', subject VARCHAR(200) NOT NULL COMMENT '主题,必填', start_time DATETIME NOT NULL COMMENT '起始时间,周/月视图按周月区间切', content TEXT COMMENT '内容', customer_id BIGINT COMMENT '关联客户,可为空', owner_id BIGINT NOT NULL, status TINYINT NOT NULL DEFAULT 0 COMMENT '0 未完成 1 已完成', create_time DATETIME NOT NULL, KEY idx_owner_time (owner_id, start_time) );idx_owner_time这个联合索引是给月视图准备的:查某人某月的日程,条件是owner_id = ? AND start_time BETWEEN ? AND ?,走这个索引能直接命中区间。周视图和月视图本质上是同一个查询换一个时间区间,不需要额外的表或字段。
值得注意的是日常事务的处理。文档把日常事务作为日程安排菜单下的第一项,但它的语义其实是待办清单,和日历上的日/周/月是两种东西。我倾向于共用一张表加类型区分,因为两者的字段几乎完全一致,分开建表只会增加维护成本。如果后面要加优先级、提醒、重复规则这些待办特有的属性,再加字段也不迟。
“关联客户”这个字段要允许为空。用例里写的是“关联客户是指日程计划中所涉及的客户信息”,但业务员临时记个事不一定挂客户,强制必填会让用户绕过系统去用记事本。
4.3 审批与邮件:状态机定死,前端才敢放开按钮
审批这块的规则密度是全文档最高的。3.3.1.3 我的审批:主管能看到审批列表,选中看详情,只能选“同意”或“不同意”。3.3.1.4 我的申请:业务员添加申请时主题和内容不能为空、必须选一个审批人;未通过或未审核的申请可以修改;审批通过后不能删除和修改,只能查看。这几条合起来就是一个三态机。
-- 申请单:状态只有 0 待审 / 1 通过 / 2 驳回 CREATE TABLE crm_apply ( id BIGINT PRIMARY KEY, subject VARCHAR(200) NOT NULL COMMENT '主题,非空校验在服务层做', content TEXT NOT NULL COMMENT '内容,非空校验在服务层做', applicant_id BIGINT NOT NULL COMMENT '申请人', approver_id BIGINT NOT NULL COMMENT '审批人,提交时必选', status TINYINT NOT NULL DEFAULT 0 COMMENT '0 待审 1 通过 2 驳回', audit_time DATETIME COMMENT '审批时间', audit_opinion VARCHAR(500) COMMENT '审批意见', create_time DATETIME NOT NULL, KEY idx_approver_status (approver_id, status) );状态机的校验必须放在服务层,不能只靠前端把按钮置灰。可编辑的条件是status IN (0, 2),可删除的条件是status IN (0, 2),审批动作要求status = 0且当前登录人是approver_id。三个条件任一不满足就抛业务异常。这套判断写在前端只是体验优化,写在服务层才是规则本身。
邮件是另一个容易想简单的地方。文档的用例写得很细:收件箱能查看、回复、删除、导出 Excel、打印;发件箱能再次发送;废件箱能恢复、永久删除、清空;查询邮件单独一个用例;还有邮件帐号配置;业务规则里反复强调“不同身份登陆看到的邮件不同”。
关键就在这句业务规则上。如果把邮件做成一张表,靠一个 folder 字段标识在收件箱还是发件箱,那么“删除”这个动作就会出问题:发件人删掉了已发邮件,收件人那边应该还能看到;收件人永久删除,也不该影响发件人。所以要做到文档要求的恢复、永久删除、清空,必须是邮件实体和用户视图分离:
-- 邮件实体:一份内容只存一份 CREATE TABLE crm_mail ( id BIGINT PRIMARY KEY, mail_from VARCHAR(100) NOT NULL, mail_to VARCHAR(500) NOT NULL COMMENT '多个收件人逗号分隔', subject VARCHAR(200), body TEXT, send_time DATETIME, attach_url VARCHAR(500) ); -- 用户视图:每个用户对每封邮件各有一条状态 CREATE TABLE crm_mail_user ( id BIGINT PRIMARY KEY, mail_id BIGINT NOT NULL, user_id BIGINT NOT NULL, folder TINYINT NOT NULL COMMENT '1 收件箱 2 发件箱 3 废件箱', read_flag TINYINT NOT NULL DEFAULT 0, UNIQUE KEY uk_mail_user (mail_id, user_id), KEY idx_user_folder (user_id, folder) );分开之后,收件人点删除只是把自己那条记录的folder改成 3,恢复改回 1,永久删除删掉这一行;发件箱那边完全不受影响。群发邮件也只存一份实体,收件人各生成一条视图记录。查询邮件的用例按 subject、发件人、时间区间过滤,直接查crm_mail_user关联crm_mail即可。
至于“邮件帐号配置”,文档把每个用户的收发件服务器、端口、密码都作为配置项,这意味着邮件走的是外部邮件服务器而不是系统内部消息。这一块建议把密码加密存储,并且在界面上做连接测试按钮,否则用户配错了只能靠一个个发信去试。
5. 避坑与排查:需求阶段就能埋下的五个雷
文档是死的,实现是活的。下面五条是我按这套文档做原型时真实遇到过或者提前拦住的问题,每条按现象、原因、解决写,能省掉不少来回。
5.1 权限与数据范围类:越权往往发生在“没想到”的地方
坑一:业务员登录后看到了同事的日程和客户。
现象很直观:A 登录进去,列表里出现了 B 昨天加的日程,客户列表里也有 B 名下的客户。原因不是权限配错,而是列表查询只按名称模糊匹配,压根没加owner_id条件,接口参数里还保留了前端传过来的ownerId,改一下请求就能查别人。解决分两步:列表接口一律不接受前端传的归属人,从会话里取;拦截器统一注入范围条件,DAO 层封掉无条件的全表查询入口。
坑二:机构管理员能改别的机构的用户。
文档只写了“机构管理员可以在自己机构下新建用户”,没写改和删。开发按字面实现,新建时校验了orgId,修改接口直接按主键更新,越权的口子就开了。解决是在权限矩阵里把sys_user的create、read、update、delete四个动作全列一遍,ORG_ADMIN的scope_type统一填“本机构及以下”,修改时先查原记录的org_id再比对,比对不上直接拒绝。
5.2 数据与流程类:状态机和箱体分类最容易想当然
坑三:审批通过的申请还能被申请人改回去。
现象是主管批完了,隔天发现内容变了。原因通常是前端把编辑按钮置灰了,但接口没做状态校验,构造请求照样能改。2.3 里“审批通过后就不能对结果进行删除、修改”这句话是业务规则,不是交互建议。解决办法是在服务层的更新方法第一行就查状态,status = 1直接抛异常,同时把“待审和驳回可编辑”写进接口文档,让前端有依据做按钮控制。
坑四:废件箱恢复后收件箱出现两封同样的邮件,永久删除还把对方发件箱里的记录一起删了。
这个前面讲过根因:邮件只有一张表、一个folder字段。多用户共用的数据,状态就必须按用户拆。解决是加crm_mail_user视图表,删除、恢复、清空全部只操作视图表,实体表只在所有视图都删除后才做物理清理。这个改动越早越好,等数据跑起来再拆表,迁移脚本会写到你怀疑人生。
坑五:文档里写了“能做成下拉列表一定做成下拉列表”,实现成了自由输入,脏数据一堆。
这条约束藏在 2.2.3 其它要求里,一句话带过,功能列表里完全没有体现,开发很容易漏。等到客户分类、部门、岗位、审批人这些字段全变成手输,同一个部门出现五六种写法,统计就没法做了。解决办法是把所有枚举型字段抽成字典表,前端统一用下拉组件,服务端做字典值校验,非法值直接拒绝入库。这是典型的“文档里一句话,实现里半个月”的需求。
坑六:单点登录不用目录服务,结果票据过期后用户被踢回登录页。
这是 3.3 那套自建票据体系的常见问题。票据有效期设得太短,用户写一封长邮件就掉线;设得太长又担心安全。我的做法是双票据:短票据走接口鉴权,有效期几分钟;长票据存在 Cookie 里,用来静默续期,只在登录和续期时使用。同时给鉴权接口加本地缓存,主系统短时不可用时降级放行已登录用户,避免整个平台跟着一起挂。
6. 二次开发:把需求文档变成能跑的原型,我的四步走法
这套文档最实际的用法,是当作一个技术选型已经过时、业务语义却相当完整的重建蓝图。我的顺序是固定的:先做身份和数据范围,再做客户主数据,然后按优先级 5 的用例补功能,最后补非功能。前三步的顺序不能换,因为范围条件贯穿所有业务表,客户 ID 贯穿所有业务对象,先把地基铺错,后面每加一个模块都要返工。
第一步,用 1.3 的术语表和 3.1 的角色图建四张表:机构、部门、用户、岗位,再把 3.3 的角色编码写进权限矩阵。验证方法是手工构造三种角色的账号,用同一个列表接口分别请求,比对返回条数。第二步,落crm_customer,把owner_id、dept_id、org_id三个冗余字段填上,跑一遍“业务员只看自己”的用例。第三步,按 CRM1.01 日程、CRM1.05 写邮件、CRM1.14 审批的顺序做,每个用例做完先自测状态机分支,别等功能全做完再测。
技术栈上我一般这么替换:JDK 升到 17,容器换成内嵌 Tomcat,数据库迁到 MySQL 8 或 PostgreSQL 14,对外接口用 REST 包一层,内部保留一份 SOAP 门面兼容老调用方。原来那份 2U 双路服务器的硬件清单可以整体丢掉,4 核 8G 单机足够跑通全部用例。
| 改造项 | 文档原方案 | 建议方案 | 验收方式 |
|---|---|---|---|
| 运行环境 | 双路四核 + 2G 内存 + 光纤盘柜 | 4 核 8G 云主机 + SSD | 压测 100 并发登录不超时 |
| 编译环境 | JDK 1.5 | JDK 17 | 全量编译零警告 |
| 数据库 | 2000 年代商业关系库 | MySQL 8 / PostgreSQL 14 | 迁移脚本可重复执行 |
| 授权接口 | SOAP WebService | REST + 保留 SOAP 门面 | 两个入口返回结果一致 |
| 认证方式 | 自建票据,不用目录服务 | 短票据 + 长票据续期 | 票据过期后能静默续期 |
验证这一步我习惯写个脚本跑一遍关键路径,比点页面靠谱:
# 用三种角色分别请求客户列表,比对返回条数是否符合范围预期 for role in sales supervisor org_admin; do token=$(curl -s -X POST http://localhost:8080/api/login \ -d "account=${role}&password=test123" | jq -r '.data.token') total=$(curl -s http://localhost:8080/api/customer/list \ -H "Authorization: Bearer ${token}" | jq '.data.total') echo "${role} 可见客户数: ${total}" done脚本里jq -r '.data.token'取的是统一响应体的 token 字段,total是分页返回的总条数。预期结果是 sales 的数最小、supervisor 等于本部门、org_admin 最大。三个数字一旦出现相等,基本可以断定范围条件没生效。
从那以后我每次接这类只有文档没有代码的资源,都强制先跑一遍这个三角色比对,再动手写业务。文档可以写得漂亮,权限不会自己长对。希望帮到你。
本文还有配套的精品资源,点击获取