☰
基于Spring Boot的大创管理系统:角色权限与状态流转设计
2026/11/2 14:16:45 网站建设 项目流程

简介:这份毕业论文文档面向计算机相关专业学生与毕业设计撰写者,围绕基于Spring Boot的大创管理系统展开完整论述,可用于选题参考、论文结构模仿与项目答辩准备。压缩包共1个文件,为doc格式的论文正文,整体约2.57MB,内容涵盖摘要与Abstract、研究背景、开发技术介绍、需求分析、可行性分析、功能分析、业务流程分析、数据库设计、数据流图、详细设计、系统截图、测试与总结等章节,并附致谢与参考文献。系统采用B/S模式,基于SSM框架与MySQL数据库开发,以Spring Boot为核心,划分学生、指导老师、院系管理员三类角色,覆盖项目申报、中检、结项、评审及评审方案管理等环节。已有134人学习,读者可从中获取完整的论文写作框架、功能模块划分思路与数据库设计方法,适合作为同类管理系统毕业设计的参考范本。

1. 从一份“项目申报表”说起:大创管理系统到底要解决什么

每年三四月,高校里最忙的往往不是上课,而是大创项目的申报窗口。学生填表、指导老师签字、院系汇总、专家评审、中期检查、结项答辩——一套流程走下来,纸质表格能堆满半张会议桌。我见过一个院系的做法:申报书用邮件收,中检报告用共享文档收,结项材料再换一个网盘,最后管理员对着三份不同格式的表格手工核对。出错是常态,漏审是玄学,想查一个项目的历史记录得翻遍聊天记录。这套基于 Spring Boot 的大创管理系统,要解决的就是把“申报—中检—结项—评审”这条链路收进一个 B/S 系统里,让三个角色各看各的、各管各的,数据只录一次。它适合正在做毕设或课程设计、需要一套完整业务闭环来撑起论文结构的人,也适合想参考一套真实管理流程落地的开发者。

2. 需求与角色拆解:三个角色、十一个功能模块怎么划

2.1 为什么是“学生—指导老师—院系管理员”三层角色

大创业务里最容易被做错的设计,是把权限做成“管理员能看所有、其他人只能看自己”。听起来合理,实际跑起来会翻车:指导老师需要看到自己名下所有项目的申报、中检、结项状态,还要能提交评审意见;院系管理员则要跨指导老师汇总,做项目类型维护和评审方案下发。所以角色划分不能只按“数据归属”,要按“业务动作”来切。

这套系统定了三个角色,职责边界很清楚:

角色核心动作数据范围
学生申报项目、提交中检/结项材料、查看评审结果与优秀项目本人项目及公开资讯
指导老师审核名下项目、管理项目类型与评审方案、录入专家评审本人指导的项目
院系管理员全量项目审批、类型维护、评审方案与专家评审管理全院系项目

学生端的功能清单是:优秀项目、项目信息、评审方案、大创资讯、项目申报管理、项目中检管理、项目结项管理、项目评审管理、专家评审管理。指导老师和院系管理员的功能高度重合,都包含个人中心、优秀项目管理、项目类型管理、项目信息管理、项目申报管理、项目中检管理、项目结项管理、项目评审管理、专家评审管理、评审方案管理。区别在于数据范围——指导老师看自己带的,管理员看全院的。

提示:毕设里最容易偷懒的地方是把指导老师和管理员做成同一套菜单、只改个角色字段。答辩时老师一问“这两个角色的操作差异在哪”就露馅了。正确做法是菜单可以复用,但查询条件里必须带teacher_id或dept_id的过滤,这是权限落到 SQL 层的体现。

2.2 业务主线的状态流转:一个项目从申报到结项要过几道关

大创项目的生命周期不是线性的“提交—通过”,而是带退回和重提的。梳理清楚状态机,后面所有模块的代码才有依据。我一般会把它画成四个阶段:

  1. 申报阶段:学生填写项目信息(名称、类型、成员、经费预算、预期成果),提交后状态为“待审核”;指导老师审核,通过则进入“已立项”,退回则回到“待修改”。
  2. 中检阶段:立项项目在中期提交进展报告,指导老师填写中检意见,管理员确认。状态在“中检待审—中检通过/中检退回”之间流转。
  3. 结项阶段:学生提交结项材料,指导老师初审,管理员终审,状态为“结项待审—结项通过/结项不通过”。
  4. 评审阶段:对结项通过的项目,管理员下发评审方案,组织专家评审,结果写入专家评审表,最终标记为“优秀项目”或普通结项。

