简介:本资源是一份面向企业信息化建设人员、软件需求分析师及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_schedule | customer_id,creator_id,assignee_id | 日日程按天展示,周日程按周一至周日分块,月日程按日历格展示(3.3.1.1 基本事件流) |
| 邮件系统 | email,email_account,email_folder | sender_id,receiver_id,related_customer_id | 收件箱/发件箱/废件箱三态分离,支持导出Excel、打印(5.2.13–5.2.17) |
| 审批管理 | approval_application,approval_record | applicant_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列表 */ List<ScheduleDto> render(List<Schedule> schedules, Map<String, Object> context); } // 日视图渲染器实现 @Component public class DailyScheduleRenderer implements ScheduleRenderer { @Override public List<ScheduleDto> render(List<Schedule> schedules, Map<String, 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?date=2024-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 条件。
// 错误示范(只校角色) List<Customer> customers = customerMapper.selectAll(); // 全查! // 正确示范(加机构过滤) Long currentOrgId = getCurrentUserOrgId(); // 从SecurityContext或ThreadLocal获取 List<Customer> customers = customerMapper.selectByOrgId(currentOrgId);血泪经验:我在某校毕设答辩现场,看到同学演示“销售主管查看客户”,老师当场问:“如果你们公司有北京、上海、广州三个销售部,上海主管能看广州客户吗?”同学愣住。后来他加了
org_id过滤,当场通过。
4.2 现象:日程安排里“关联客户”下拉框为空,或显示了其他部门的客户
原因:文档2.2.3节要求“能做成下来列表的选项一定做成下拉列表”,但前端请求客户列表时,没传org_id参数,后端也未做机构过滤,导致查出全库客户。更糟的是,有些同学用SELECT * FROM customer塞进下拉框,客户一多直接卡死。
解决:下拉框数据接口必须带分页和机构过滤,且前端禁用v-model双向绑定大数据量列表,改用远程搜索(Remote Search)。
// Vue组件中 <el-select v-model="form.customerId" filterable remote :remote-method="loadCustomers" :loading="customerLoading" > <el-option v-for="item in customerOptions" :key="item.id" :label="item.name" :value="item.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-if="status !== '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_time):
customer客户表
| 字段名 | 类型 | 说明 | 文档依据 |
|---|---|---|---|
id | BIGINT PK | 主键 | — |
name | VARCHAR(100) | 客户名称 | 3.3.1.1 “关联客户” |
mobile | VARCHAR(20) | 手机号 | 5.2.16 短信管理 |
org_id | BIGINT | 所属机构ID(外键) | 1.2.3 用户组织结构 |
owner_id | BIGINT | 当前负责人ID(销售员ID) | 3.1 总体功能需求 |
schedule日程表
| 字段名 | 类型 | 说明 | 文档依据 |
|---|---|---|---|
id | BIGINT PK | 主键 | — |
title | VARCHAR(200) | 主题 | 3.3.1.1 基本事件流 |
start_time | DATETIME | 启始时间 | 同上 |
content | TEXT | 内容 | 同上 |
customer_id | BIGINT | 关联客户ID | 同上 |
creator_id | BIGINT | 创建人ID | 同上 |
assignee_id | BIGINT | 指派人ID | CRM205 指派人员 |
schedule_type | VARCHAR(20) | 'DAILY','WEEKLY','MONTHLY','TASK' | 3.2 功能划分 |
email邮件表
| 字段名 | 类型 | 说明 | 文档依据 |
|---|---|---|---|
id | BIGINT PK | 主键 | — |
subject | VARCHAR(200) | 主题 | 5.2.12 写邮件 |
body | LONGTEXT | 邮件正文 | 同上 |
sender_id | BIGINT | 发件人ID | 5.2.13 收件箱 |
receiver_id | BIGINT | 收件人ID | 同上 |
folder_type | VARCHAR(20) | 'INBOX','SENT','TRASH' | 5.2.13–5.2.15 |
status | VARCHAR(20) | 'DRAFT','SENT','READ' | 5.2.16 查询邮件 |
related_customer_id | BIGINT | 关联客户ID | 5.2.12 写邮件 |
approval_application审批申请表
| 字段名 | 类型 | 说明 | 文档依据 |
|---|---|---|---|
id | BIGINT PK | 主键 | — |
title | VARCHAR(200) | 主题 | 3.3.1.4 基本事件流 |
content | TEXT | 申请内容 | 同上 |
applicant_id | BIGINT | 申请人ID | 同上 |
approver_id | BIGINT | 审批人ID | CRM114 我的审批 |
status | VARCHAR(20) | 'PENDING','APPROVED','REJECTED' | 3.3.1.4 后置条件 |
related_customer_id | BIGINT | 关联客户ID | 同上 |
关系说明:四张表通过
org_id,customer_id,user_id形成网状关联,但无循环依赖。customer是中心实体,schedule,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": "a@b.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_id) | 3.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,没一次被老师挑出逻辑漏洞。
希望帮到你。
本文还有配套的精品资源,点击获取