资讯动态

基于SpringBoot的校园设备维护报修系统设计与实战

发布时间:2026/9/17 3:07:26 来源:尧图企业网站定制
1. 项目整体设计与思路拆解1.1 这个项目到底在解决什么问题先说说我为什么对这个项目感兴趣。你随便找一所高校宿舍楼、教学楼、实验楼里跑着的设备少说也有几千台空调、多媒体、门禁、照明、饮水机哪一样坏了不修都影响正常教学。以前很多学校是纸质报修单学生跑到宿管那儿登记宿管再打电话找维修师傅师傅修完再回头填一张单子整个过程追进度靠问、查记录靠翻、统计工作量靠Excel手动数效率低不说还经常漏单、扯皮。所以基于SpringBoot的校园设备维护报修系统本质上是把线下这套报修-派单-维修-验收-统计流程搬到线上让每个环节可追踪、可考核、可分析。往大了说这是高校后勤信息化里非常典型的一个场景小到几十万人口的大学大到中小学后勤都能套用这套模型。往小了说这也是一个非常适合拿来练手或者做毕业设计的SpringBoot综合项目因为它的业务链路完整又不像商城系统那样过度重复。如果你是一个正在学SpringBoot的人或者需要做一个能写进简历的真实项目强烈建议把这个系统好好搞一遍。它的价值在于涉及用户角色多学生、修理工、管理员、业务状态流转复杂待接单、维修中、待验收、已完成、还要处理消息通知、数据统计、权限控制这些绕不开的硬需求几乎把SpringBoot后端开发的常见场景都覆盖了。1.2 技术选型背后的取舍既然标题里写着SpringBoot那么后端框架基本就是定死的。但选SpringBoot的原因不只是因为大家都会而是它这套约定大于配置的机制天然适合校园报修这种业务逻辑清晰、开发周期紧、后续要维护的项目。我的建议是采用前后端分离架构前端用Vue Element UI或者更轻的Vue 3 Element Plus后端就是SpringBoot提供RESTful API。为什么要前后端分离因为报修系统里有大量表单交互、列表筛选、状态标签切换这种前端活儿分离之后前端专注交互体验后端专注业务逻辑和数据两边并行开发效率高得多。而且后续如果要接小程序端或者APP端后端API直接复用不用重写。数据库上常规做法是MySQL MyBatis-Plus。注意这里一定要用MyBatis-Plus不要用原生MyBatis因为它内置了分页插件、代码生成器、条件构造器能把你的工作量至少砍掉三分之一。缓存上可以引入Redis用来放用户token、工单热点数据、验证码之类的东西虽然业务体量不大但有了Redis你才能在简历上写使用Redis缓存热点数据这个加分项不能丢。权限框架方面我强烈建议别一上来就搞Spring Security OAuth2那一套重型组合校园报修系统的角色就三种学生、维修工、管理员用JWT做token鉴权配合一个拦截器就足够逻辑清晰、出错好排查也方便你在面试时讲清楚为什么这么设计。1.3 数据库表设计是项目的灵魂表设计这东西看起来不起眼实际上决定了你后面写代码是舒服还是痛苦。我给一个可以直接参考的模型总共六张核心表。用户表user存id、用户名、密码BCrypt加密后、真实姓名、手机号、角色1学生、2维修工、3管理员、所属部门或校区。密码加密这一点千万别省明文存密码的项目一旦被人扒出来基本就是事故。设备表device存设备编号、设备名称、类型空调/多媒体/照明等、安装位置比如第3教学楼502室、品牌型号、购置日期、状态正常/报废/维修中。设备表的好处是让报修工单能挂到具体设备上后续统计哪些设备故障率最高就非常方便。报修工单表repair_order这是核心中的核心。字段包括工单号用日期随机数生成、报修人id、设备id、故障描述、故障图片URL、紧急程度普通/紧急/特急、状态待接单/已接单/维修中/待验收/已完成/已关闭、指派的维修工id、报修时间、接单时间、完成时间、验收备注。状态字段我建议存int数字0到5不要直接存中文方便代码里判断流转。维修记录表repair_record每条工单可以有多次操作记录包括操作人、操作类型接单/维修/转单/验收、操作时间、内容备注。这个表是审计追踪用的出了问题能追溯谁在什么时候干了什么。通知消息表notification存接收人id、标题、内容、是否已读、创建时间。用于站内信、微信模板消息或邮件通知的持久化。统计视图不需要建表等写到统计功能时用SQL聚合查询或者建视图即可。字段命名统一用下划线风格Java实体类里用驼峰开启MyBatis-Plus的map-underscore-to-camel-case这样表字段和实体属性自动映射省心。主键一律用雪花ID或者自增ID建议统一别混用。2. SpringBoot核心机制解析与项目初始化要点2.1 从Idea新建项目说起别小看版本选型不少新手挂在起点上不是在写代码而是在新建项目那一步就被SpringBoot版本搞晕了。网上教程特别多但版本套版本你照着老教程选了Java 8然后发现SpringBoot拉到的是3.x一编译报错再看原因原来是javax包变成了jakarta包接口命名也变了顿时心态就崩了。我个人的经验是如果是学习或者做毕业设计千万不要追新版本不要看到一个SpringBoot 3.2.0就手痒。当前阶段最稳的组合是JDK 8 SpringBoot 2.7.x为什么因为2.7.x是2.x系列的最后一个稳定版本网上对应资料最全各种第三方整合的坑基本都被踩平了你在群里问问题也最容易得到有效答案。如果你非要折腾JDK 17或21那就要做好自己排查兼容性问题的心理准备比如某些老版本MyBatis-Plus在JDK 17下会报模块访问错误处理起来很闹心。新建项目时在Spring Initializr页面选择Spring Web、MyBatis Framework如果有、Validation、Lombok这几个依赖就够了其余依赖后面通过Maven手动加不要一次勾太多反而乱。2.2 自动装配原理讲给面试官听也讲给写代码的自己听SpringBoot最神奇的机制就是自动装配。你想想以前用SSM框架的时候你要配置数据源、配置SqlSessionFactory、配置事务管理器、配置组件扫描一堆XML或者配置类手写五分钟排错两小时。而SpringBoot项目里你只加了一个spring-boot-starter-web依赖Tomcat内嵌服务器就起来了Controller就能被访问了你加了一个spring-boot-starter-data-redisRedisTemplate就能直接注入了它凭什么这么聪明关键在于SpringBootApplication注解上的EnableAutoConfiguration它会扫描META-INF目录下的spring.factories文件或者AutoConfiguration.imports文件这个文件里列出了所有需要自动配置的类。SpringBoot启动的时候会把这些配置类加载进来然后通过ConditionalOnClass、ConditionalOnMissingBean、ConditionalOnProperty这一系列条件注解判断当前classpath里有没有对应的类用户有没有自己定义过Bean配置文件里有没有相关开关如果条件满足就执行自动配置。比如RedisAutoConfiguration上标着ConditionalOnClass(RedisOperations.class)也就是说你的classpath里没有Redis相关jar包的时候这个自动配置直接跳过不会报错一旦你引入starter依赖classpath里有这些类了它就自动生成RedisTemplate等Bean。这个机制对开发报修系统的好处是你不用手动写大量配置类配置文件里的内容可以非常精简。但这也带来一个问题——配置不可见。出了问题尤其是AutoConfiguration不生效的时候新手往往一头雾水。我的排查心得是先用debugtrue打开自动配置报告看看哪些AutoConfiguration生效、哪些不生效以及原因再考虑是不是启动类扫描包路径不对、或者Bean被重复定义导致条件不成立。2.3 分层架构与包结构规划写这种业务系统包结构一定要清爽。我习惯这样组织com.campus.repair ├── config // 配置类跨域、拦截器、WebMvc ├── controller // 接口层 ├── service // 业务层 接口/实现分离 ├── mapper // MyBatis-Plus的Mapper接口 ├── entity // 数据库实体类 ├── dto // 入参出参对象 ├── vo // 视图对象组合展示用 ├── utils // 工具类JWT、Result包装类 ├── exception // 统一异常处理 └── constant // 常量定义Controller层只做参数接收和结果包装不写业务逻辑。Service层写核心业务逻辑比如创建工单的时候要同时插入工单记录和通知记录这个事务放在Service方法里。Mapper层只用MyBatis-Plus的BaseMapper做基本的增删改查复杂查询用Wrapper或者写SQL。可能有人觉得这种分层太老套但我要说老套意味着稳。报修系统这种CRUD业务追求的就是逻辑清晰、易于维护你离职了或者毕业了别人接手你的代码能快速看懂这才是好的代码。千万别把一堆逻辑全堆在Controller里看起来写起来是快后患无穷。另外接口返回值统一封装。定义一个Result类包含code、message、data三个字段Controller所有接口返回这个对象。前端拿到后统一判断code是否为200再决定渲染逻辑。很多人忽略这一步导致前端每个请求都要单独处理错误逻辑代码重复又难看。3. 核心功能模块的实操实现3.1 用户登录与JWT鉴权报修系统第一步是登录。用户输入用户名密码后端校验通过后签发一个JWT令牌前端存储这个令牌后续每个请求都在Header里带上Authorization: Bearer token。后端写一个拦截器拦截所有需要鉴权的路径解析token然后把用户信息放入ThreadLocal里供Controller使用。核心代码长这样Component public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录接口 String uri request.getRequestURI(); if (uri.contains(/auth/login)) { return true; } String token request.getHeader(Authorization); // 这里用JwtUtil工具类校验token有效则将用户id放入request Long userId JwtUtil.parseToken(token.replace(Bearer , )); if (userId null) { response.setStatus(401); return false; } request.setAttribute(userId, userId); return true; } }注意拦截器注册时要配置排除路径比如登录接口、静态资源、接口文档。JWT的密钥要放到配置文件里不要硬编码在代码里且过期时间一般设置为24小时或者7天。我遇到过不少项目token鉴权做了但过期时间设成30天安全意识太弱。校园系统虽然不像支付系统那么敏感但该做的还是要做毕竟用户的手机号、宿舍位置都算隐私数据。3.2 工单状态流转是业务核心报修工单是系统的主线状态流转必须设计得严谨。我的方案是这样的0待接单——学生提交报修后自动进入该状态所有空闲维修工可见。 1已接单——维修工点击接单此时工单绑定到该维修工身上其他维修工不可见。 2维修中——维修工开始处理如果需要离开现场的时间可以在这里记录。 3待验收——维修工点击维修完成状态变为待验收学生收到通知可进行确认。 4已完成——学生确认无误工单关闭打分评价。 5已关闭——超时未处理或者管理员手动关闭。状态流转一定要做成受控的不要让用户随意改状态。比如一个普通学生不可能把待接单改成维修完成这就要在后端接口里做权限校验。我的做法是每个状态的变更都写一个独立接口接口内先判断当前状态是否符合前置条件不符合就抛异常返回错误提示。千万不要图省事做一个万能更新状态接口参数随便传那后台数据分分钟被搞乱。举个例子学生确认验收这个操作PostMapping(/order/{orderId}/confirm) public Result confirmOrder(PathVariable Long orderId, HttpServletRequest request) { Long userId (Long) request.getAttribute(userId); RepairOrder order repairOrderService.getById(orderId); // 权限校验该工单确实是这个用户报修的 if (!order.getReporterId().equals(userId)) { return Result.error(只能确认自己报修的工单); } // 状态校验只有待验收才能确认完成 if (order.getStatus() ! 3) { return Result.error(当前状态不可确认); } order.setStatus(4); order.setFinishTime(new Date()); repairOrderService.updateById(order); // 同步写一条记录、发通知给维修工 repairRecordService.record(orderId, userId, 确认完成, 学生确认维修完成); notificationService.send(order.getWorkerId(), 工单完成确认, 你处理的工单已被学生确认完成); return Result.success(); }这样写下来状态流转的每一步都有据可查出问题能通过维修记录表完整还原现场。3.3 消息通知模块的两种实现报修系统里有个特别影响体验的功能消息通知。学生提交报修后要收到你的工单已创建维修工张三已接单维修工要有新工单提醒管理员要收到超时未处理提醒。这里有两种常见方案。一种是站内信方案直接往notification表插记录前端打开系统时拉取未读消息数量这种实现简单不依赖第三方。适合Web端为主的使用场景。另一种是集成第三方推送比如微信公众号模板消息、邮件或者钉钉机器人。这种需要申请对应平台的开发者资质还需要配置模板ID、调用API复杂度高不少但胜在提醒及时维修工能第一时间在手机上收到消息。我的建议是先做站内信跑通全流程等系统真正部署上线有运营诉求了再考虑对接微信模板消息。报修系统的核心是流程不是推送姿势。当然如果你希望简历上多点技术亮点也可以引入WebSocket实现维修工端工单列表的实时刷新这个相对更好讲、投入也不大。这里我踩过一个很典型的坑站内信写入和工单状态更新不是在同一事务里的结果工单状态改成功了通知插入失败导致维修工根本没看到新单。解决方法是把这两个操作放在同一个Service方法里加上Transactional注解要么都成功要么都回滚。3.4 数据统计与可视化管理员端最需要的就是统计报表本月报修总数、各类型设备故障排行、维修工完工量排名、平均维修时长、超时工单数。这些统计项看似复杂其实都是SQL聚合的活儿。我的做法是写一个StatisticsController专门提供统计数据接口。比如查询各类设备报修占比SELECT d.type, COUNT(*) AS cnt FROM repair_order o LEFT JOIN device d ON o.device_id d.id WHERE o.create_time BETWEEN #{start} AND #{end} GROUP BY d.type ORDER BY cnt DESC如果数据量大了SQL会有点压力但校园报修系统一天最多也就几百条工单完全撑得住不需要引入复杂的OLAP引擎。前端用ECharts画饼图、柱状图、折线图加起来代码量大一点但没什么技术难度。还有一个思路值得做根据历史工单数据计算各教学楼设备故障频率提前安排巡检。这就是从被动报修向主动预防迈了一小步写论文或者做汇报时是很加分的运营亮点。4. 前后端联调与部署上线中的常见坑4.1 跨域问题别再一脸懵前后端分离开发的时候前端跑在8080端口后端跑在8081端口浏览器一请求接口控制台就报跨域错误。新手第一反应是搞什么JSONP、代理其实SpringBoot里解决跨域非常简单写一个配置类实现WebMvcConfigurer重写addCorsMappings方法就行。Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }注意allowCredentials(true)和allowedOriginPatterns(*)要搭配使用不能再用老的allowedOrigins(*)否则浏览器会拒绝携带凭证的跨域请求。开发环境这样配没问题但生产环境建议把allowedOriginPatterns改成具体的前端域名避免接口被任意网站调用。4.2 数据库连接超时与连接池耗尽报修系统部署上线后最常出现的故障就是数据库连接超时。原因多半是MySQL的wait_timeout默认是8小时长时间无请求的连接会被服务端断开而HikariCP连接池不知道仍然持有这些死连接下次请求拿去用就报CommunicationsException。解决方式有几种最稳妥的是在连接池配置里加connection-test-query或者设置validation-timeout。HikariCP默认是推荐配置但在MySQL下建议加上spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000这里最大生命周期必须小于MySQL的wait_timeout一般设置成30分钟或者更短确保连接被重建而不是拿一个被服务端断开的连接去用。很多人忽略这个参数等到线上出问题才回来补课尤其建议在写毕业设计和简历项目的时候就把这个经验写上面试官一看就知道你真实做过上线运维。4.3 文件上传的坑报修时学生要上传故障照片这就涉及文件上传功能。后端接收MultipartFile然后保存到服务器本地磁盘或者对象存储。校园系统体量小通常保存到本地磁盘指定目录同时返回一个URL供前端回显。但有两个坑必须提醒。第一Spring Boot默认单个文件上传大小限制是1MB你可能需要改配置spring: servlet: multipart: max-file-size: 10MB max-request-size: 20MB第二不要把文件随便保存在项目静态目录里否则重新部署时会丢。最好单独指定一个外部的文件存储路径比如/data/repair-system/uploads/配置文件里用绝对路径。而且访问图片需要配置一个静态资源映射把/uploads/**映射到实体磁盘路径。如果你部署到云服务器也可以考虑接入阿里云OSS或者MinIO操作难度不大但能把文件管理做得更专业。4.4 定时任务处理超时工单报修系统里有个很实用的功能自动识别超时工单。比如规定紧急工单必须在2小时内接单普通工单24小时内接单超出时间自动升级提醒管理员或者重新派单。这就用到了SpringBoot的定时任务。在主启动类或者配置类上加EnableScheduling然后在方法上加Scheduled(cron 0 */5 * * * ?)每5分钟扫描一次工单表Component public class OrderTimeoutTask { Scheduled(cron 0 */5 * * * ?) public void scanTimeoutOrders() { // 查询所有待接单且创建时间超过N小时的工单 ListRepairOrder timeoutOrders repairOrderService.list( new LambdaQueryWrapperRepairOrder() .eq(RepairOrder::getStatus, 0) .lt(RepairOrder::getCreateTime, new Date(System.currentTimeMillis() - 2 * 3600 * 1000)) ); // 逐个升级处理 } }这里要注意两点一是定时任务方法内不要忘记加try-catch防止单条数据处理异常导致整个任务中断二是如果将来部署了多实例定时任务会在多个实例上重复执行需要用分布式锁或ShedLock来解决校园系统单机部署压力不大但你要知道有这回事。5. 优化亮点与扩展方向5.1 登录认证的升级路径全文用的JWT实现了基础鉴权但如果想让系统设计更完美可以引入Redis管理token状态。思路是登录时生成token后以token为key用户信息为value存入Redis同时设置过期时间。每次请求来拦截器先查Redis存在才放行。这样最大的好处是能实现强制下线功能——管理员可以删除某个用户对应的Redis key这个用户的下一次请求就会被拦截token立刻失效。纯JWT方案是无法主动让token失效的除非你把过期时间设得非常短再配合refresh_token去刷新。这两种方案在面试时都可以讲前者胜在简单后者重视可控性。5.2 引入工作流引擎值不值得有计划可能问SpringBoot整合Flowable或者Activiti来做工单流转行不行我的看法是这个项目规模下引入工作流引擎属于过度设计。Flowable是为复杂的、多角色、多分支、有会签/驳回的业务流程准备的报修工单的状态流转用代码控制已经足够清晰。但如果你是为了学习工作流引擎单独做一个模块去整合Flowable也是可以的选择只是不要把它堆到报修系统主流程里平白增加维护成本。当前业界听说有springboot整合flowable的搜索热词但那是另一个项目的范畴。如果真想加分不如把精力花在把状态流转代码写得更规范、把事务边界画得更清楚上面这在面试官眼里更显功力。5.3 性能优化和监控校园报修系统并发量不高优化空间有限但有两件事还是值得做。第一是热点数据的缓存。设备列表、维修工是否在线这类不常变化的数据可以缓存到Redis减少数据库压力。比如工单详情页可能频繁被查看可以把工单的基本信息和状态缓存到Redis当状态变更时删除对应缓存。第二是操作日志。除了repair_record表记录业务操作外还可以用Logback的MDC集成一个请求日志增强模块把每个请求的用户id、请求路径、耗时、异常信息统一打印到日志文件里。这个日志是你排查线上问题最核心的依据。我见过太多项目出了问题只有前端一句接口报500后端日志却没记录任何上下文查起问题来像大海捞针。5.4 后续可以怎么扩展报修系统的扩展方向其实很多。比如增加一个备品备件管理模块维修工可以申领配件管理员通过库存流水跟踪成本。再比如增加评价体系学生验收后对维修服务打分形成维修工的月度绩效排名。又比如对接学校的统一身份认证系统CAS学生和教师直接用学号工号登录省去单独注册流程。这些扩展方向每一个都可以作为你博客的下一篇选题。6. 前端快速搭建要点基于Vue6.1 工程结构与路由设计既然定位是前后端分离前端也不能糊弄。用Vue 3 Vite Pinia Vue Router工程结构如下src ├── api // 接口请求封装 ├── assets // 静态资源 ├── components // 公共组件 ├── router // 路由配置 ├── store // 全局状态管理 ├── views // 页面 │ ├── student // 学生端提交报修、我的工单 │ ├── worker // 维修工端工单列表、接单维修 │ └── admin // 管理端用户管理、设备管理、统计报表 └── utils // 封装axios、token存取路由配置里用beforeEach守卫做登录判断没有token就跳转到登录页有token再根据角色ref字段判断能访问哪些页面。这个角色权限控制虽然和后端拦截器有重复但前端先做一层拦截一是交互体验好不用等接口报401才跳登录二是减少非法请求打到后端。6.2 接口统一封装前端axios请求必须统一封装不要每个页面裸用axios.get散落一地。我在utils/request.js里封装如下逻辑const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { ElMessage.error(res.message) return Promise.reject(new Error(res.message)) } return res }, error { if (error.response error.response.status 401) { localStorage.removeItem(token) router.push(/login) } ElMessage.error(网络请求异常) return Promise.reject(error) } )重点说一下baseURL。开发环境通过Vite配置代理把/api转发到后端8081端口这样开发时不会有跨域问题生产环境用Nginx把/api反向代理到后端服务。整个路径链路才是完整的前端请求/api/order/list经过Nginx转到后端/order/list。6.3 表单设计的小经验报修表单是整个系统的高频组件。布局上我建议做成故障类型下拉 地点级联选择 设备编号可模糊搜索 故障描述多行文本 图片上传最多三张 紧急程度单选。这里有两个实用的小设计一个是地点级联要实现校区-教学楼-房间三级联动数据可以后端接口返回也可以用静态常量表维护。既然是校园报修系统地点数据相对固定用静态常量维护即可不用过度设计。另一个是图片预览上传前可以本地预览上传失败时才提示用户不要等整个表单提交才发现图片没传上去。提升体验的关键在于把上传成功返回的URL保存到表单数据里而不是上传后立即提交整个表单。7. 常见问题与排查技巧实录7.1 环境与编译问题速查表问题现象可能原因解决方式项目启动报ClassNotFoundException依赖版本冲突或没引入检查pom.xml中同名依赖使用mvn dependency:tree排查冲突接口访问404Controller未被扫描或请求路径错误确认启动类所在包路径包含所有Controller返回JSON字段为null实体类没加TableField或字段名不匹配检查驼峰映射配置开启map-underscore-to-camel-caseMyBatis-Plus批量插入失败没有配置批量SQL注入器自定义SqlInjector或循环单条插入端口被占用上一次的服务没停干净使用lsof -i:8081查进程并kill掉7.2 业务逻辑类问题我遇到过最经典的业务bug学生在Web端提交报修发票传了图片但维修工在工单详情页看不到图片。排查后才发现我保存图片的时候用的是相对路径而返回前端的是绝对路径到了前端只显示了后半段路径导致没拼上前端域名。这个问题虽然小但暴露了一个规范性问题——后端接口返回的数据结构里所有文件URL必须统一为完整可访问的URL不能在展示层做二次拼接。另一个常见的业务问题是并发接单。两个维修工同时点击同一个待接单工单如果代码逻辑是先查询状态为待接单再更新为已接单就会出问题两人都查询到了待接单状态然后各自更新导致一个工单被两个人接走。解决办法有两种第一种是在工单表加乐观锁版本号更新时带上version字段第二种更简单粗暴用一条带条件的update语句比如UPDATE repair_order SET worker_id?, status1 WHERE id? AND status0返回影响行数如果影响行数为0说明别人已经抢单成功了。7.3 部署上线流程与踩坑服务器的部署我通常按如下步骤操作编译打包执行mvn clean package -DskipTests生成jar包注意如果用了本地文件存储要确认打包不包含上传目录。然后把jar包上传到服务器编写systemd服务文件配置开机自启、日志输出去向。启动时加上JVM参数比如-Xms512m -Xmx1024m防止内存溢出。最后配置Nginx反向代理前端静态文件放到/usr/share/nginx/html接口请求转发到localhost:8081。这里有一个非常大的坑如果用宝兰德或其他替代容器替换Tomcat逻辑上不是简单的换jar包。SpringBoot内嵌Tomcat的替换需要考虑Servlet API版本兼容性、WebSocket支持、JSP支持等问题。但常规SpringBoot应用直接用自带Tomcat以及打jar包方式是主流如果你是内部部署强制要求再单独研究替换方案这里不多展开。还有数据库的时区设置。MySQL连接串一定要带上serverTimezoneAsia/Shanghai否则日期字段会差8小时在工单超时判断的时候差之毫厘谬以千里。另外建议在JVM启动参数里也统一时区-Duser.timezoneAsia/Shanghai双保险。8. 写在最后的个人体会真实的开发过程中做的项目不一定要多宏大把一件事情的完整链路吃透才最重要。校园设备维护报修系统的技术难度不算高但它特别完整从用户需求、角色权限、状态流转、消息通知到前后端分离、部署上线、日志排障包括的问题面非常广。如果你把它认认真真做一遍收获的东西绝对比看一百篇SpringBoot教程要多得多。我自己的经验是做一个项目一定要做笔记把踩过的坑、分析过的原因记录下来。像SpringBoot版本选择、连接池参数配置、定时任务的多实例问题、并发接单的悲催场景这些东西不是一个Hello World级别的教程能带给你的。写这篇博客我也是把之前的零散笔记重新整理了一遍边写边回忆起当时凌晨一两点钟被测试同学喊起来看bug的日子那会儿真的烦躁但也就是在这些烦躁里能力一点点长起来了。最后再分享一个小技巧给你的项目加上一个banner。SpringBoot支持自定义启动banner把启动时的那个Spring图案换成你学校或者项目的Logo加一句口号虽然不影响功能但每次启动都会心情好一点。用现成的Spring Boot Banner生成器在线输入文字就能生成放到src/main/resources/banner.txt里即可这个细节你做完可以发给同学看也是个小彩蛋。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价