大创管理系统毕设方案:三角色权限与全流程闭环落地拆解 简介这份资源是面向计算机专业毕业生的大创管理系统毕业论文文档基于Spring Boot与SSM框架开发适合正在准备毕业设计或课程设计的学生参考。论文完整覆盖从摘要、背景意义、需求分析、可行性分析到数据库设计、数据流图、详细设计、系统测试与总结的写作脉络并围绕学生、指导老师、院系管理员三类角色展开项目申报、中检、结项、评审等功能设计可帮助读者理清论文结构与技术实现思路。资源包共1个doc文件约2.57MB内容为可直接查阅的论文正文与目录。目前已有134人学习下载适合需要借鉴完整论文框架、功能模块划分与SSMMySQL技术描述写法的读者参考使用。1. 大创管理系统毕设方案从三角色权限到全流程闭环的落地拆解每年到了大创项目申报季院系负责这块工作的老师手里往往压着几十甚至上百份申报书中检、结项、评审的表格散落在不同文件夹里学生交一次材料要跑三趟办公室。这套基于 Spring Boot 的大创管理系统方案要解决的就是这个场景把项目申报、中检、结项、评审、专家分配串成一条线上流程让院系管理员、指导老师、学生三个角色各看各的界面、各走各的流程。它适合正在做毕设或课程设计、需要一套结构完整且能跑通的管理系统选题的同学也适合想参考一套成熟权限模型和审批流设计的从业者。下面按需求、设计、实现、避坑、验收的顺序拆开讲。2. 需求与角色建模三个角色、十一个功能模块怎么划2.1 从线下流程反推功能边界做管理系统最容易翻车的地方是一上来就画功能结构图结果画完发现角色之间的数据权限对不上。我一般的做法是先把线下流程走一遍学生提交申报书 → 指导老师初审 → 院系管理员分配专家 → 专家评审打分 → 中检材料提交 → 结项验收。这条链路里每个节点谁操作、谁可见、谁审批决定了功能模块的边界。从项目正文给出的角色功能清单看学生端有优秀项目、项目信息、评审方案、大创资讯、项目申报管理、项目中检管理、项目结项管理、项目评审管理、专家评审管理指导老师和院系管理员的功能高度重合都包含个人中心、优秀项目管理、项目类型管理、项目信息管理、项目申报管理、项目中检管理、项目结项管理、项目评审管理、专家评审管理、评审方案管理。这里有个设计上的关键判断指导老师和管理员功能列表几乎一样但数据范围必须不同——指导老师只能看到自己名下学生的项目管理员看全院的。这个差异不在功能菜单上体现而在数据查询的过滤条件里体现这是后面实现章节要重点处理的地方。学生端多出来的「大创资讯」是内容展示模块管理员和老师端没有说明资讯的发布权限归管理员学生只读。这个不对称在权限表设计时要单独标注否则容易做成学生也能发资讯的漏洞。2.2 角色权限矩阵与菜单可见性把功能清单落成权限矩阵是需求阶段最值得花时间的一张表。下面这张表按「角色 × 模块 × 操作」三个维度展开操作列只列关键动作实际开发时再细化到增删改查。模块学生指导老师院系管理员大创资讯查看查看增删改查项目类型查看查看增删改查项目信息查看查看本人名下增删改查全院项目申报提交/修改/撤回审核本人名下审核/退回全院项目中检提交材料审核审核/催办项目结项提交材料审核审核/归档项目评审查看结果发起评审分配专家/查看全部专家评审无打分分配/汇总评审方案查看增删改查增删改查优秀项目查看推荐认定/发布这张表的价值在于它直接对应后面拦截器里的权限判断逻辑。比如「项目信息」这一行学生是查看、老师是查看本人名下、管理员是全院增删改查三种数据范围对应三种 SQL 过滤条件写代码时照着表来就不会漏。提示权限矩阵一定要在写代码前定稿中途改角色权限是最容易引发返工的操作尤其是数据范围这类隐性权限改一处要动好几个 Mapper。2.3 技术选型为什么是 Spring Boot SSM MySQL项目正文里技术栈写的是 SSM 框架加 MySQL摘要里又强调 Spring Boot 作为核心框架。这两者不矛盾SSM 是 Spring SpringMVC MyBatis 的组合Spring Boot 是在这个组合外面包了一层自动配置和起步依赖把 XML 配置量压下去。对于毕设这种周期紧、要快速出可运行系统的场景Spring Boot 的价值很实在——不用手写一堆applicationContext.xml数据源、事务、MVC 映射都能通过注解和application.yml搞定。MySQL 选型没什么争议开源、资料多、和 MyBatis 配合成熟学生机器上装一个 5.7 或 8.0 都能跑。B/S 结构则是这类管理系统的基础设定浏览器访问、服务端集中部署学生和老师不用装客户端这也是正文里反复强调「界面清晰、操作简单」的技术前提。需要提醒的是正文里提到 JSP 技术而 Spring Boot 对 JSP 的支持并不算友好官方更推荐 Thymeleaf。如果照着老教程用 JSP打包成可执行 jar 后页面可能 404这是选型阶段就要想清楚的点。我的建议是如果指导老师没有硬性要求 JSP直接用 Thymeleaf模板放在templates目录下和 Spring Boot 的默认约定一致省掉一堆视图解析器配置的麻烦。3. 总体架构与数据库设计分层结构、核心表与状态流转3.1 三层架构与包结构划分系统按经典的 Controller-Service-Mapper 三层划分包结构建议这样组织com.dachuang ├── controller // 接收请求参数校验返回视图或 JSON ├── service // 业务逻辑事务边界 │ └── impl ├── mapper // MyBatis 接口 ├── entity // 数据库实体 ├── config // 拦截器、跨域、MyBatis 配置 └── util // 通用工具如分页、文件上传Controller 层只做参数接收和结果封装不写业务判断Service 层承担状态流转和权限校验Mapper 层对应 XML 或注解 SQL。这个划分看起来是教科书套路但实际项目里最常见的翻车就是业务逻辑漏到 Controller 里导致同一个校验在两个接口里写了两遍改一处忘一处。把「项目状态能不能从申报改成中检」这类判断统一收在 Service 里后面加流程节点时只改一个地方。3.2 核心数据表设计正文给出了大创资讯表和评审方案表的部分字段这里按项目全流程补全几张关键表的设计。字段类型沿用 MySQL 常用类型主键统一用bigint自增。项目信息表是整条流程的主表状态字段是核心CREATE TABLE project_info ( id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 主键, project_name VARCHAR(200) NOT NULL COMMENT 项目名称, project_type BIGINT(20) NOT NULL COMMENT 项目类型ID, student_id BIGINT(20) NOT NULL COMMENT 申报学生ID, teacher_id BIGINT(20) DEFAULT NULL COMMENT 指导老师ID, status TINYINT(2) NOT NULL DEFAULT 0 COMMENT 0待审核 1已立项 2中检中 3已结项 4已退回, apply_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 申报时间, PRIMARY KEY (id), KEY idx_student (student_id), KEY idx_teacher (teacher_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT项目信息表;状态字段status用数字编码而不是字符串好处是查询快、索引小坏处是可读性差所以注释必须写清楚每个值的含义。student_id和teacher_id都建了索引因为列表页几乎每次查询都要按这两个字段过滤不建索引在数据量上来后翻页会明显变慢。评审记录表用来存专家打分一个项目可以有多条评审记录CREATE TABLE review_record ( id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 主键, project_id BIGINT(20) NOT NULL COMMENT 项目ID, expert_id BIGINT(20) NOT NULL COMMENT 专家ID, score DECIMAL(5,2) DEFAULT NULL COMMENT 评分, comment TEXT DEFAULT NULL COMMENT 评审意见, review_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 评审时间, PRIMARY KEY (id), UNIQUE KEY uk_project_expert (project_id, expert_id), KEY idx_project (project_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT评审记录表;这里有个设计细节值得说(project_id, expert_id)建了唯一索引防止同一个专家对同一个项目重复打分。这个约束放在数据库层比放在代码层可靠代码里判断「是否已评审」总有并发漏判的可能唯一索引是最后一道防线。3.3 项目状态流转设计状态流转是这类审批系统的骨架。把status的合法迁移路径画清楚Service 层的校验逻辑就有依据当前状态允许操作目标状态操作角色0 待审核审核通过1 已立项指导老师/管理员0 待审核退回4 已退回指导老师/管理员1 已立项提交中检2 中检中学生2 中检中中检通过1 已立项指导老师/管理员1 已立项提交结项3 已结项学生4 已退回重新提交0 待审核学生这张表直接对应 Service 里的一个checkTransition(currentStatus, action)方法任何状态变更前先过这个方法不合法就抛业务异常。很多毕设系统状态字段随便改前端传什么就存什么答辩时老师一问「已结项的项目还能不能改状态」就答不上来问题就出在缺了这层校验。4. 关键模块实现登录鉴权、申报审核与评审分配4.1 登录拦截与角色鉴权登录流程正文里给了流程图校验用户名密码非空、校验账号密码正确、登录成功。落到代码上核心是一个登录接口加一个拦截器。登录接口校验通过后把用户信息写进 SessionPostMapping(/login) public String login(String username, String password, HttpSession session, Model model) { // 参数非空校验对应流程图里的两个判断分支 if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { model.addAttribute(msg, 用户名和密码不能为空); return login; } User user userService.login(username, password); if (user null) { model.addAttribute(msg, 用户名或密码错误); return login; } // 登录成功用户信息入 Session后续拦截器据此判断 session.setAttribute(loginUser, user); return redirect:/index; }密码校验这里有个血泪经验数据库里存的密码必须加密不能明文。毕设阶段很多人图省事直接存明文答辩时被问到安全性就尴尬。用 Spring 自带的BCryptPasswordEncoder一行代码就能搞定登录时用matches比对成本极低。拦截器负责拦住未登录访问和越权访问public class AuthInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session request.getSession(); User user (User) session.getAttribute(loginUser); if (user null) { // 未登录重定向到登录页 response.sendRedirect(/login); return false; } // 角色校验从请求路径前缀判断所需角色与用户角色比对 String uri request.getRequestURI(); if (uri.startsWith(/admin/) user.getRole() ! 1) { response.sendRedirect(/403); return false; } return true; } }拦截器里按 URL 前缀做角色判断前提是 Controller 的路径规划要统一管理员接口统一挂/admin/老师接口挂/teacher/学生接口挂/student/。路径规划乱了拦截器就写不干净。这个约定在项目初期就要定下来后面加接口照着挂比事后补权限省事得多。4.2 项目申报与审核的数据范围控制前面权限矩阵里提到指导老师只能看本人名下的项目管理员看全院。这个差异落在 MyBatis 的查询条件里最直接的做法是在 Service 层根据当前登录角色拼装查询参数public PageInfoProjectInfo listProjects(ProjectQuery query, User currentUser) { // 按角色收窄数据范围老师只看自己名下学生只看自己申报的 if (currentUser.getRole() 2) { query.setTeacherId(currentUser.getId()); } else if (currentUser.getRole() 3) { query.setStudentId(currentUser.getId()); } // 管理员 role1 不加额外条件查全院 PageHelper.startPage(query.getPageNum(), query.getPageSize()); return new PageInfo(projectMapper.selectByQuery(query)); }这段代码的关键在ProjectQuery这个查询对象它把teacherId、studentId、status、projectType等条件都收进去Mapper 的 XML 里用if动态拼 SQL。这样一套查询逻辑同时服务三个角色不用为每个角色写一个接口。PageHelper 负责分页startPage必须紧挨着查询语句中间不能插别的数据库操作否则分页参数会被错误消费这是用 PageHelper 最常见的坑。审核动作本身不复杂难的是状态校验和操作留痕。审核通过时更新status同时往操作日志表插一条记录记录谁在什么时间把哪个项目从什么状态改成了什么状态。日志表在毕设里经常被忽略但答辩时老师很爱问「操作能不能追溯」有这张表就能答。4.3 专家评审分配与评分汇总评审模块的流程是管理员或老师为项目分配专家 → 专家登录后看到待评审列表 → 打分并填写意见 → 系统汇总平均分。分配环节要注意两点一是同一项目不能重复分配同一专家靠前面设计的唯一索引兜底二是分配后专家端要能查到查询条件按expert_id过滤。评分汇总用一条聚合 SQL 就能完成SELECT project_id, COUNT(*) AS expert_count, AVG(score) AS avg_score, MIN(score) AS min_score, MAX(score) AS max_score FROM review_record WHERE project_id #{projectId} GROUP BY project_id;汇总结果用于优秀项目认定平均分排名靠前且专家数达到阈值的项目进入优秀项目候选列表。这个阈值建议做成可配置项放在评审方案表里不同批次的大创项目评审标准可能不同写死在代码里后面改起来要重新打包。注意评分字段用DECIMAL(5,2)而不是FLOAT浮点数在求和求平均时会出现精度误差比如 85.6 存进去变成 85.59999展示时四舍五入看着没问题但排名比较时可能出错。5. 避坑与常见问题排查五个最容易翻车的点5.1 中文乱码从数据库到页面的全链路排查现象学生提交的项目名称在列表页显示成问号或乱码。原因乱码可能出现在三个环节——数据库字符集、JDBC 连接串、页面编码。任何一环不是 UTF-8中文就会在传递过程中损坏。解决数据库建库时指定DEFAULT CHARSETutf8mb4JDBC 连接串加useUnicodetruecharacterEncodingutf8Thymeleaf 模板头部声明meta charsetUTF-8。三处都对齐后乱码基本绝迹。排查时从数据库直接SELECT看数据本身是否正常能快速定位是哪一环出的问题。5.2 文件上传失败路径与大小限制现象学生上传申报书附件页面报错或文件存到了意想不到的位置。原因Spring Boot 默认上传大小限制是 1MB申报书 PDF 很容易超另外上传路径如果用相对路径部署方式一变比如打成 jar 运行文件就找不到了。解决在application.yml里调大限制spring: servlet: multipart: max-file-size: 20MB max-request-size: 20MB上传目录用配置项指定绝对路径不要用System.getProperty(user.dir)拼相对路径。文件存磁盘、路径存数据库这是标准做法别把文件二进制直接塞进数据库字段查询和备份都会很难受。5.3 分页参数失效PageHelper 的调用顺序现象列表页永远显示第一页数据或者每页条数不对。原因PageHelper 的startPage是通过 ThreadLocal 传递分页参数的它只对紧接着的第一条 MyBatis 查询生效。如果中间插了一次 count 查询或其他数据库操作分页参数就被消耗掉了。解决确保PageHelper.startPage(...)和真正的列表查询之间没有其他 Mapper 调用。如果确实需要先查总数再查列表把startPage放在列表查询前一行。这个坑很隐蔽因为代码不报错只是结果不对排查时容易怀疑到 SQL 上。5.4 越权访问只藏菜单不拦接口现象学生账号通过直接输入管理员接口地址能访问到管理功能。原因前端菜单按角色隐藏了但后端接口没有做角色校验属于典型的「前端权限不是权限」。解决所有涉及角色差异的接口在拦截器或 Controller 入口做角色判断不能只依赖前端隐藏。测试时用学生账号登录后手动拼管理员 URL 访问一遍能访问到就是漏洞。这个检查在答辩演示前一定要做被老师当场试出来很被动。5.5 状态并发修改两个人同时审核现象同一个项目被两个管理员几乎同时点审核日志里出现两条状态变更记录最终状态不确定。原因审核逻辑是「先查状态、再判断、再更新」查和更新之间没有锁两个请求都读到旧状态都判断为可审核都执行了更新。解决更新语句带上状态条件用影响行数判断是否成功UPDATE project_info SET status #{newStatus} WHERE id #{id} AND status #{expectedStatus};如果返回影响行数为 0说明状态已被别人改过提示用户刷新重试。这是乐观锁的简化版比加悲观锁轻量对毕设场景足够用。6. 验收与答辩怎么证明这套系统真的跑通了验收这件事我一般分三步走功能走查、边界测试、演示脚本。功能走查按角色来学生账号完整走一遍申报 → 中检 → 结项老师账号走一遍审核 → 评审分配管理员账号走一遍类型维护 → 资讯发布 → 优秀项目认定。每一步记录实际结果和预期结果形成一张验收表答辩时这张表比口头说「功能都实现了」有说服力得多。边界测试重点打几个容易出问题的地方空表单提交、超长文本、重复提交、越权访问、状态非法跳转。比如已结项的项目再点「提交中检」系统应该给出明确提示而不是静默失败或报 500。这类测试用例提前准备好答辩现场演示时挑两三个跑给老师看比讲十句「系统很稳定」管用。演示脚本要控制在五到八分钟顺序建议是登录页展示三种角色入口 → 学生提交一个申报 → 切老师账号审核通过 → 切管理员分配专家 → 专家打分 → 回到列表看状态变化和评分汇总。这条链路把系统最核心的价值串起来了老师看完就知道你做了什么。演示前把数据库重置到干净状态准备两三条测试数据别用真实姓名用「测试学生一」这类占位数据。答辩时被问技术细节高频问题集中在权限怎么做的、状态流转怎么保证合法、密码怎么存的、分页怎么实现的。这几个问题前面章节都有对应答案提前把关键代码位置记熟被问到能直接翻到那一行比背概念强。从那以后我每次带人做这类管理系统都强制先定权限矩阵和状态流转表再动手写代码返工率能降一大半。希望这套拆解能帮到你照着结构走毕设这关不难过。本文还有配套的精品资源点击获取