尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于SpringBoot的高校校园网故障管理系统设计与实现全指南

基于SpringBoot的高校校园网故障管理系统设计与实现全指南 在计算机专业毕业设计中管理系统类选题一直占比较大而基于 SpringBoot 的高校校园网故障管理系统又属于其中非常典型的“业务闭环 技术覆盖”组合。它既不像纯电商系统那样业务面过宽也不像纯工具类项目那样缺乏业务深度。学生提交故障单、维修人员接单处理、管理员分配工单并查看统计报表这一条完整链路既能展示后端的接口设计、数据库建模、权限控制能力又可以用 Vue、Thymeleaf 或小程序作为前端呈现数据可视化也能顺势纳入论文。本文会围绕这个选题从业务需求、功能拆分、表结构设计、核心代码实现、运行验证、常见排错、论文撰写和答辩准备几个层面展开帮助准备做该题目的同学理清开发思路也帮助指导老师快速了解这个选题的工程价值。这个系统本质上是在解决一个实际问题高校校园网规模不断扩大学生宿舍、教学楼、办公区的网络故障报修长期依赖电话、微信群、Excel 表格登记信息散落在不同渠道维修进度不透明管理员也很难统计哪个区域故障最多、哪个维修人员工作量最大。用一个 Web 系统把“报修—派单—处理—反馈—统计”串起来就是这套毕业设计最核心的价值。对毕设而言它业务明确、角色清晰、技术栈主流工作量适中非常适合作为 SpringBoot 方向的项目选题。1. 这个选题到底在解决什么问题——从校园网运维现状说起1.1 校园网故障报修的真实痛点在没有信息化系统之前校园网故障报修通常走这几个渠道电话通知网络中心、在学院群里发消息、提交纸质报修单。这三个渠道各有问题。电话报修的最大问题是信息不完整。学生报修时经常只留下一句“网断了”没有楼栋、房间号、联系方式、故障类型维修人员需要反复回拨确认。微信群报修则容易被大量消息刷掉而且没有状态跟踪学生不知道自己的报修单是否被受理只能反复询问。纸质报修单的问题更明显不易查询、不易统计、容易丢失。这些痛点放在一起就能提炼出系统需求学生可以按规范格式提交故障单包含位置、故障类型、描述、联系电话。维修人员可以看到分配给自己的工单更新处理进度填写处理结果。管理员可以分配工单、查看全部故障单、统计故障类型和维修耗时。所有角色都能根据工单号查询处理进度。这个业务逻辑并不复杂但覆盖了用户管理、工单管理、状态流转、权限控制和统计分析是标准的“小而完整”的毕业设计业务模型。1.2 为什么 SpringBoot 适合做这个毕设SpringBoot 是当前 Java Web 开发使用率最高的框架之一因为它的自动配置机制大幅降低了 Spring 项目的搭建成本。传统 SSM 项目需要手动配置 Spring、SpringMVC、MyBatis 的 XML 文件而 SpringBoot 通过 starter 依赖和自动配置让开发者只需要关注业务代码。用 SpringBoot 做这个选题优势体现在几个方面起步快引入spring-boot-starter-web、spring-boot-starter-data-jpa或mybatis-spring-boot-starter、mysql-connector-java就能快速搭建一个可运行的项目骨架。生态成熟认证授权、接口文档、代码生成器、权限框架都有现成集成方案。市场需求大Java 后端岗位普遍要求 SpringBoot 经验做这个题目能覆盖招聘常见技能点。论文素材丰富自动配置原理、启动流程、starter 机制、内嵌 Tomcat 都可以作为论文中“技术介绍”部分的支撑内容。对于技术能力中等、想在毕设中稳定输出一个完整项目的学生来说SpringBoot 是比 SSM 更省心、比 Spring Cloud 更稳妥的选择。1.3 用一条核心业务流程理解系统整个系统可以凝缩成一条主链路学生登录 → 填写故障单 → 提交 → 管理员查看未分配工单 → 指派维修人员 → 维修人员接单 → 填写处理结果 → 学生查看处理反馈围绕这条主线还需要补充几个辅助流程学生可以在“我的报修”中查看历史工单和状态。管理员可以按时间段、故障类型、处理状态筛选工单。维修人员可以查看自己名下所有工单按状态排序。系统可以对超时未处理的工单进行标记或提醒。这套流程设计好之后数据库表、接口、页面都围绕它展开。做之前把主链路画清楚后面开发就不容易跑偏。2. 功能范围要先定清楚不然开发时容易越做越散2.1 角色边界学生、维修人员、系统管理员各管什么建议按三种角色做权限设计账号表里加一个role字段区分身份不引入完整 RBAC 框架也能满足毕设要求。角色核心功能需要的数据学生提交故障单、查询自己提交的工单、查看处理结果姓名、学号、联系电话、宿舍或办公地点维修人员查看被分配工单、更新处理状态、填写维修结果姓名、工号、维修类型偏好可选管理员分配工单、管理用户、查看统计报表、导出数据工号、管理权限标记三种角色的权限边界要清楚学生只能增删改查自己的工单维修人员只能查看分配给自己的工单管理员拥有全部权限。这个边界在 Service 层做校验而不是只靠前端隐藏按钮。这里有一个常见的毕设误区把管理员功能做得过大比如让管理员手动录入所有故障信息、手动维护维修结果这样系统就退化成 Excel 管理工具。正确做法是让管理员承担“调度”职责把具体处理动作交给维修人员和学生操作才能体现系统价值。2.2 功能模块清单与优先级做毕业设计最忌讳功能规划过满开发到后期发现时间不够。建议按优先级把功能分成三类核心功能必须完成用户登录注册、故障单提交、工单列表、管理员派单、维修人员更新状态、学生查看反馈。增强功能有时间再做短信或站内信通知、按时间区间的统计报表、Excel 导出、图片上传。演示亮点答辩加分ECharts 图表展示故障类型分布、维修耗时趋势、楼栋故障排行。在开发顺序上先做核心功能闭环再考虑增强功能。很多同学上来先折腾前端样式结果后端的工单状态逻辑没想清楚最后联调时反复返工。2.3 核心状态机故障单的一生故障单状态是整个系统的核心建议定义为枚举避免在代码里散落魔法值。public enum FaultStatus { PENDING(待处理, 0), ASSIGNED(已派单, 1), PROCESSING(处理中, 2), RESOLVED(已解决, 3), CLOSED(已关闭, 4); private final String desc; private final int code; FaultStatus(String desc, int code) { this.desc desc; this.code code; } public String getDesc() { return desc; } public int getCode() { return code; } }状态流转建议如下当前状态操作下一状态待处理管理员指派维修人员已派单已派单维修人员开始处理处理中处理中填写维修结果已解决已解决管理员确认或学生确认已关闭任意状态管理员取消已关闭这部分要写进论文的“系统设计”章节也是答辩时老师最容易提问的地方。3. 数据库设计是论文和答辩最容易被追问的部分3.1 核心表结构设计建议从四张核心表开始设计后期按功能扩展。用户表CREATE TABLE user ( id bigint NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 登录账号, password varchar(100) NOT NULL COMMENT 加密后密码, real_name varchar(50) NOT NULL COMMENT 真实姓名, role tinyint NOT NULL DEFAULT 0 COMMENT 0-学生 1-维修人员 2-管理员, phone varchar(20) NOT NULL COMMENT 联系电话, student_no varchar(30) DEFAULT NULL COMMENT 学号或工号, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;故障单表CREATE TABLE fault_order ( id bigint NOT NULL AUTO_INCREMENT, order_no varchar(30) NOT NULL COMMENT 工单号, student_id bigint NOT NULL COMMENT 提交人ID, assignee_id bigint DEFAULT NULL COMMENT 维修人员ID, fault_type varchar(30) NOT NULL COMMENT 故障类型网络中断、网速慢、设备故障、配置问题等, location varchar(100) NOT NULL COMMENT 故障位置如宿舍楼栋房间号, description varchar(500) NOT NULL COMMENT 故障描述, status tinyint NOT NULL DEFAULT 0 COMMENT 状态0待处理 1已派单 2处理中 3已解决 4已关闭, priority tinyint NOT NULL DEFAULT 1 COMMENT 优先级1普通 2紧急, handle_result varchar(500) DEFAULT NULL COMMENT 处理结果, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_student_id (student_id), KEY idx_assignee_id (assignee_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT故障工单表;这个设计里有几个关键点order_no使用单独字段而不是直接用自增主键因为工单号要展示给学生如SD20250612001。student_id和assignee_id都关联user表但要区分语义一个是报修人一个是维修人。数据库外键可以不加改由 Service 层保证业务关系但实体中要维护关联关系因为 JPA/MyBatis Plus 的查询需要用到。状态字段用tinyint而不是varchar查询效率更高也便于代码里用枚举映射。处理记录表用于保存每个工单的状态变更历史CREATE TABLE fault_log ( id bigint NOT NULL AUTO_INCREMENT, order_id bigint NOT NULL, operator_id bigint NOT NULL, from_status tinyint DEFAULT NULL, to_status tinyint NOT NULL, remark varchar(255) DEFAULT NULL, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_order_id (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT工单操作日志表;第一次做这种系统的同学很容易忽略日志表但这是答辩时的加分项。因为有了这张表论文里可以写“系统对关键操作进行留痕支持审计追溯”这也符合真实管理系统的要求。评论或反馈表CREATE TABLE feedback ( id bigint NOT NULL AUTO_INCREMENT, order_id bigint NOT NULL, user_id bigint NOT NULL, content varchar(500) NOT NULL, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_order_id (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT工单反馈表;如果需要实现学生或管理员在工单下留言这张表就能派上用场。3.2 外键和状态字段的取舍很多教程喜欢在数据库里大量加外键约束但实际毕设项目中建议只在建表测试时保留正式开发时优先靠应用程序保证数据一致性。原因有三点外键锁对并发写入有额外开销虽然毕设场景并发很低但不利于展示“对实际工程问题的理解”。删除用户或批量导入数据时外键约束容易导致操作失败。Spring Data JPA 维护双向关联关系时外键约束会和级联操作相互干扰。更合理的做法是在实体类中定义关联关系使用ManyToOne或ManyToMany但是否保存外键由 JPA 策略决定。MyBatis 场景则直接写多表 JOIN SQL不在数据库层加外键这种写法更常见。但是唯一索引和普通索引不能省。username必须唯一故障单查询会按student_id、assignee_id、status频繁过滤这三列要建立普通索引。3.3 数据统计怎么算论文的“系统实现”部分需要展示统计功能常见统计维度如下统计项SQL 思路各故障类型数量SELECT fault_type, COUNT(*) FROM fault_order GROUP BY fault_type各状态工单数量SELECT status, COUNT(*) FROM fault_order GROUP BY status维修人员工单量SELECT assignee_id, COUNT(*) FROM fault_order GROUP BY assignee_id当月故障趋势按DATE_FORMAT(create_time, %Y-%m-%d)分组平均处理时长AVG(TIMESTAMPDIFF(HOUR, create_time, update_time))统计建议在 MySQL 中使用 GROUP BY 完成不要在 Java 内存里做聚合。原因是逻辑简单、性能更好而且 SQL 语句可以直接写进论文显得工作量饱满。4. 开发环境、技术栈和项目目录要对齐4.1 环境要求做毕设前先把环境版本固定下来避免后期因为版本不一致产生各种奇怪问题。推荐一套常用组合组件推荐版本说明JDK1.8 或 11SpringBoot 2.x 用 JDK 8SpringBoot 3.x 用 JDK 17Maven3.6依赖管理和打包MySQL5.7 或 8.0生产常用版本SpringBoot2.7.x 或 3.x二选一不要混用MyBatis Plus3.5.x也可使用 Spring Data JPA这里有一个重要提醒如果使用 SpringBoot 3.xJDK 必须是 17 以上且有的第三方 starter 还没有完全适配。如果不想在版本兼容上浪费太多时间建议使用 SpringBoot 2.7.x JDK 1.8这是目前资料最多、踩坑最少的组合。4.2 SpringBoot 项目目录结构建议按功能包管理而不是按层分包。所谓按层分包是把 controller、service、mapper 全部放在独立包下项目变大后各个模块混在一起不好维护。按功能分包更清晰com.example.campusnetwork ├── config # 配置类如跨域、拦截器 ├── controller # 接口层 │ ├── AuthController.java │ ├── FaultOrderController.java │ └── AdminController.java ├── service # 业务层 │ ├── FaultOrderService.java │ └── UserService.java ├── mapper # 数据访问层 │ ├── UserMapper.java │ └── FaultOrderMapper.java ├── entity # 实体类 │ ├── User.java │ └── FaultOrder.java ├── dto # 接收参数对象 │ ├── LoginDTO.java │ └── FaultOrderDTO.java ├── vo # 返回结果对象 │ └── OrderVO.java ├── common # 通用类 │ ├── Result.java │ └── PageResult.java └── exception # 异常处理 └── GlobalExceptionHandler.java有些同学把所有类都往一个包下堆文件到 30 个以上后就很难找。代码组织本身也是论文“系统实现”中可以写的点描述清楚项目结构评审老师会认为工程素养不错。4.3 application.yml 有哪些关键配置一个最小可运行的application.yml示例server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/campus_network?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: root jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true这里有几个容易出错的地方serverTimezoneAsia/Shanghai可以避免 MySQL 8 的时区报错。map-underscore-to-camel-case开启后数据库的create_time才能自动映射到实体的createTime。如果使用 SpringBoot 3.xspring.datasource配置前缀不变但驱动类需要换成com.mysql.cj.jdbc.Driver并且引入对应的 JDBC 驱动版本。不要为了“看起来高级”而同时引入多数据源、Redis、消息队列毕设项目关键在于把主流程做扎实。5. 关键功能实现从登录到故障单闭环5.1 用户认证和登录态管理毕设项目不推荐直接引入 Spring Security JWT 这样复杂的组合虽然它很主流但配置和异常处理会占掉大量开发时间。一个稳妥的做法是使用拦截器 Session 或 Token 的简单方案。如果使用 Session核心代码如下RestController RequestMapping(/api/auth) public class AuthController { PostMapping(/login) public Result login(RequestBody LoginDTO loginDTO, HttpSession session) { User user userService.login(loginDTO.getUsername(), loginDTO.getPassword()); session.setAttribute(loginUser, user); return Result.success(user); } PostMapping(/logout) public Result logout(HttpSession session) { session.removeAttribute(loginUser); return Result.success(); } }配合拦截器实现未登录拦截Component public class LoginInterceptor 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.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\msg\:\未登录或登录已过期\}); return false; } return true; } }密码必须加密存储不要使用明文。推荐BCryptPasswordEncoder或DigestUtils.md5DigestAsHex加盐Spring Security 的BCryptPasswordEncoder即使不引入完整 Spring Security 也可以单独使用。这里要注意使用 Session 方案时需要考虑跨域携带 Cookie 的问题。前后端分离时前端请求需要配置withCredentials: true后端要配置跨域允许携带凭证Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }5.2 提交故障单的表单校验与服务端校验前端表单可以写一些简单校验比如必填、手机号格式但服务端必须再做一层校验否则可以通过接口直接提交非法数据。故障单提交服务代码如下Service public class FaultOrderService { Resource private FaultOrderMapper faultOrderMapper; Transactional public FaultOrder submit(FaultOrderDTO dto, User student) { // 1. 校验故障类型和描述 if (!StringUtils.hasText(dto.getLocation())) { throw new BizException(故障位置不能为空); } if (!StringUtils.hasText(dto.getDescription())) { throw new BizException(故障描述不能为空); } // 2. 生成工单号格式SD yyyyMMdd 4位随机数 String orderNo SD LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) RandomUtil.randomNumbers(4); // 3. 保存工单 FaultOrder order new FaultOrder(); order.setOrderNo(orderNo); order.setStudentId(student.getId()); order.setFaultType(dto.getFaultType()); order.setLocation(dto.getLocation()); order.setDescription(dto.getDescription()); order.setPriority(dto.getPriority()); order.setStatus(FaultStatus.PENDING.getCode()); faultOrderMapper.insert(order); // 4. 写入操作日志 faultLogMapper.insert(new FaultLog(order.getId(), student.getId(), null, FaultStatus.PENDING.getCode(), 学生提交工单)); return order; } }关键点有几个Transactional保证工单保存和日志写入要么同时成功要么同时失败。工单号生成逻辑要保证业务上的唯一性比赛场景用日期 随机数足够也可以使用数据库唯一索引兜底。操作日志从第一步就开始记录后续每一次状态变更都要插入一行这是审计需求。5.3 维修派单和状态流转管理员派单和维修人员改状态的代码要放在 Service 层并且校验当前用户角色和工单当前状态。Transactional public void assign(Long orderId, Long assigneeId, User admin) { FaultOrder order faultOrderMapper.selectById(orderId); if (order null) { throw new BizException(工单不存在); } if (order.getStatus() ! FaultStatus.PENDING.getCode()) { throw new BizException(只有待处理工单才能派单); } order.setAssigneeId(assigneeId); order.setStatus(FaultStatus.ASSIGNED.getCode()); faultOrderMapper.updateById(order); faultLogMapper.insert(new FaultLog(orderId, admin.getId(), FaultStatus.PENDING.getCode(), FaultStatus.ASSIGNED.getCode(), 管理员分配工单给维修人员 assigneeId)); }维修人员更新状态Transactional public void updateStatus(Long orderId, Integer targetStatus, String handleResult, User repairer) { FaultOrder order faultOrderMapper.selectById(orderId); if (order null) { throw new BizException(工单不存在); } if (!order.getAssigneeId().equals(repairer.getId())) { throw new BizException(只能处理分配给自己的工单); } int current order.getStatus(); // 只允许从已派单改为处理中或从处理中改为已解决 if (!((current FaultStatus.ASSIGNED.getCode() targetStatus FaultStatus.PROCESSING.getCode()) || (current FaultStatus.PROCESSING.getCode() targetStatus FaultStatus.RESOLVED.getCode()))) { throw new BizException(非法的状态流转); } order.setStatus(targetStatus); if (handleResult ! null) { order.setHandleResult(handleResult); } faultOrderMapper.updateById(order); faultLogMapper.insert(new FaultLog(orderId, repairer.getId(), current, targetStatus, handleResult)); }这段代码体现了状态机校验的严谨性论文里写“系统对状态流转做了边界校验避免出现非法跳转”时这段代码就是直接证据。5.4 统计报表与导出统计报表可以先用一个接口返回聚合数据再在前端用 ECharts 渲染。Mapper 中写统计 SQLMapper public interface StatsMapper { Select(SELECT fault_type AS name, COUNT(*) AS value FROM fault_order WHERE create_time BETWEEN #{start} AND #{end} GROUP BY fault_type) ListMapString, Object countByType(Param(start) String start, Param(end) String end); }时间参数建议使用LocalDateTime在 Service 层做默认值处理public ListMapString, Object countByType(String start, String end) { LocalDateTime startTime StringUtils.hasText(start) ? LocalDateTime.parse(start 00:00:00, formatter) : LocalDateTime.now().minusDays(30); LocalDateTime endTime StringUtils.hasText(end) ? LocalDateTime.parse(end 23:59:59, formatter) : LocalDateTime.now(); return statsMapper.countByType(startTime, endTime); }Excel 导出可以使用 Apache POI 或 EasyExcelEasyExcel 更推荐API 简单对内存压力小。导出功能不是核心功能建议放到功能基本完成后再补。5.5 通知机制如果希望系统有“提醒”能力优先实现站内信而不是短信或邮件。因为短信需要接入第三方服务邮件需要配置 SMTP站内信只需一张通知表和一次查询。通知表设计CREATE TABLE notification ( id bigint NOT NULL AUTO_INCREMENT, user_id bigint NOT NULL COMMENT 接收人ID, content varchar(255) NOT NULL, is_read tinyint NOT NULL DEFAULT 0, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id_read (user_id, is_read) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT站内通知表;关键业务动作发生时写入通知派单后通知维修人员维修完成通知学生。学生登录后可以在顶部红点看到未读数量。6. 运行验证启动、测试和常见异常排查6.1 从零启动一个最小可运行版本推荐按下面步骤进行每完成一步就验证一次不要等到所有代码写完再启动。创建数据库和表结构在 MySQL 中执行建库建表 SQL。创建 SpringBoot 项目引入依赖。配置application.yml先只配置数据源和 MyBatis。编写一个测试接口验证项目能启动、数据库能连接。逐步实现实体类、Mapper、Service、Controller。使用 Postman 或 Apifox 测试接口。对接前端页面。启动命令mvn clean spring-boot:run或者打包后运行mvn clean package -DskipTests java -jar target/campus-network-0.0.1-SNAPSHOT.jar启动成功的标志是控制台出现 Tomcat started on port(s): 8080并且数据库连接池初始化无异常。6.2 常见的三类启动问题问题现象常见原因检查与处理启动报Access denied for user rootlocalhost数据库账号密码错误检查application.yml中 username/password 是否与本地 MySQL 一致启动报Table campus_network.user doesnt exist没有执行建表 SQL或数据库名不对检查数据库名执行建表脚本启动报Failed to configure a DataSource数据源依赖缺失或配置未生效确认已引入spring-boot-starter-jdbc或mybatis-plus-boot-startermybatis-plus 无法扫描 Mapper启动类未加MapperScan启动类或配置类加MapperScan(com.example.campusnetwork.mapper)如果使用 SpringBoot 3.x还需要注意javax.servlet与jakarta.servlet的包名差异。很多老教程写的javax.servlet.http.HttpSession在 SpringBoot 3 中已经不存在需要改成jakarta.servlet.http.HttpSession。这是新手最容易踩的版本兼容坑。6.3 功能验证用例清单功能做完之后按照下面的用例逐步验证用例编号操作预期结果TC01学生登录返回用户信息Session 写入成功TC02学生提交工单故障位置为空接口返回“故障位置不能为空”TC03学生提交合法工单生成工单号状态为待处理TC04管理员查看未分配工单能看到刚提交的工单TC05管理员给维修人员派单状态变为已派单维修账号能看到该工单TC06维修人员处理非自己名下的工单返回“只能处理分配给自己的工单”TC07维修人员将已派单改为已解决接口拒绝提示非法状态流转TC08维修人员按顺序更新状态到已解决学生端可以看到处理结果TC09管理员查看统计接口返回按故障类型分组的数据TC10未登录访问受保护接口返回 401 或跳转登录页这组用例写进论文的“系统测试”章节评审老师看到后会认为项目有完整的测试意识。7. 把项目变成毕设论文和答辩素材7.1 论文章节怎么对应项目模块毕设论文的常见结构可以直接对应到系统模块论文章节对应内容绪论校园网报修现状、选题背景、国内外类似系统概述相关技术介绍SpringBoot、MyBatis Plus、MySQL、前端框架、ECharts需求分析功能性需求、非功能性需求、角色分析、用例建模系统设计总体架构图、功能模块图、数据库设计、接口设计系统实现登录认证、工单管理、派单处理、统计报表、关键代码系统测试测试环境、测试用例、测试结果、缺陷修复记录总结与展望项目成果、不足、后续扩展方向数据库设计小节中除了给出建表 SQL还应该画出 E-R 图。E-R 图可以用 Visio、draw.io 或 IDEA 的数据库插件生成不要用手画也不要贴代码截图。7.2 答辩时容易被问的技术问题结合这个选题答辩老师通常会从业务、技术、安全性三个维度提问为什么工单状态不用字符串而是用数字加枚举如何防止学生随意修改别人的工单如果维修人员一直不处理工单系统有什么机制密码是怎么存储的如果数据库泄露密码是否安全统计报表的 SQL 慢怎么办为什么选择 MyBatis Plus 而不是 JPA项目如何部署准备怎么演示回答这些问题的策略是不追求答得完美但要能说出自己的设计依据。比如“为什么用数字加枚举不用字符串”可以回答枚举约束状态可选项数据库用数字索引更快代码可读性更强而且状态流转可以在 Service 层做统一判断。7.3 自己给自己做的代码走查答辩前建议按这个清单重新审视自己的代码[ ] 所有接口都做了登录和权限校验了吗[ ] 错误请求是不是统一返回了标准 JSON[ ] 有没有使用全局异常处理器而不是在每个方法里写 try-catch[ ] 密码字段有没有被序列化返回给前端[ ] 数据库连接配置、密码等有没有硬编码在代码里[ ] 前端页面和后端接口能否独立演示而不是必须依赖自动生成的浏览器如果发现某个接口返回了用户表的密码字段一定要处理。可以在实体类的 password 字段上增加JsonIgnore注解或者在查询时直接不查询该列。8. 开发节奏、最佳实践与扩展方向8.1 开发进度规划建议毕设项目开发时间一般在 8 到 12 周。建议按下面的节奏推进阶段周期交付物需求分析和选题确认第 1 周功能清单、角色模型、数据库初步设计环境搭建和基础框架第 2 周项目骨架、数据库表、登录注册功能核心模块开发第 3-5 周工单提交、派单、处理、查询完整闭环增强功能和报表第 6-7 周统计图表、站内通知、Excel 导出前后端联调和测试第 8 周测试用例执行、缺陷修复论文撰写第 9-11 周论文初稿到终稿答辩准备第 12 周PPT、演示环境、预演很多同学在第三、四周时容易卡在“要不要加更多功能”上。建议记住一个原则先把主流程跑通再考虑锦上添花。一个能完整演示“学生报修—管理员派单—维修人员处理—学生反馈”的系统已经足够通过多数学校的中期检查和答辩。8.2 代码质量和安全实践实际开发中容易被忽视但很重要的实践参数校验使用分组校验与自定义注解结合避免在 Controller 中堆积大量 if 判断。Service 层方法承担事务边界Controller 层只做参数接收和结果返回。不要使用select *明确列出需要的字段既能减少网络传输也便于 SQL 分析。对查询列表接口做分页哪怕是毕设项目直接用IPage或 PageHelper 也不复杂。登录接口和提交接口要防重复提交简单的做法是在前端按钮加 loading后端对工单号做唯一约束。安全方面至少要关注密码加密、SQL 注入防护、接口越权校验。MyBatis 使用#{}参数绑定本身就能防止 SQL 注入但拼接排序字段、LIKE 查询时仍然要小心// 不推荐直接拼接排序字段 queryWrapper.orderByAsc(userInput); // 推荐白名单校验 String safeSort asc.equalsIgnoreCase(sort) ? asc : desc;8.3 可以扩展的方向如果在核心功能完成后还有时间和精力可以考虑以下扩展方向引入 WebSocket 实现工单状态实时推送学生页面不用刷新就能看到状态变化。引入 Redis 保存登录 Token 和工单热点数据提升性能也能在论文技术介绍里增加内容。接入企业微信或短信服务在派单和维修完成时发送通知。不过这个需要申请开发者账号时间成本较高建议量力而行。增加维修评价功能学生可以给维修人员打分形成闭环反馈。开发移动端小程序适配校园网报修场景天然适合手机端提交如果能做一个简单的小程序前端答辩效果会明显提升。这些扩展中WebSocket 和 Redis 的性价比最高。两者都有完善的 SpringBoot 集成示例而且论文里可以写“系统在数据访问层引入缓存降低了数据库压力”技术含量会更高。8.4 可复用清单最后整理一套开发前检查清单开始写代码和做论文之前先对一遍业务主链路是否已经清晰能否用一句话讲清楚。三种角色的权限边界是否明确。工单状态集合和流转规则是否定义完整。数据库表是否覆盖所有业务流程关键查询字段是否建立索引。是否设计了操作日志表关键操作是否都会写日志。所有写接口是否加了事务。密码、手机号、姓名等敏感字段是否有加密或脱敏处理。接口返回结构是否统一异常是否能被前端识别。测试用例是否覆盖正常流程、异常流程和越权场景。论文中的技术描述是否与代码实际实现一致。这个清单也适合用在中期检查前对照着查一遍能发现大部分会影响答辩的问题。这个毕设题目的核心在于把一条真实的校园网报修流程用一个主流 Web 技术栈完整落成系统。做好这个选题的关键不在功能数量而在业务逻辑的严谨程度和技术实现的规范程度。建议先完成最小闭环再逐步增强同时让数据库设计、接口设计、代码实现与论文内容保持一一对应这样开发过程会更顺答辩时也更有底气。
返回列表