这条主线决定了数据库里至少要有项目主表、申报记录、中检记录、结项记录、评审方案、专家评审六类核心数据。很多同学把中检和结项都塞进项目主表加几个状态字段,做到后面发现“退回意见”没地方存、多次中检没法留痕,只能推倒重来。血泪经验是:每个阶段一张独立表,主表只存当前状态和最新快照。

2.3 功能模块的边界:哪些该合并,哪些必须拆开

原文列出的功能项有十几个,直接一个功能一个 Controller 会写出大量重复代码。合理的合并策略是按“业务对象”聚合:

  • 项目域:项目信息、项目申报、项目中检、项目结项——共用项目主表和状态机,拆成四个 Controller 但共享 Service。
  • 评审域:评审方案、专家评审、项目评审——评审方案是模板,专家评审是打分记录,项目评审是汇总视图。
  • 基础域:项目类型、优秀项目、大创资讯——偏配置和内容展示,逻辑轻。
  • 个人中心:用户信息与密码修改,三个角色共用一套接口,靠角色字段区分。

这样拆的好处是 Service 层不会出现一个类两千行的情况,答辩讲架构时也能说清楚“高内聚”落在哪。下面这张模块职责表可以直接放进论文的概要设计章节:

模块主要类职责
项目申报ProjectApplyController / ProjectService申报提交、退回重提、列表查询
项目中检ProjectCheckController中检材料提交与审核
项目结项ProjectFinishController结项材料与终审
评审方案ReviewPlanController方案模板的增删改查与下发
专家评审ExpertReviewController专家打分录入与结果汇总
基础配置ProjectTypeController / NewsController类型维护、资讯发布

3. 技术选型与总体架构:B/S 三层结构怎么落到 Spring Boot 工程里

3.1 SSM 与 Spring Boot 的关系:别在论文里写混

原文摘要里同时出现了“SSM 框架”和“Spring Boot”,很多同学写论文时把这两个当成并列技术,答辩被追问就答不上来。准确的说法是:SSM 是 Spring + SpringMVC + MyBatis 的组合,Spring Boot 是在这个组合之上做自动配置和起步依赖的脚手架。也就是说,系统底层仍然是 SSM 的三层协作,Spring Boot 负责把 XML 配置干掉、把 Tomcat 内嵌进来。

落到工程结构上,典型的包划分是这样的:

com.dachuang ├── config # 拦截器、跨域、MyBatis 配置 ├── controller # 按业务域分包:project / review / base / user ├── service # 接口 + impl ├── mapper # MyBatis Mapper 接口 ├── entity # 与数据库表对应的实体 ├── dto # 前端传参与返回视图对象 └── common # 统一返回、异常、常量

这个结构不新鲜,但它是答辩时能讲清楚“分层”的最小骨架。Controller 只做参数校验和调用,Service 承载状态流转和事务,Mapper 只写 SQL。翻车点在于有人把业务判断写进 Controller,比如“如果状态是待审核才能提交中检”,结果中检和结项两个入口各写一遍,改需求时漏改一处就出 bug。

3.2 三层架构的职责划分与请求链路

B/S 模式下,一次“学生提交申报”的请求链路是:浏览器表单 → Controller 接收 DTO → Service 校验项目状态与必填项 → Mapper 插入申报记录并更新主表状态 → 返回统一 JSON。三层各管一段,任何一层都不越界。

用一段申报提交的 Service 代码说明状态校验该放哪:

