资讯详情

资讯详情

CRM需求文档深度解析:从J2EE老系统到现代重构的权限与流程设计

简介这是面向企业CRM系统建设与产品设计人员的需求分析设计文档围绕客户关系管理中的销售自动化、客户信息整合与数据分析支持等目标展开适合产品经理、需求分析师和开发团队参考。文档以1个doc文件呈现压缩包大小1.66MB内容涵盖项目背景、用户组织结构、业务流程、功能需求及性能指标并附有详尽的用例描述、概念结构图、业务流程图和界面原型预览便于从需求到设计一体化理解。全文约60页结构按引言、任务概述、功能需求、性能需求等模块划分既可帮助团队统一术语与需求口径也可作为后续系统设计与开发验收的基线。目前已有188人学习下载对正在规划或实施CRM项目的人员具有直接借鉴价值。1. 这份CRM客户关系管理需求文档值得每个ToB开发者读一遍刚接触CRM客户关系管理项目的开发者最容易把需求分析文档当成“一堆没用的流程描述”。直到我接手一个老系统的二次开发领导丢来一份六十页的需求规格说明书才意识到这些用例描述才是项目最值钱的部分——它定义了完整的三类角色、九大业务域、三十多个功能用例还有精确到按钮级的界面交互规则。这套客户关系管理系统文档解决的是典型的中小型企业客户管理问题销售部门管客户、就业部门盯合作企业、主管做审批、系统管理员控权限。适合正在做CRM相关项目、需要写需求文档、或者想看懂老项目设计逻辑的开发者和产品经理。2. 需求文档里的技术栈盘点J2EE SQL Server 2000时代的CRM该看什么2.1 从运行环境反推技术选型WebSphere、SQL Server与JDK 1.5的组合这份文档在任务概述部分给出了清晰的运行环境约束这些信息对于拆解老项目至关重要。数据库采用Microsoft SQL Server 2000应用服务器是IBM WebSphere Application Server 6.1编译程序是JDK 1.5操作系统是Windows XP SP2。这一套组合是2008年前后典型的J2EE企业级应用标准配置也决定了代码层面会遇到的两个关键约束。第一个约束是JDK 1.5时代的语法限制。那时候还没有Lambda表达式、Stream API和Optional写循环基本靠for和Iterator集合操作靠的是Collections工具类。这意味着如果你打算把这段历史资产翻新成Spring Boot项目几乎所有业务层的代码都要重写而不是简单调整依赖。第二个约束是WebSphere的部署特性。WebSphere 6.1对JSP编译、类加载顺序和数据源配置都有自己的一套玩法和今天嵌入式Tomcat的开发体验差别很大。文档里提到的“单点登录功能但不使用AD或其他LDAP系统”在当年的技术背景下一般会采用Session共享加自定义用户上下文的方式实现也就是登录成功后把用户信息塞进Session再通过Filter拦截请求做身份校验。# 典型的老J2EE部署环境 JDK 1.5 IBM WebSphere Application Server 6.1 Microsoft SQL Server 2000 (SP4) Windows Server 2003 / Windows XP SP2这套组合决定了两个事实第一系统内部大量使用JSP/Servlet/JavaBean的分层方式页面和业务逻辑耦合较重第二数据库访问走JDBC或早期ORM框架SQL语句直接写在Java代码里或配置文件里的情况很常见。2.2 系统目标与角色划分三类角色、三个业务域、一条审批链文档在功能需求开头明确说了系统由三类角色组成系统管理员、主管销售部门/就业部门、业务员销售部门/就业部门。这个三角色模型是理解整个CRM系统的钥匙。业务员负责记录客户信息、通过和客户交流记录客户表达的意愿和建议。主管通过业务员记录的客户信息和日程安排来把握客户的整体意向动态主管也可以直接和客户沟通还可以通过邮件系统进行双方交流。系统管理员负责客户分类、用户信息管理与数据安全。从功能划分来看系统包含九个模块日程安排日常事务、日日程、周日程、月日程、客户信息管理、指派员工与指派目标主管才能操作、邮件系统写邮件、收件箱、发件箱、废件箱、查询邮件、邮件帐号配置、删除邮件、群发邮件、审批管理我的审批、我的申请、短信管理发送短信、查询短信、删除短信、组织结构管理部门管理、员工管理、系统管理客户分类管理、数据库操作、设置用户权限、组织管理添加修改删除部门、添加修改删除人员。-- 角色权限的核心逻辑数据归属决定可见范围 -- 业务员只能操作自己的客户、日程和邮件 -- 主管可以查看下属业务员的数据并进行审批 SELECT u.user_id, u.user_name, r.role_name, d.dept_name FROM sys_user u JOIN sys_user_role ur ON u.user_id ur.user_id JOIN sys_role r ON ur.role_id r.role_id LEFT JOIN sys_dept d ON u.dept_id d.dept_id WHERE u.user_id ? -- 当前登录用户这段SQL是权限模型的核心思路用户、角色、部门三张表关联。业务层再根据角色类型做数据行级过滤。2.3 功能模块全景十二个用例模块的优先级与归属文档用表格列举了三十二个用例并且标注了优先级。这里有一个值得注意的细节用例编号并不是统一连贯的——客户信息管理是CRM201日程安排是CRM101邮件系统是CRM107审批管理是CRM114短信管理是CRM116组织结构是CRM119系统管理是CRM301。这说明文档在编写过程中经历了多次功能增补编号体系并不严格。优先级标注也很有意思。客户分类管理、数据库操作、设置用户权限的优先级都达到了四分以上客户管理五分、日程安排五分说明文档编制者认为客户和日程是最核心的业务。而邮件系统的用例分散在五到七的编号区间短信管理则相对边缘。从这些优先级数据中我一般会把模块划分为三个建设批次批次模块理由P0必须客户信息管理、日程安排客户管理是系统存在的根本日程是销售日常工作记录P1重要审批管理、邮件系统、用户权限审批支撑业务流转邮件是内外沟通管道权限是安全底线P2增强短信管理、组织管理、数据库操作短信是补充通知手段数据库备份还原属于运维功能这个划分方式可以直接用于排期和资源分配。如果你在设计自己的CRM系统也可以借鉴这种按优先级分层的方法把有限的开发资源先投入核心链路。3. 核心模块拆解日程安排、审批流与邮件管理的用例链路3.1 日程安排的用例转换从“点击新增”到数据库记录文档中CRM1.01“日程安排”用例是描述最详尽的一个包含了日日程、周日程、月日程三种粒度。基本事件流是用户点击日程安排页面看到四个菜单——日常事务、日日程、周日程、月日程然后分别进行新增、修改、删除、查看操作。把这段需求转成后端逻辑其实就是一张日程表加上增删改查接口。关键在于“新增日程”对话框中有一个“关联客户”字段这个字段把日程和客户信息绑定起来。// 日程表核心结构根据需求推演 CREATE TABLE crm_schedule ( schedule_id INT PRIMARY KEY IDENTITY(1,1), -- 日程ID schedule_type TINYINT NOT NULL, -- 1日 2周 3月 subject NVARCHAR(200) NOT NULL, -- 主题 start_time DATETIME NOT NULL, -- 启始时间 content NVARCHAR(2000), -- 内容 customer_id INT, -- 关联客户ID owner_id INT NOT NULL, -- 归属人业务员ID dept_id INT NOT NULL, -- 归属部门 create_time DATETIME DEFAULT GETDATE(), update_time DATETIME DEFAULT GETDATE(), deleted_flag TINYINT DEFAULT 0 );这张表的设计思路是schedule_type区分日程粒度customer_id建立与客户信息的关联owner_id和dept_id配合实现数据隔离。业务规则中明确规定“销售人员只能对自己的日程安排信息进行查询、添加、修改、删除”所以每次查询都要带上owner_id条件。// 查询日程列表的核心SQL按归属人过滤 SELECT schedule_id, schedule_type, subject, start_time, content, customer_id FROM crm_schedule WHERE owner_id ? AND deleted_flag 0 AND schedule_type ? -- 日/周/月 ORDER BY start_time DESC;参数说明第一个问号是当前登录用户的ID第二个问号是日程类型日、周、月。这看似简单的设计恰恰解决了销售管理中最常见的越权查看问题。3.2 审批流的状态机我的申请与我的审批CRM1.04“我的申请”和CRM1.03“我的审批”构成了一个完整的审批闭环。销售人员发起申请主管进行审批审批结果只有“同意”或“不同意”两种。文档中有一个特殊需求值得注意“审批通过后就不能对结果进行删除、修改只能有查看的功能”。这个需求说明审批流需要状态机。申请从创建到结束会经历待审核、已同意、已拒绝、已撤回几个状态。其中只有待审核状态的申请允许修改和删除已通过的申请锁定。// 申请状态枚举 public enum ApplyStatus { PENDING(0, 待审核), APPROVED(1, 已同意), REJECTED(2, 已拒绝), CANCELED(3, 已撤回); private final int code; private final String desc; ApplyStatus(int code, String desc) { this.code code; this.desc desc; } }审批流实现的关键在于销售人员添加申请时必须选择一个审批人文档明确要求申请内容里必须有主题和内容且两项不能为空。审批人在“我的审批”页面看到待审批列表点击后查看细节并提交审批意见。审批结束后系统根据审批结果更新申请状态同时可以触发后续动作比如通知申请者或者记录日志。// 审批处理的核心逻辑伪代码 public void approve(Long applyId, Long approverId, boolean approveResult) { // 1. 校验审批人身份 Apply apply applyMapper.selectById(applyId); if (!apply.getApproverId().equals(approverId)) { throw new BizException(只能审批指派给自己的申请); } // 2. 判断状态是否允许审批 if (apply.getStatus() ! ApplyStatus.PENDING.getCode()) { throw new BizException(该申请已处理不能重复审批); } // 3. 更新状态 apply.setStatus(approveResult ? ApplyStatus.APPROVED.getCode() : ApplyStatus.REJECTED.getCode()); apply.setApproveTime(new Date()); applyMapper.updateById(apply); }逻辑说明审批前必须校验身份和状态双条件这是防止越权审批和重复审批的基本保障。参数approveResult是布尔值true代表同意false代表不同意。3.3 邮件系统的四箱模型收件箱、发件箱、废件箱与查询邮件系统是这份文档里用例最多的模块覆盖了写邮件、收件箱、发件箱、废件箱、查询邮件、邮件帐号配置、删除邮件、群发邮件八个功能。核心玩法是四箱模型收件箱存客户来信发件箱存已发出的邮件废件箱放删除的邮件再加上一个查询功能做全局搜索。四箱模型在数据表设计上有一个经典做法不物理分区而是在邮件表上加状态字段。-- 邮件系统的表结构设计推演 CREATE TABLE crm_mail ( mail_id INT PRIMARY KEY IDENTITY(1,1), mail_to NVARCHAR(200) NOT NULL, -- 收件人地址 mail_from NVARCHAR(200) NOT NULL, -- 发件人地址 subject NVARCHAR(500), -- 主题 content NTEXT, -- 邮件正文 box_type TINYINT NOT NULL, -- 1收件箱 2发件箱 3废件箱 owner_id INT NOT NULL, -- 邮件归属人 send_time DATETIME, read_flag TINYINT DEFAULT 0, -- 是否已读 deleted_flag TINYINT DEFAULT 0, -- 是否逻辑删除 permanent_flag TINYINT DEFAULT 0 -- 是否永久删除 );参数说明box_type是核心字段决定了邮件显示在哪个箱体。收件箱和发件箱删除邮件时不会物理删行而是把box_type改成3移到废件箱废件箱清空时才是物理删除或标记permanent_flag。这个设计的好处是误删可恢复符合文档中“恢复邮件”“清空废件箱”的用例要求。另外发件箱支持“再次发送”收件箱支持“导出Excel”“打印”这些功能在实现时都很直接——导出用POI生成Excel打印用浏览器的window.print()。4. 从文档到落地权限边界、数据模型与接口要求4.1 权限设计系统管理员、主管、业务员的数据隔离方案文档反复强调三类角色的差异系统管理员负责客户分类、用户信息管理、数据安全主管能查看业务员记录的客户信息和日程安排能做审批能指派人员和目标业务员只能管理自己的数据和日程。这个权限模型要落地需要解决两个层面的问题。第一是功能权限什么人能进入什么菜单、点什么按钮。第二是数据权限业务员查客户列表时只能看到自己名下或自己部门范围内的客户。功能权限在J2EE时代常见做法是用Filter加上角色标识进行URL拦截。数据权限则在SQL层处理比如客户信息管理模块中“销售部门只能对自己管理范围内的系统进行管理”意味着客户表必须有归属人字段和归属部门字段。// 数据权限过滤的三种策略从简单到复杂 // 策略1仅限本人业务员 WHERE c.owner_id #{currentUserId} // 策略2本部门主管查看部门下属业务员 WHERE c.dept_id IN ( SELECT dept_id FROM sys_dept WHERE parent_id #{currentUserDeptId} OR dept_id #{currentUserDeptId} ) // 策略3全部数据系统管理员 -- 不加过滤条件我一般会在MyBatis的拦截器里根据当前用户角色动态拼接这些条件而不是在业务代码里分散判断。这样做的原因是权限规则集中管理后续调整管控级别只需要改拦截器逻辑。4.2 数据模型设计从ER图到业务表的推演文档中提到了“数据概念结构图实体—关系图”虽然正文没有给出具体图例但结合用例描述可以反推核心实体用户、角色、部门、客户、日程、邮件、申请审批、短信、客户分类。这些实体之间的关系可以这样理解一个部门有多个用户一个用户拥有多个客户一个客户有多个日程和邮件一个用户发起多个申请、审批多个申请。客户分类是树形结构系统管理员可以添加修改删除分类列表节点。-- 客户信息表核心业务表 CREATE TABLE crm_customer ( customer_id INT PRIMARY KEY IDENTITY(1,1), customer_name NVARCHAR(200) NOT NULL, -- 客户名称 customer_type TINYINT, -- 客户类型关联客户分类表 contact_name NVARCHAR(100), -- 联系人 contact_phone NVARCHAR(50), -- 联系电话 owner_id INT NOT NULL, -- 归属人业务员 dept_id INT NOT NULL, -- 归属部门 level TINYINT DEFAULT 1, -- 客户级别 source NVARCHAR(100), -- 客户来源 remark NVARCHAR(1000), -- 备注 create_time DATETIME DEFAULT GETDATE() );客户信息管理是文档强调的重点模块“贯穿于整个项目”所以这张表的设计直接决定了后续所有关联功能的数据基础。4.3 非功能性需求安全性、界面要求与故障处理文档的性能需求章节提到了数据精确度、时间特性、适应性运行需求部分涉及安全性、用户界面、接口要求、故障处理。这类非功能性需求虽然不如用例生动但在实施评审时是必选项。界面要求部分特别有意思文档列出了二十多个界面的操作细节比如“添加发送短信”“查看已接收短信列表”“删除已接收短信”“查看审批列表”“添加审批信息反馈”“查看我的申请列表”等等。界面层的需求文档通常包含按钮位置、表单字段、列表展示方式。安全性需求在文档中没有展开但结合“系统管理员对用户权限进行设置”这个用例可以推断系统需要支持用户密码管理、会话超时、操作日志记录。接口要求提到通过标准的WebService为其他软件系统提供统一的权限管理服务这意味着系统不是一个孤立应用而是未来CRM平台的一个基础服务。5. 避坑与排查老CRM需求文档落地时的5个经典翻车现场5.1 用例编号混乱导致需求追溯困难现象需求评审时开发按用例编号追踪功能发现CRM119是部门管理、CRM301是客户分类管理编号没有任何连续性而且客户信息管理同时出现CRM201和CRM1.01两种写法。原因文档在多次迭代中由不同人补充需求编号体系没有统一维护导致追踪矩阵失效。解决落地前先建立需求追踪矩阵RTM把所有用例重新编号与模块、页面、测试用例一一对应。不要沿用文档里的原始编号作为代码注释或接口命名依据。5.2 “能做成下拉列表的一定做成下拉列表”被过度解读现象文档里明确写着“能做成下来列表的选项一定做成下拉列表。方便用户”结果前端把所有文本框都改成了下拉框客户名称、邮件内容这种自由文本也被做成下拉框数据录入效率反而变低。原因需求描述过于口语化没有明确哪些字段适合下拉、哪些字段适合自由输入。解决整理一份枚举字段清单。客户分类、客户类型、日程类型、优先级、审批状态这些有限取值的字段做下拉客户名称、日程主题、邮件正文这种无限取值的字段保留文本输入。下拉框数据来源统一从数据字典表读取。5.3 数据权限只在页面隐藏没在接口层管控现象销售业务员通过修改URL参数访问到了其他业务员的客户详情页越权数据暴露。原因页面按钮根据角色做了显示隐藏但后端接口没有做数据行级过滤接口层是无条件信任前端传参的。解决在Service层增加数据权限校验查询客户详情时必须校验当前用户是否有权操作该客户。原则是前端控制可见性后端控制数据边界。5.4 邮件附件存储方式没提前规划现象邮件支持导出、打印、再次发送但文档没有提及附件处理上线后用户反馈发送含附件的邮件速度极慢服务器磁盘占用飙升。原因附件直接存在数据库表里大文件读写频繁导致性能瓶颈。解决附件走文件存储路径数据库只存文件路径等信息。经验教训是这类隐含需求最好在需求评审阶段主动追问。5.5 逻辑删除与物理删除混用导致数据混乱现象废件箱执行“清空”操作后部分邮件还能在收件箱里出现恢复功能时数据错乱。原因有的模块用deleted_flag做逻辑删除有的模块直接执行DELETE语句物理删除标准不统一。解决统一所有删除操作走逻辑删除永久删除只允许在废件箱阶段执行且需要二次确认。数据表增加deleted_flag和permanent_flag双字段代码层用枚举约束删除行为。6. 二次开发改造把2009年的需求文档翻译成现代技术栈如果你拿到的就是这份类似的需求文档要把它改造成可运行的现代系统我的建议是先别急着写代码按照下面三个步骤走。先把六十页文档重新拆成用户故事和验收标准。这个阶段的工作量大约占整个改造周期的百分之三十。把每个用例转换成“作为某角色我希望执行某操作以便达到某目标”然后给每个用户故事标注优先级和依赖关系。日程安排、审批流、邮件系统这几个用例必须保持原有业务语义因为销售流程一旦改得面目全非业务方是不会买账的。技术栈迁移方面我一般会把原有的J2EE结构翻译成Spring Boot加MyBatis Plus的经典组合。JDK 1.5的代码全部重写WebSphere的WebService接口改用RESTful方式暴露。数据库方面保留客户、日程、邮件、审批四张核心表的结构设计SQL Server 2000的语法需要转换到MySQL 8或PostgreSQL比如分页方式要改、NTEXT类型要换成TEXT或JSONB。邮件模块的改造值得单独讲一下。老系统的邮件收发是基于JavaMail直接对接邮件服务器的现在更推荐用Spring Boot的邮件自动配置配合OAuth2协议对接企业邮箱。文档中“废件箱可恢复”的需求建议用软删除加回收站机制实现不要物理删行。权限这块我的经验是直接换用Spring Security加Sa-Token这类成熟框架不建议自己写Filter拦截器。文档中“系统管理员可以在任何机构下创建用户机构管理员可以在自己机构下新建用户”这个需求翻译到现代框架里就是基于RBAC模型的用户和机构管理用数据权限注解加部门数据范围控制就能搞定。从那以后我每次拿到老旧的需求文档都会强制走一遍“拆用例、列名词、画边界、定状态”四个步骤再动手写代码这样既能保证需求不丢失又不会让老文档的过时设计拖累新技术方案。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →