资讯详情

CRM需求分析文档实战指南:角色权限、业务域划分与学生项目落地要点

📅 2026/10/27 3:10:08 | 华诺云谱 👁 阅读
CRM需求分析文档实战指南:角色权限、业务域划分与学生项目落地要点
简介本资源是一份面向企业信息化建设人员、软件需求分析师及CRM系统开发者的专业级需求分析设计文档聚焦客户关系管理系统的功能定义与架构规划解决销售流程自动化、客户数据整合与业务流程优化等核心问题。文档内容完整覆盖引言、任务概述、功能需求、用例描述、数据流图、实体关系图及界面原型设计特别包含用户组织结构映射、业务对象术语定义、软硬件运行环境要求及实施约束条件等实战细节具备直接指导系统开发落地的工程价值。资源为单文件Word文档.doc共1个文件大小1.66MB格式规范、排版清晰便于阅读与二次编辑。目前已有188人学习下载适合中高级IT从业者开展需求调研、撰写同类文档或作为高校信管/软件工程课程的案例参考。1. 这份 CRM 需求分析文档不是模板套用的“纸面功夫”而是能直接撑起毕设答辩、课设交付甚至小型企业落地的骨架你手头这份《CRM客户关系管理需求分析设计文档》表面看是2009年某高校实训班NT10班产出的旧版材料但它的价值恰恰藏在“过时”的细节里——它没用云原生、微服务、低代码这些热词包装却老老实实写清了谁在用、用在哪、怎么分权、数据怎么流、界面怎么交互、连下拉框该不该做都标了注释。这种“笨功夫”正是学生做毕设最缺的“真实感”不是从网上抄个UML图就交差而是真有人站在销售主管、就业专员、系统管理员三个角色背后一笔一划画出审批流、日程树、邮件收发闭环。它适合三类人一是正在赶毕设 deadline 的同学需要一份结构完整、逻辑自洽、能过导师初审的“需求基线”二是做课设小组长的同学要带着组员分工——客户模块谁做、审批流谁调、邮件配置谁测三是刚入行的初级实施顾问想看看一个真实哪怕轻量CRM系统需求文档到底该落到什么颗粒度。别被“SQL Server 2000”“WebSphere 6.1”吓退这些是时代烙印而它里面关于角色权限隔离、客户-日程-邮件三者关联、审批状态机流转的设计逻辑今天写 Spring Boot Vue 的项目照样得照着这个思路搭。2. 总体架构设计三层结构与四个核心业务域的职责划分这份需求文档虽未明说架构但从功能模块、运行环境、接口要求中可反向推演出清晰的分层逻辑。它不是单体大泥球也不是盲目上微服务而是典型的“表现层–业务逻辑层–数据访问层”三层架构且每一层都服务于明确的业务域。我带过几个类似规模的校企合作项目发现学生最容易犯的错就是把所有功能堆在 Controller 里结果改个审批状态要动五六个文件。而这份文档用“角色功能数据流向”三重约束天然倒逼出合理的分层。2.1 系统角色与权限边界不是RBAC模型而是“机构树岗位操作粒度”三维控制文档反复强调“销售部门只能对自己管理范围内的系统进行管理”“系统管理员可在任何机构下创建用户机构管理员只能在自己机构下新建用户”。这不是一句空话它定义了一套比标准 RBAC 更贴近业务的权限模型机构树Organization Tree以“万策对外机构”为根向下分销售部、就业部、系统维护部每个部门可再设子部门如销售部→华东区→上海组。这棵树不是静态组织图而是权限作用域的容器。岗位Position文档中称“工作组”实际是角色实例化。例如“销售主管”不是全局角色而是“销售部→华东区”下的一个具体岗位其审批权限仅限本机构内业务员提交的申请。操作粒度Operation Granularity权限控制到按钮级。比如“删除已发短信”5.2.5和“删除我的申请”5.2.10是两个独立权限点不能因为有“删除”权限就默认拥有全部删除能力。提示实现时千万别用PreAuthorize(hasRole(SALES_MANAGER))这种粗粒度注解。我一般会建一张role_org_permission表字段包括role_id,org_id,permission_code,permission_desc。当用户点击“删除我的申请”时后端先查当前用户所属机构ID再查该机构下该角色是否拥有PERM_DELETE_MY_APPLICATION权限。这样华东区主管删不了华北区的申请逻辑清清楚楚。2.2 四大核心业务域客户、日程、邮件、审批彼此耦合但边界清晰文档将功能划为四大块3.2节每一块都承担明确的业务语义且相互之间通过“关联客户”建立弱耦合业务域核心实体关键关联点典型业务规则客户信息管理customer,customer_group所有日程、邮件、审批记录均含customer_id外键销售人员只能查看/编辑自己名下客户3.3.1.1 备选流日程安排daily_task,weekly_plan,monthly_schedulecustomer_id,creator_id,assignee_id日日程按天展示周日程按周一至周日分块月日程按日历格展示3.3.1.1 基本事件流邮件系统email,email_account,email_foldersender_id,receiver_id,related_customer_id收件箱/发件箱/废件箱三态分离支持导出Excel、打印5.2.13–5.2.17审批管理approval_application,approval_recordapplicant_id,approver_id,related_customer_id,status审批状态仅允许“同意/不同意”通过后不可修改3.3.1.4 后置条件这种划分避免了“大客户表”陷阱——即把所有字段塞进一张customer表。我见过太多毕设项目客户表里硬塞了“最后联系时间”“下次跟进日期”“审批状态”结果日程改了时间客户表也要同步更新事务一多就出错。而这份文档的思路是日程归日程管客户归客户管两者靠外键关联查的时候 JOIN改的时候各负其责。2.3 数据流向与关键接口WebService 是灵魂不是摆设文档2.1节明确“通过标准的 WebService 为其它软件系统提供统一的权限管理服务”。这意味着它不是一个孤岛系统而是未来可能被 HR 系统、合同管理系统调用的权限中心。其核心 WebService 接口应包含getUserPermissions(userId: String, orgId: String): PermissionList返回某用户在某机构下的所有可执行操作码如[CRM_VIEW_CUSTOMER, CRM_EDIT_TASK]validateApproval(approvalId: String, action: String): Boolean校验审批动作合法性如“同意”操作是否由指定 approver 发起syncCustomerData(customerDto: CustomerDto): Result供外部系统推送客户变更需鉴权幂等处理注意文档2.2.3节强调“不要使用AD或LDAP”所以权限数据必须全量存在本库。我一般会在数据库加一张ws_api_log表记录每次 WebService 调用的request_id,api_name,caller_ip,status_code,response_time方便后期排查跨系统问题。毕设答辩时老师问“怎么保证接口安全”你拿出这张表的设计比背OAuth2.0原理更有说服力。3. 功能模块实现从用例到代码的关键落点与配置示例文档3.3.1节的用例描述CRM101–CRM305是全文最扎实的部分。它没写“系统应具备高可用性”而是写“点击‘日日程’进入界面弹出窗口填主题、启始时间、内容、关联客户”。这种颗粒度正是你写代码时最需要的输入。下面我以“日程安排”和“邮件帐号配置”两个高频模块为例给出可直接复用的实现要点。3.1 日程安排模块四类日程的共性抽象与差异化渲染文档将日程拆为日常事务、日日程、周日程、月日程CRM101–CRM104表面看是四个功能实则共享同一套底层模型。我建议用“策略模式模板方法”实现避免重复造轮子// 统一日程实体简化版 public class Schedule { private Long id; private String title; // 主题 private LocalDateTime startTime; // 启始时间精确到分钟 private String content; // 内容 private Long customerId; // 关联客户ID private Long creatorId; // 创建人 private String scheduleType; // DAILY, WEEKLY, MONTHLY, TASK // getter/setter... } // 日程渲染策略接口 public interface ScheduleRenderer { /** * 渲染日程列表前端所需JSON结构 * param schedules 日程列表 * param context 渲染上下文如日视图的date周视图的weekStart * return 渲染后的DTO列表 */ ListScheduleDto render(ListSchedule schedules, MapString, Object context); } // 日视图渲染器实现 Component public class DailyScheduleRenderer implements ScheduleRenderer { Override public ListScheduleDto render(ListSchedule schedules, MapString, Object context) { LocalDate targetDate (LocalDate) context.get(date); return schedules.stream() .filter(s - DateUtils.isSameDay(s.getStartTime(), targetDate)) .map(this::toDto) .collect(Collectors.toList()); } private ScheduleDto toDto(Schedule s) { ScheduleDto dto new ScheduleDto(); dto.setId(s.getId()); dto.setTitle(s.getTitle()); dto.setStartTime(s.getStartTime().toLocalTime()); // 日视图只显示时间 dto.setContent(s.getContent()); dto.setCustomerId(s.getCustomerId()); return dto; } }设计说明scheduleType字段是关键。它让同一张schedule表支撑四种日程避免建daily_schedule,weekly_schedule等四张表。查询时DAO 层根据scheduleType和上下文参数如date,weekStart,month动态拼接 WHERE 条件。前端调用/api/schedules/daily?date2024-06-15时后端注入context.put(date, LocalDate.parse(2024-06-15))交由DailyScheduleRenderer处理。这样新增“季度日程”只需加一个QuarterlyScheduleRenderer不动核心逻辑。3.2 邮件帐号配置模块安全存储密码与SMTP动态适配文档5.2.17节要求“邮件帐号配置”但没提密码怎么存。这是学生项目最常翻车的点——把邮箱密码明文存数据库。文档2.2.2节写的是“Windows XP SP2 SQL Server 2000”当时可能真这么干但现在必须加密。我推荐 AES-128-CBC 加密密钥由 Spring Bootapplication.yml中的mail.encryption.key配置并强制要求 SMTP 配置项必须校验连通性# application.yml 片段 mail: encryption: key: 32-byte-aes-key-must-be-exactly # 32字节Base64密钥 smtp: host: smtp.exmail.qq.com port: 465 username: ${MAIL_USERNAME} password: ${MAIL_PASSWORD} # 环境变量注入非明文// 邮件账号实体密码字段加密存储 Entity Table(name email_account) public class EmailAccount { Id private Long id; private String username; // 明文用于显示 Column(name encrypted_password) private String encryptedPassword; // AES加密后Base64字符串 private String smtpHost; private Integer smtpPort; private Boolean useSsl; // true for port 465, false for 587 // 密码解密方法仅在发信时调用 public String decryptPassword() { return AesUtil.decrypt(encryptedPassword, getEncryptionKey()); } private String getEncryptionKey() { return environment.getProperty(mail.encryption.key); } } // SMTP连通性测试服务 Service public class SmtpConnectivityService { public boolean testConnection(EmailAccount account) { try { Properties props new Properties(); props.put(mail.smtp.host, account.getSmtpHost()); props.put(mail.smtp.port, account.getSmtpPort().toString()); props.put(mail.smtp.auth, true); if (Boolean.TRUE.equals(account.getUseSsl())) { props.put(mail.smtp.ssl.enable, true); } else { props.put(mail.smtp.starttls.enable, true); } Session session Session.getInstance(props, new Authenticator() { Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( account.getUsername(), account.decryptPassword() // 此处解密 ); } }); Transport transport session.getTransport(smtp); transport.connect( account.getSmtpHost(), account.getSmtpPort(), account.getUsername(), account.decryptPassword() ); transport.close(); return true; } catch (Exception e) { log.error(SMTP connection test failed for account {}, account.getUsername(), e); return false; } } }参数说明useSsl字段至关重要。QQ邮箱企业版用 465 端口SSL网易邮箱用 587 端口STARTTLS如果前端配置页面不区分后端硬写props.put(mail.smtp.ssl.enable, true)就会导致网易邮箱连不上。所以EmailAccount表必须有use_ssl列前端配置页提供“SSL加密”和“TLS加密”两个单选按钮。毕设演示时当场测通 SMTP比讲一百遍“高内聚低耦合”都管用。4. 关键避坑指南学生项目最容易翻车的5个点及血泪解决方案这份需求文档写于2009年但里面埋的坑今天的学生一个都没躲开。我带过的毕设里80%的延期和答辩卡壳都源于这几个看似简单、实则致命的点。以下全是真实踩过的坑按“现象→原因→解决”结构整理每一条都对应文档中的具体条款。4.1 现象登录后销售主管能看到所有部门的客户而非仅本机构原因权限校验只做了角色判断如isSalesManager()没校验org_id。文档1.2.3节明确“用户组织结构”和2.2.3节“销售部门只能对自己管理范围内的系统进行管理”但代码里漏了机构过滤。解决在所有客户查询接口如GET /api/customers的 Service 层强制注入当前用户所属机构ID并作为 WHERE 条件。// 错误示范只校角色 ListCustomer customers customerMapper.selectAll(); // 全查 // 正确示范加机构过滤 Long currentOrgId getCurrentUserOrgId(); // 从SecurityContext或ThreadLocal获取 ListCustomer customers customerMapper.selectByOrgId(currentOrgId);血泪经验我在某校毕设答辩现场看到同学演示“销售主管查看客户”老师当场问“如果你们公司有北京、上海、广州三个销售部上海主管能看广州客户吗”同学愣住。后来他加了org_id过滤当场通过。4.2 现象日程安排里“关联客户”下拉框为空或显示了其他部门的客户原因文档2.2.3节要求“能做成下来列表的选项一定做成下拉列表”但前端请求客户列表时没传org_id参数后端也未做机构过滤导致查出全库客户。更糟的是有些同学用SELECT * FROM customer塞进下拉框客户一多直接卡死。解决下拉框数据接口必须带分页和机构过滤且前端禁用v-model双向绑定大数据量列表改用远程搜索Remote Search。// Vue组件中 el-select v-modelform.customerId filterable remote :remote-methodloadCustomers :loadingcustomerLoading el-option v-foritem in customerOptions :keyitem.id :labelitem.name :valueitem.id / /el-select // loadCustomers 方法 loadCustomers(query) { if (query.length 2) return; // 至少输2个字才查 this.customerLoading true; api.getCustomers({ orgId: this.currentUser.orgId, // 必传机构ID keyword: query, page: 1, size: 20 }).then(res { this.customerOptions res.data; }).finally(() this.customerLoading false); }4.3 现象审批通过后申请人还能修改/删除申请记录原因文档3.3.1.4节后置条件写得清清楚楚“审批通过后就不能对结果进行删除修改。只能有查看的功能”但代码里只做了前端按钮隐藏v-ifstatus ! APPROVED后端接口完全没校验抓个包就能绕过。解决后端接口必须做状态守门State Guard。在updateApplication()和deleteApplication()方法开头强制校验public void updateApplication(Long appId, ApplicationUpdateDto dto) { Application app applicationMapper.selectById(appId); if (APPROVED.equals(app.getStatus()) || REJECTED.equals(app.getStatus())) { throw new BusinessException(已审批的申请不可修改); } // ...后续逻辑 }玄学提醒毕设答辩时老师最爱用 Postman 直接调后端接口测试。如果你只做前端限制老师一试就崩印象分直接归零。4.4 现象导出邮件Excel时中文乱码或日期格式错误原因文档5.2.16节要求“导出邮件”但用new HSSFWorkbook()POI 3.x处理 Excel不设置编码和单元格格式。更常见的是用SimpleDateFormat解析数据库里的datetime字段时区搞错。解决统一用 POI 5.x 的XSSFWorkbook.xlsx格式并显式设置字体和日期格式XSSFWorkbook workbook new XSSFWorkbook(); XSSFSheet sheet workbook.createSheet(邮件列表); XSSFFont font workbook.createFont(); font.setFontName(微软雅黑); font.setFontHeightInPoints((short) 10); XSSFCellStyle style workbook.createCellStyle(); style.setFont(font); style.setDataFormat(workbook.createDataFormat().getFormat(yyyy-mm-dd hh:mm:ss)); Row headerRow sheet.createRow(0); for (int i 0; i headers.length; i) { Cell cell headerRow.createCell(i); cell.setCellValue(headers[i]); cell.setCellStyle(style); } // ...填充数据行每行cell均 setCellStyle(style)4.5 现象短信发送失败日志里只有一句“发送异常”找不到具体错在哪原因文档5.2.16–5.2.18节涉及短信管理但没提日志规范。学生常写e.printStackTrace()或log.error(send sms error)出了问题两眼一抹黑。解决短信发送必须记录结构化日志包含关键上下文log.info(SMS_SEND_START | phone:{} | content:{} | templateCode:{} | userId:{}, phone, content, templateCode, userId); try { // 发送逻辑 log.info(SMS_SEND_SUCCESS | phone:{} | msgId:{} | userId:{}, phone, msgId, userId); } catch (Exception e) { log.error(SMS_SEND_FAILED | phone:{} | content:{} | userId:{} | errorMsg:{}, phone, content, userId, e.getMessage(), e); // 记录完整异常栈 }后悔药我带的一个小组上线前一周短信总失败就靠这条日志定位到是运营商模板审核未通过而不是代码问题。没有它至少多花三天。5. 数据模型与接口设计ER图落地、API契约与验收检查表文档3.3.2节提到“数据概念结构图实体—关系图”3.3.3节有“系统业务流程图”但原文未附图。作为一份能交付的方案我们必须补全这部分——不是画个漂亮UML充数而是给出可建表、可生成MyBatis XML、可被Postman调通的真实数据契约。5.1 核心实体ER关系聚焦客户、日程、邮件、审批四张主表基于文档功能描述提炼出四张核心表及其关键字段省略审计字段如create_time,update_timecustomer客户表字段名类型说明文档依据idBIGINT PK主键—nameVARCHAR(100)客户名称3.3.1.1 “关联客户”mobileVARCHAR(20)手机号5.2.16 短信管理org_idBIGINT所属机构ID外键1.2.3 用户组织结构owner_idBIGINT当前负责人ID销售员ID3.1 总体功能需求schedule日程表字段名类型说明文档依据idBIGINT PK主键—titleVARCHAR(200)主题3.3.1.1 基本事件流start_timeDATETIME启始时间同上contentTEXT内容同上customer_idBIGINT关联客户ID同上creator_idBIGINT创建人ID同上assignee_idBIGINT指派人IDCRM205 指派人员schedule_typeVARCHAR(20)DAILY,WEEKLY,MONTHLY,TASK3.2 功能划分email邮件表字段名类型说明文档依据idBIGINT PK主键—subjectVARCHAR(200)主题5.2.12 写邮件bodyLONGTEXT邮件正文同上sender_idBIGINT发件人ID5.2.13 收件箱receiver_idBIGINT收件人ID同上folder_typeVARCHAR(20)INBOX,SENT,TRASH5.2.13–5.2.15statusVARCHAR(20)DRAFT,SENT,READ5.2.16 查询邮件related_customer_idBIGINT关联客户ID5.2.12 写邮件approval_application审批申请表字段名类型说明文档依据idBIGINT PK主键—titleVARCHAR(200)主题3.3.1.4 基本事件流contentTEXT申请内容同上applicant_idBIGINT申请人ID同上approver_idBIGINT审批人IDCRM114 我的审批statusVARCHAR(20)PENDING,APPROVED,REJECTED3.3.1.4 后置条件related_customer_idBIGINT关联客户ID同上关系说明四张表通过org_id,customer_id,user_id形成网状关联但无循环依赖。customer是中心实体schedule,email,approval_application均以customer_id为外键体现“客户为中心”的CRM本质。建表时所有外键必须加索引如idx_customer_org否则关联查询极慢。5.2 RESTful API契约按文档用例编号定义可测试端点文档3.2节列出了用例编号CRM101–CRM305我们将其映射为标准REST API确保每个用例都有对应端点且命名符合文档描述用例编号用例名称HTTP方法URL路径请求体示例文档依据CRM101日常事务GET/api/schedules/tasks—3.3.1.2 基本事件流CRM102日日程GET/api/schedules/daily{ date: 2024-06-15 }3.3.1.1 基本事件流CRM103周日程GET/api/schedules/weekly{ weekStart: 2024-06-10 }同上CRM104月日程GET/api/schedules/monthly{ year: 2024, month: 6 }同上CRM107发邮件POST/api/emails/send{ to: ab.com, subject: ..., body: ... }3.3.1.5 基本事件流CRM108收件箱GET/api/emails/folders/INBOX—3.3.1.6 基本事件流CRM109废件箱GET/api/emails/folders/TRASH—3.3.1.8 基本事件流CRM114我的审批GET/api/approvals/my—3.3.1.3 基本事件流CRM115我的申请GET/api/approvals/my-applications—3.3.1.4 基本事件流CRM205指派人员POST/api/schedules/assign{ scheduleId: 123, userId: 456 }CRM205 用例描述设计说明URL 路径严格遵循 REST 原则资源名词用复数schedules,emails,approvals动作用 HTTP 方法表达GET 查、POST 增、PUT 改、DELETE 删。/folders/INBOX这种路径比/inbox更易扩展未来加OUTBOX只需改枚举值。所有接口必须返回标准 JSON 结构{ code: 200, message: success, data: {...} }便于前端统一处理。5.3 验收检查表对照文档条款逐条验证答辩前必过清单毕设答辩不是考你背了多少理论而是看你有没有把文档里的白纸黑字变成可运行、可演示、可解释的系统。我给学生定的硬性验收标准就是拿着这份检查表一项项打钩序号验收项文档依据演示方式是否通过1登录后销售员只能看到自己名下客户owner_id current_user_id3.3.1.1 备选流登录销售员A查客户列表登录销售员B查客户列表确认数据隔离□2日日程界面选择日期后只显示该日的日程DATE(start_time) ?3.3.1.1 基本事件流在日视图选6月15日列表只显示6月15日的日程□3审批通过后申请人无法修改/删除该申请后端拦截3.3.1.4 后置条件用Postman调PUT /api/approvals/{id}传已审批状态返回400错误□4邮件帐号配置页输入SMTP信息后点击“测试连接”按钮弹出成功/失败提示5.2.17 邮件帐号配置填QQ邮箱配置点测试填错误密码点测试观察提示□5导出邮件Excel打开后中文不乱码日期格式为“yyyy-MM-dd HH:mm:ss”5.2.16 查询邮件点“导出Excel”用Excel打开检查编码和格式□6短信发送日志包含手机号、内容、错误信息如有5.2.16–5.2.18 短信管理查看logs/app.log搜索SMS_SEND_确认字段齐全□7系统管理员可创建任意机构用户机构管理员只能创建本机构用户2.2.3 其它要求管理员登录创建华北区用户华北区管理员登录尝试创建华东区用户应失败□提示答辩前夜我要求学生把这张表打印出来对着系统一项项操作录屏存档。老师问“怎么保证权限不越界”你直接打开录屏播放第1项和第7项的操作过程比讲十分钟RBAC模型都直观。从那以后我每次带毕设都强制走一遍这个 checklist没一次被老师挑出逻辑漏洞。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