尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot宿舍管理系统设计与实现:从表结构到部署避坑指南

SpringBoot宿舍管理系统设计与实现:从表结构到部署避坑指南 从选题到上线这篇说透SpringBoot宿舍管理系统怎么做又到毕业设计季节后台收到不少同学问宿舍管理系统怎么做也有几位在职的朋友想拿这个练手SpringBoot。这题目确实经典——业务边界清晰、角色分明、功能闭环完整用来演示SpringBoot的Web开发能力再合适不过。但正因为做的人多网上模板代码质量参差不齐照抄很容易翻车。我前段时间刚帮一位学弟把这个项目完整走了一遍从需求分析、表结构设计到核心模块编码、最后服务器部署踩了不少坑。这篇就把整个过程中的关键设计决策和实打实的代码经验整理出来给准备做这个题目的同学一个可以直接复用的参考。1. 选题定位与需求分析宿舍管理系统的核心价值在哪先说选题。很多同学担心“SpringBoot宿舍管理系统”太普通、没亮点。我的看法恰恰相反——对毕设来说需求边界清晰、逻辑闭环完整、技术延展空间大这三个特性比题目听起来“高大上”重要得多。宿舍管理系统恰好全占了。1.1 角色划分与权限边界宿舍管理系统本质上是一个多角色、多权限的校园后勤业务系统。按我实际梳理角色至少分四类学生查看宿舍分配、提交报修申请、查询水电费、访客登记宿管员处理报修工单、管理入住/退宿、登记访客、抄录水电表辅导员查看所辖学生的住宿情况、审批调宿申请系统管理员维护宿舍楼/房间基础数据、创建用户账号、统计报表这里有个关键设计点不要为了“功能多”而堆页面要把核心业务闭环做扎实。我见过太多项目把“失物招领”“二手交易”“论坛交流”塞进来结果报修功能还没跑通。一个能完整走通“提交-派单-处理-回访-评价”的报修模块比五个半成品模块都有说服力。1.2 核心业务闭环识别我用一张业务流程图梳理需求这里不贴图直接讲逻辑链住宿管理闭环学生信息 → 入住分配宿舍楼/房间/床位→ 调宿申请 → 退宿登记 → 房间状态变更报修管理闭环学生提交 → 宿管派单 → 维修工处理 → 学生确认完成 → 评价费用管理闭环水电表抄录 → 月度账单生成 → 学生查看欠费 → 缴费登记访客管理闭环访客登记 → 进出时间记录 → 宿舍楼门禁联动逻辑上每个闭环都有状态流转而状态流转恰好是SpringBoot开发中展示业务逻辑能力的最佳载体。后面我会详细讲报修模块的状态机设计。1.3 表结构设计从需求到数据库模型数据库设计是这个项目最见功力的地方。我最终拆了9张核心表这里给出建表SQL的关键片段和设计思路-- 宿舍楼表 CREATE TABLE dorm_building ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT 楼栋名称, manager_id BIGINT COMMENT 宿管员ID, floor_count INT NOT NULL DEFAULT 6, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 宿舍房间表 CREATE TABLE dorm_room ( id BIGINT PRIMARY KEY AUTO_INCREMENT, building_id BIGINT NOT NULL, room_number VARCHAR(20) NOT NULL UNIQUE COMMENT 门牌号, bed_count INT NOT NULL DEFAULT 4 COMMENT 床位总数, bed_used INT NOT NULL DEFAULT 0 COMMENT 已用床位, status TINYINT NOT NULL DEFAULT 1 COMMENT 1可用 0停用, UNIQUE KEY uk_building_room (building_id, room_number) ); -- 学生住宿表 CREATE TABLE dorm_student ( id BIGINT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE, student_name VARCHAR(50) NOT NULL, room_id BIGINT COMMENT 当前房间, bed_no VARCHAR(10) COMMENT 床位号, checkin_time DATETIME, status TINYINT COMMENT 1在住 0已退宿 );有几个设计决策值得展开说第一房间表和床位不单独建表而是用bed_used字段加bed_no字符串字段记录。有些同学喜欢把每个床位建一条记录结果一张四人间宿舍要拆4条床位记录房间信息大量冗余查询还要join。我选择在dorm_student表里直接存bed_no配合bed_used计数器做校验逻辑更清晰。床位维度的统计哪几个床位空了通过dorm_student表查询即可得到。第二房间状态与床位数量直接挂钩引入“乐观锁计数器”思想。每次分配床位时代码要校验bed_used bed_count然后执行update操作时带上WHERE bed_used 旧值再SET bed_used bed_used 1。这就是乐观锁的简单应用防止并发分配超员。第三逻辑外键而非物理外键。我建议在外键关系上不用FOREIGN KEY约束只在代码层保证关联性。原因很现实毕设项目后期调试时经常要清表重置数据物理外键会带来一堆删不掉、插不进的麻烦。用逻辑外键即普通字段加索引配合MyBatis-Plus的封装开发效率高很多。2. 技术选型与项目结构为什么是SpringBoot MyBatis-Plus Vue技术栈选择直接影响开发效率和论文工作量。我的组合是后端Spring Boot 2.7.x MyBatis-Plus 3.5.x Spring Security JWT前端Vue 3 Element Plus Axios Vite数据库MySQL 8.0开发工具IDEA Navicat Postman Swagger2.1 版本选型的取舍逻辑Spring Boot选2.7.x而不是3.x这是很多同学容易踩的坑。Spring Boot 3.0起要求Java 17并且javax包全部迁移到jakarta很多老教程的代码会直接报错。如果你用IDEA自带的Spring Initializr新建项目默认就是3.x这时候把教程里javax.servlet替换成jakarta.servlet才能跑通。我在项目里统一用2.7.18版配合Java 8/11都稳定网上绝大多数资料也能直接参考。MyBatis-Plus而不是MyBatis核心是省掉大量CRUD代码。单表查询直接继承BaseMapperT分页查询用PaginationInnerInterceptor逻辑删除用TableLogic注解比手写XML爽太多。不过要注意MyBatis-Plus只适合单表操作多表查询还是要手写SQL不要强行用它的Wrapper处理复杂关联。2.2 后端项目结构的分层设计我的package结构如下这个分层经过了实际项目的检验写论文画架构图也方便com.example.dms ├── config // 配置类CORS跨域、JWT拦截器、MyBatis-Plus分页插件 ├── controller // 控制层接收请求、参数校验、返回统一结果 ├── service // 业务层业务逻辑、事务控制 │ └── impl // 接口实现 ├── mapper // 数据访问层继承BaseMapper的接口 ├── entity // 实体类对应数据库表 ├── dto // 数据传输对象表单请求对象、响应对象 ├── vo // 视图对象给前端返回的组装数据 ├── common // 通用类统一返回结果、异常处理、常量、工具类 └── security // JWT过滤器和权限相关代码这个分层的核心思想是**“controller只做转发、service只管业务、mapper只碰数据”**。具体到代码里就是Controller不写任何SQL相关逻辑只接收参数、调用Service、处理异常Service是业务逻辑的核心层事务注解Transactional加在Service方法上实体类不要直接暴露给前端查询结果组装的VO单独定义2.3 统一返回体与异常处理的必要性这是很多同学忽略但答辩必被问的地方。如果每个Controller方法返回类型五花八门有的返回Map有的直接返回对象前端处理会非常痛苦。我统一用了一个ResultT类Data public class ResultT { private Integer code; // 200成功 400参数错误 401未登录 500服务器错误 private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(Integer code, String message) { ResultT result new Result(); result.setCode(code); result.setMessage(message); return result; } }配合一个全局异常处理器RestControllerAdvice把业务异常、参数校验异常、未知异常统一转成这个格式返回。这样前端只需要判断code字段就能处理所有响应。我习惯自定义一个BusinessException业务逻辑里遇到“房间已满”“重复提交”等情况直接抛出全局处理器捕获后返回对应错误信息。3. 核心模块实现细节入住分配、报修流转与水电费账单骨架搭好了现在进入最核心的部分。这三个模块是宿舍管理系统的“灵魂”也是答辩时评委最爱深挖的地方。3.1 入住分配并发安全与业务规则校验入住分配的逻辑不算复杂但边界场景特别多而且这些边界场景正是论文里“系统测试”章节的好素材。核心代码逻辑Service public class DormStudentServiceImpl implements DormStudentService { Autowired private DormRoomMapper dormRoomMapper; Autowired private DormStudentMapper dormStudentMapper; Override Transactional(rollbackFor Exception.class) public boolean assignRoom(AssignRoomDTO dto) { // 1. 学生是否已分配宿舍 Long count dormStudentMapper .selectCount(new LambdaQueryWrapperDormStudent() .eq(DormStudent::getStudentNo, dto.getStudentNo()) .eq(DormStudent::getStatus, 1)); if (count 0) { throw new BusinessException(该学生已分配宿舍不能重复分配); } // 2. 房间是否存在且状态正常 DormRoom room dormRoomMapper.selectById(dto.getRoomId()); if (room null || room.getStatus() 0) { throw new BusinessException(房间不存在或已停用); } // 3. 床位是否充足乐观锁更新 int rows dormRoomMapper.update(null, new LambdaUpdateWrapperDormRoom() .eq(DormRoom::getId, dto.getRoomId()) .eq(DormRoom::getBedUsed, room.getBedUsed()) .lt(DormRoom::getBedUsed, room.getBedCount()) .set(DormRoom::getBedUsed, room.getBedUsed() 1)); if (rows 0) { throw new BusinessException(该房间床位已满分配失败); } // 4. 创建住宿记录 DormStudent dormStudent new DormStudent(); dormStudent.setStudentNo(dto.getStudentNo()); dormStudent.setStudentName(dto.getStudentName()); dormStudent.setRoomId(dto.getRoomId()); dormStudent.setBedNo(dto.getBedNo()); dormStudent.setCheckinTime(LocalDateTime.now()); dormStudent.setStatus(1); return dormStudentMapper.insert(dormStudent) 0; } }这段代码里最值钱的是第3步的乐观锁更新。两个学生同时申请同一个房间最后一个空床位时如果没有eq(DormRoom::getBedUsed, room.getBedUsed())这个条件两个请求都会通过校验然后插进来造成超员。加上这个条件后只有一个update能返回1另一个返回0被拦截。这个点写进论文里比堆一百个页面都加分。3.2 报修工单的状态机与流程闭环报修模块我设计了五个状态待派单 → 维修中 → 待验收 → 已完成 / 已取消。public enum RepairStatus { PENDING(0, 待派单), PROCESSING(1, 维修中), WAITING_CONFIRM(2, 待验收), COMPLETED(3, 已完成), CANCELED(4, 已取消); private final Integer code; private final String desc; RepairStatus(Integer code, String desc) { this.code code; this.desc desc; } public Integer getCode() { return code; } public String getDesc() { return desc; } }**状态流转的核心是不允许跳状态、不允许逆流转。**比如待验收的工单不能被取消已完成的状态不能改回维修中。我用一个transition方法统一管理public boolean changeStatus(Long orderId, Integer targetStatus, Long operatorId) { RepairOrder order repairOrderMapper.selectById(orderId); if (order null) { throw new BusinessException(工单不存在); } // 校验当前状态是否允许流转到目标状态 SetInteger allowedTrans getAllowedTransitions(order.getStatus()); if (!allowedTrans.contains(targetStatus)) { throw new BusinessException(非法状态流转); } // 权限校验不同角色只能执行特定操作 // ... order.setStatus(targetStatus); return repairOrderMapper.updateById(order) 0; }suspend挂起这个状态我没加因为实际场景里“维修中”本身就包含等待配件、等待师傅到场的情况。状态设计越少流程越清晰论文里也越好解释。3.3 水电费账单定时任务与数据汇总水电模块的常见误区是把水电费做成手工录入——管理员每月逐个房间填数字。这样实现简单但体现不出SpringBoot的特色。我的方案是用定时任务自动生成月度账单。在启动入口加EnableScheduling然后写一个定时任务Component public class BillGenerateTask { Autowired private DormRoomMapper dormRoomMapper; Autowired private BillMapper billMapper; // 每月1日凌晨1点生成上个月账单 Scheduled(cron 0 0 1 1 * ?) public void generateMonthlyBill() { // 获取上个月的年月 YearMonth lastMonth YearMonth.now().minusMonths(1); String billMonth lastMonth.toString(); // 格式2026-01 // 查询所有有学生入住的房间 ListDormRoom rooms dormRoomMapper.selectList( new LambdaQueryWrapperDormRoom().gt(DormRoom::getBedUsed, 0)); for (DormRoom room : rooms) { // 查询上个月房间用水用电量从meter_reading表获取 MeterReading reading meterReadingMapper.selectOne( new LambdaQueryWrapperMeterReading() .eq(MeterReading::getRoomId, room.getId()) .eq(MeterReading::getMonth, billMonth)); if (reading null) { continue; // 没有抄表记录就不生成账单 } // 计算金额用水量 * 单价 用电量 * 单价 BigDecimal amount reading.getWaterUsage() .multiply(new BigDecimal(3.5)) .add(reading.getElectricUsage().multiply(new BigDecimal(0.8))); Bill bill new Bill(); bill.setRoomId(room.getId()); bill.setMonth(billMonth); bill.setAmount(amount); bill.setStatus(0); // 未缴费 billMapper.insert(bill); } } }cron 0 0 1 1 * ?这个表达式的含义是每年每月1日的01:00:00执行。前面的0 0 1是时分秒1是日期*是月份每月?是星期不指定。这里要注意Cron表达式的坑——SpringBoot的Cron只有6个字段没有年秒、分、时、日、月、周写多了直接启动报错。另外一个细节定时任务里的操作要防重复执行。比如刚部署完服务器定时任务把7月的账单生成了一遍第二天调整代码重新部署又执行了一次就会生成两批重复账单。我在bill表加了唯一索引uk_room_month(room_id, month)插入时用insertOrUpdate从数据库层面防重。4. 从开发到部署IDEA配置、Maven打包与Linux环境适配代码写完只是第一步能跑起来、能给别人演示才是关键。这一节讲部署相关的实际操作经验。4.1 IDEA中SpringBoot的配置细节IDEA 2026版本以及其他较新版本运行SpringBoot项目时端口配置可以在Run/Debug Configurations里临时指定也可以通过配置文件统一管理。我的习惯是端口写死在application.yml因为部署到服务器时用外部配置文件覆盖即可server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/dorm_manager?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 redis: host: 127.0.0.1 port: 6379 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0IDEA热部署的坑spring-boot-devtools这个依赖建议加上但它有个很坑的点——修改application.yml后它会自动重启应用连不上数据库时启动失败会疯狂循环重启。解决办法是在application.yml里配置spring: devtools: restart: enabled: true exclude: static/**,public/**,templates/**4.2 Maven构建与打包的必备姿势Maven打包是毕设演示前最容易翻车的环节。用IDEA右侧Maven面板执行package命令时SpringBoot项目默认打包的是可执行jar包。有几步必须注意第一步pom.xml里确保有spring-boot-maven-plugin插件build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build第二步打包时跳过测试mvn clean package -DskipTests如果加了spring-boot-starter-test依赖打包时默认会自动跑单元测试。一旦某个测试类连接数据库失败整个打包流程直接红灯退出。我习惯把-DskipTests写进Maven配置里团队开发时也不会互相坑。第三步打包产物区分打包完成后target目录下会有两个jar项目名-1.0.0.jar可执行jar和项目名-1.0.0.jar.original普通jar。必须用不带.original的那个这才是SpringBoot的可执行jar包里面包含了所有依赖。.original是给外部容器用的直接双击运行不了。4.3 部署到Linux服务器的环境适配带学弟部署的时候我发现最大问题不是代码而是Windows开发环境到Linux运行环境的差异。主要解决三件事数据库连接适配本地MySQL密码是123456服务器上改成了强密码代码里直接写死密码很危险。我的方案是启动时用环境变量覆盖java -jar dorm-system.jar --spring.datasource.password${DB_PASSWORD}这样jar包里可以保持默认配置真实密码只存在服务器的环境变量里。答辩展示的时候现场改数据库连接也不需要重新打包。文件路径问题Windows的C:\Users\xxx在Java代码里要写System.getProperty(file.separator)而不是硬编码\\。我在做宿舍管理系统的头像上传功能时就是用这种方式拼接路径Linux下才能正常存到/var/www/uploads。防火墙和端口服务器安全组和系统防火墙都要放行8080端口。我经常遇到“jar包启动成功但浏览器访问不了”的情况十有八九是阿里云/腾讯云安全组没配要么是firewall-cmd没放行。这个坑写进论文的“部署与测试”章节里反而是亮点——说明你真的遇到并解决了实际问题。宝塔面板部署如果你用宝塔面板“网站”菜单里选“Java项目”上传jar包、填写端口、设置启动命令java -jar dorm-system.jar绑定域名后就能直接访问。但要注意宝塔默认使用的是Java 8环境如果你把Spring Boot 3.x项目部署上去会因为Java版本不兼容直接启动失败。这也是我为什么坚持Spring Boot 2.7版——兼容性最好。5. 前后端联调与Vue打包进SpringBoot的几种方式宿舍管理系统如果只做后端API页面全靠Swagger看不直观答辩演示效果差很多。这里分享前后端联调的经验。5.1 联调阶段跨域与接口联调最常见的问题跨域问题是前后端分离开发的第一个坎。前端跑在http://localhost:5173Vite默认端口后端跑在8080浏览器会拦截跨域请求。我的解决方案是在后端配置类统一处理Configuration public class CorsConfig { Bean public CorsWebFilter corsWebFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(http://localhost:5173); // 前端地址 config.addAllowedMethod(*); config.addAllowedHeader(*); config.setAllowCredentials(true); config.setMaxAge(3600L); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsWebFilter(source); } }这里有个细节allowCredentials(true)表示允许携带Cookie但一旦设置为trueaddAllowedOrigin就不能用*通配符必须指定具体地址否则浏览器直接拒绝。另一个联调常见问题是日期时间格式。后端返回LocalDateTime默认序列化成2026-01-15T10:30:00这种中间带T的格式前端展示很丑。我的解决方式是在application.yml配置全局的Jackson格式spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT85.2 Vue项目打包后如何给SpringBoot“带”着跑毕设答辩时最轻松的演示方式是启动SpringBoot jar包浏览器直接访问8080端口就能看到页面不用额外启动Vue的dev server。这就涉及怎么把Vue打包产物放进SpringBoot项目里。有两种常用方式我分别说清楚优劣方式一把dist目录放进SpringBoot的static目录简单但不好维护npm run build # 把生成的dist目录下的文件copy到后端项目的src/main/resources/static/这样打包jar时前端页面会自动包含进去。这种方式最省事但有个坑Vue路由如果是history模式刷新页面时会出现404因为后端根本没有对应的路径。解决方案一个是改用hash路由createWebHashHistory另一个是后端写一个转发控制器Controller public class PageForwardController { // 解决history模式路由刷新404 RequestMapping(value {/, /login, /dashboard, /student/**, /repair/**}) public String forward() { return forward:/index.html; } }方式二用Maven插件把前端构建集成进后端打包流程在pom.xml里配置frontend-maven-plugin打包后端jar时自动执行npm install和npm run build然后把产物拷贝进后端资源目录。好处是每次mvn package都能打出一个完整可运行的jar不需要手动复制缺点是首次构建需要下载Node环境比较慢。人演示时间紧张的时候我推荐方式一手动copy一次就够了。5.3 联调中的API前缀统一问题我习惯在Controller的RequestMapping里统一加前缀比如/api/student、/api/admin、/api/repair前端封装的axios实例统一用baseURL: /api。这样前后端都清晰部署到服务器后如果加了Nginx反向代理也只需要在Nginx里把/api前缀转发到SpringBoot的8080端口非常灵活。6. SpringBoot版本过高的适配问题从2.7到3.x的几条经验和避坑记录答辩前一周学弟突然问“老师让我把SpringBoot版本升到3.x说更主流怎么办”。很多同学会在这个环节被难住其实思路清晰的话半天就能解决。我陪他踩了一遍坑把这部分经验完整记录下来。6.1 从javax到jakarta代码迁移的机械步骤Spring Boot 3.x最核心的变化是Java EE包名从javax迁移到jakarta。如果你代码里写的是import javax.servlet.http.HttpServletRequest;Spring Boot 3.x下直接编译报错“找不到javax.servlet”。全局搜索import javax.全部替换成import jakarta.。基本上涉及Servlet、Validationjavax.validation、Annotationjavax.annotation这几类。IDE的全局替换功能五分钟搞定。但要注意有些第三方库内部还在用旧的javax包如果它们没有升级到兼容Jakarta的版本就会在运行时抛NoClassDefFoundError。比如某些老版本的pagehelper、fastjson都会踩到。所以升级前先检查依赖清单优先用Spring官方或主流社区更新过的库。6.2 自动装配机制的兼容性变化Spring Boot 3.x对自动装配的机制也做了调整。2.7时代如果你要自定义一个自动配置类是在META-INF/spring.factories文件里声明org.springframework.boot.autoconfigure.EnableAutoConfigurationcom.example.MyAutoConfiguration3.x换成了META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件每行一个配置类的全限定名。很多第三方starter没跟上这个变化就会在3.x里失效。如果你遇到“明明加了依赖但配置不生效”的问题优先怀疑这个。6.3 我最终的建议不要盲目升级跟学弟折腾完Spring Boot 3.x的适配后我的建议其实是如果毕设要求没硬性规定留在2.7完全没问题。原因有三2.7仍在社区维护周期内资料多、报错可查论文的“技术栈选型”章节写清楚为什么选2.7稳定性优先、兼容性广本身就是合理的选型论证3.x带来的主要优势AOT编译、GraalVM原生镜像等对毕设场景没有实质帮助反而徒增复杂度如果老师确实要求3.x那上面的迁移步骤足够应付。答辩被问“你如何考虑版本升级风险”时能说出javax到jakarta的变化、spring.factories到AutoConfiguration.imports的变化就是加分项。6.4 关于SpringBoot整合周边组件的提醒热搜词里有“springboot整合flink”“springboot集成tdengine”“springboot集成activemq”这些整合类的词。宿舍管理系统这类业务系统不建议为了体现技术深度去硬塞Flink或TDengine——一个宿舍管理系统根本产生不了流式计算和时序数据库级别的数据量硬整合会让论文“需求分析”和“技术选型”自相矛盾高并发大数据量的技术栈和低并发轻量级的业务场景不匹配。如果你确实想体现扩展能力整合一个RabbitMQ或ActiveMQ做报修通知异步化已经是恰到好处的复杂度。7. 答辩前最终的部署验证清单与常见故障处理最后给一份我总结的“答辩前48小时部署验证清单”这是帮多位同学做完项目上线后沉淀的实操经验。按这个顺序检查基本能避免现场翻车。第一项数据库初始化验证数据库能否用项目自带的init.sql脚本一键重建答辩换个环境运行最怕数据库表缺失把数据库账号密码改成和目标环境一致的或者确认环境变量注入正常第二项jar包启动验证确认mvn clean package -DskipTests能产出可执行jar执行java -jar xxx.jar看启动日志有没有红字异常用curl http://localhost:8080/api/health验证服务存活第三项前端资源验证访问http://localhost:8080/能否正常出现登录页登录、查询、提交工单等核心流程走一遍重点测试刷新页面确认history路由的404问题已处理第四项服务器部署验证服务器防火墙和安全组是否放行端口数据库连接地址是否替换成了服务器地址后台定时任务是否正常触发可以把cron改短测试比如每5分钟执行一次确认数据无误后再改回每月执行高频故障对照表现象原因排查顺序常用解法启动时报Failed to configure a DataSourceapplication.yml数据库连接配置错误检查url/username/password确认数据库已创建且服务已启动前端请求全部401JWT拦截器把登录接口也拦截了在拦截器配置里放行/api/auth/login等白名单路径上传图片后页面显示404静态资源映射没配配置spring.web.resources.static-locations指向上传目录打包后前端页面白屏Vue-router使用history模式切换hash模式或配置后端转发刷新页面404history模式无转发按上文方式配置PageForwardController接口返回时间差8小时数据库时区与Jackson时区不一致数据库url加serverTimezoneAsia/ShanghaiJackson加GMT8帮学弟走完这个项目的整个过程我最大的体会是管理系统类项目能不能做好不在功能页面的数量而在核心业务闭环的质量。一个能完整走通入住-报修-账单流程、状态流转逻辑严谨、部署方案清晰的项目远比堆了十几个不痛不痒的功能模块更有说服力。如果你正在做这个题目按上面的方案从表结构设计入手先把核心闭环跑通再考虑扩展功能。遇到具体卡点欢迎来交流。
返回列表