@Service public class ProjectApplyServiceImpl implements ProjectApplyService { @Resource private ProjectMapper projectMapper; @Resource private ProjectApplyMapper applyMapper; @Override @Transactional(rollbackFor = Exception.class) public void submitApply(ProjectApplyDTO dto, Long studentId) { // 1. 查项目当前状态,只有“待修改”或首次申报才允许提交 Project project = projectMapper.selectById(dto.getProjectId()); if (project != null && !"待修改".equals(project.getStatus()) && !"未申报".equals(project.getStatus())) { throw new BizException("当前状态不允许提交申报"); } // 2. 必填项校验放在 Service,Controller 只做非空 if (StringUtils.isBlank(dto.getBudget()) || dto.getMembers() == null) { throw new BizException("经费预算与成员信息不能为空"); } // 3. 写申报记录(留痕),再更新主表状态 applyMapper.insert(buildApplyRecord(dto, studentId)); projectMapper.updateStatus(dto.getProjectId(), "待审核"); } }

这段代码有三个设计点值得在论文里点出来。第一,@Transactional保证“插记录 + 改状态”要么都成要么都不成,避免出现有申报记录但主表还是旧状态的脏数据。第二,状态判断用字符串常量而不是魔法值散落各处,后面改成枚举也方便。第三,退回重提走的是同一个接口,靠状态区分,不需要为“首次申报”和“重新提交”写两套逻辑。参数上studentId从登录会话取,绝不从前端传,这是防越权的基本操作。

3.3 数据库设计:从 E-R 到核心表字段

原文给出了管理员、评审方案、大创资讯三个实体的属性图,以及资讯表和评审方案表的字段。按业务主线补全,核心表至少包括:用户表、项目主表、项目申报表、项目中检表、项目结项表、评审方案表、专家评审表、项目类型表、大创资讯表。

以项目主表为例,字段设计要兼顾状态查询和列表展示:

CREATE TABLE project ( id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键', project_name VARCHAR(200) NOT NULL COMMENT '项目名称', type_id BIGINT(20) NOT NULL COMMENT '项目类型', student_id BIGINT(20) NOT NULL COMMENT '申报学生', teacher_id BIGINT(20) DEFAULT NULL COMMENT '指导老师', budget DECIMAL(10,2) DEFAULT NULL COMMENT '经费预算', members VARCHAR(500) DEFAULT NULL COMMENT '成员名单', status VARCHAR(20) NOT NULL DEFAULT '未申报' COMMENT '状态', addtime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_student (student_id), KEY idx_teacher (teacher_id), KEY idx_status (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目主表';

索引不是摆设。学生端列表按student_id查,老师端按teacher_id查,管理员按status筛待审项目,三个索引对应三条高频查询。评审方案表按原文给的字段保留标题、创新点、前期准备、实施方案、预期成果、经费预算、成员素质、图片、创建时间,这张表本质是“评审维度模板”,专家评审表再引用方案 ID 并逐项打分。这样设计的好处是换一套评审指标不用改代码,只改方案数据。

注意:MySQL 里status用 VARCHAR 存中文状态在毕设里很常见,但排序和统计会别扭。如果时间允许,建议存英文码值(如PENDING、PASSED),前端做映射,论文里也好写“状态机”。

4. 核心模块实现:申报、中检、结项与评审怎么串起来

4.1 项目申报与退回重提的实现要点

申报模块的难点不在新增,而在“退回后重提”和“指导老师分配”。学生首次提交时teacher_id可能为空,由管理员或学生选择指导老师后回填。退回时要把退回意见写进申报记录表,而不是覆盖原记录,这样学生能看到历次退回原因。

列表查询要按角色拼条件,我一般用一个查询 DTO 加动态 SQL:

<select id="selectProjectPage" resultType="ProjectVO"> SELECT p.*, t.type_name, u.real_name AS studentName FROM project p LEFT JOIN project_type t ON p.type_id = t.id LEFT JOIN sys_user u ON p.student_id = u.id <where> <if test="role == 'student'"> AND p.student_id = #{userId} </if> <if test="role == 'teacher'"> AND p.teacher_id = #{userId} </if> <if test="status != null and status != ''"> AND p.status = #{status} </if> <if test="keyword != null and keyword != ''"> AND p.project_name LIKE CONCAT('%', #{keyword}, '%') </if> </where> ORDER BY p.addtime DESC </select>

role和userId由后端从会话注入,前端只传status和keyword。这样即使有人改前端参数也越不了权。分页用 PageHelper 一行搞定,论文里可以写“物理分页,避免全量加载”。

4.2 中检与结项:同一套审核逻辑的复用

中检和结项的流程几乎一样:学生提交材料 → 指导老师审核 → 管理员终审。差别只在材料字段和状态码。与其写两套几乎相同的代码,不如抽一个AuditService,用bizType区分中检和结项:

public void audit(Long recordId, String bizType, String result, String opinion, Long auditorId) { // 根据业务类型路由到不同 Mapper,但审核动作一致 if ("CHECK".equals(bizType)) { checkMapper.updateAudit(recordId, result, opinion, auditorId); projectMapper.updateStatusByCheck(recordId, result); } else if ("FINISH".equals(bizType)) { finishMapper.updateAudit(recordId, result, opinion, auditorId); projectMapper.updateStatusByFinish(recordId, result); } }

复用带来的直接好处是审核意见、审核人、审核时间这三个字段的处理只写一遍。答辩时如果被问“中检和结项有什么区别”,回答“材料字段和状态码不同,审核动作抽象复用”,比背功能列表有说服力。参数result用“通过/退回”两个值,opinion必填当结果为退回时,这个校验放在 Service 入口。

4.3 评审方案与专家评审的关联设计

评审方案是管理员维护的“评分模板”,专家评审是具体项目按模板打分。两张表通过plan_id关联,专家评审表还要存project_id、expert_id、各项得分和总分。汇总时按项目分组求平均分,再和方案里的权重相乘得到最终评审结果。

这里有个容易忽略的点:专家评审录入后不应该允许随意修改,否则评审结果失去公信力。通常的做法是加一个“评审锁定”状态,管理员确认汇总后锁定,锁定后只能查看。这个细节写进论文的“系统安全性”小节,比空谈权限控制实在得多。

4.4 优秀项目与大创资讯:内容型模块的轻量实现

优秀项目本质是结项评审通过且评分达标的项目打标展示,不需要单独建业务表,在项目主表加is_excellent标记即可,列表查询时过滤。大创资讯按原文给的字段(标题、简介、图片、内容、创建时间)建表,后台增删改查,前台列表加详情。这两个模块代码量小,但论文里不能省——它们撑起了“信息发布”这条线,也让系统看起来完整。

5. 避坑与排查:这套系统最容易翻车的五个地方

5.1 状态字段满天飞,改一处漏三处

现象:申报、中检、结项各自维护一套状态字符串,学生端显示“待审核”,管理员端显示“待审”,统计时对不上。原因:没有统一的状态常量或枚举,各模块各写各的。解决:建一个ProjectStatus枚举或常量类,所有状态读写只引用常量;数据库里存码值,前端统一映射。改需求时只改一处。

5.2 越权访问:前端藏了菜单,接口还能直接调

现象:学生用浏览器直接请求管理员的项目列表接口,能拿到全院数据。原因:权限只做在菜单渲染层,Controller 没校验角色和数据范围。解决:登录后把角色和用户 ID 放会话,所有列表查询在 Service 层强制拼student_id/teacher_id条件;管理类接口加角色拦截器。这是答辩必问项,提前准备好说辞。

5.3 文件上传路径写死,换台机器就 404

现象:本地开发时图片能显示,部署到另一台机器或换目录后全部裂图。原因:上传路径写死成D:/upload/,数据库存的是绝对路径。解决:路径配置化(application.yml里配file.upload-path),数据库只存相对文件名,读取时拼配置前缀;静态资源映射用WebMvcConfigurer统一处理。

5.4 中检/结项重复提交,产生多条有效记录

现象:学生连点两次提交按钮,或网络重试,同一阶段出现两条待审记录。原因:接口没做幂等,前端也没防重复点击。解决:Service 里先查该学生该项目该阶段是否已有“待审核”记录,有则拒绝;前端按钮提交后置灰。数据库层面可加唯一索引兜底。

5.5 评审汇总用浮点累加,分数对不上

现象:专家打分 85.5、90.0、78.5,系统汇总显示 254.00000001。原因:用 double 做金额和分数累加。解决:分数和经费统一用BigDecimal,数据库用DECIMAL,汇总时setScale(1, RoundingMode.HALF_UP)。这个坑不踩一次很难记住。

6. 验收与答辩:怎么证明这套系统真的能跑通

验收不是把功能点一遍就完事。我带过的项目里,答辩翻车最多的不是功能缺失,而是讲不清“业务流程怎么闭环”。建议按下面三步准备。

第一步,跑通一条完整业务链并留证据。用一个学生账号申报项目,切指导老师账号审核通过,再切管理员账号确认立项;然后依次走中检提交与审核、结项提交与终审、评审方案下发、专家评审录入、优秀项目标记。每一步截图存档,按时间顺序排进论文的“系统实现”章节。这条链路能跑通,说明状态机、权限过滤、关联查询都是对的。

第二步,准备一张验收对照表。把需求里的功能项和实际测试结果一一对应,比空口说“功能齐全”有说服力:

验收项操作路径预期结果实测
学生申报学生登录→项目申报→提交状态变“待审核”,列表可见通过
老师审核老师登录→申报管理→通过状态变“已立项”通过
越权拦截学生直接请求管理员列表接口返回无权限或仅本人数据通过
重复提交连续两次点击提交第二次提示已提交通过
评审汇总录入三条专家评分平均分保留一位小数通过

第三步,预判三个必问问题。一是“为什么选 Spring Boot 而不是原生 SSM”,答自动配置和内嵌容器降低部署成本,底层仍是 SSM 分层;二是“权限怎么做的”,答会话取角色 + Service 层数据范围过滤 + 拦截器兜底;三是“数据一致性怎么保证”,答关键写操作加事务、状态流转单入口。这三个问题答顺了,基本盘就稳了。

从那以后我每次带毕设,都强制要求学生先画状态机再写代码,验收时按状态机逐条走一遍,而不是对着菜单点。状态机对了,系统就散不了。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询