ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于SpringBoot+Vue的科创项目管理系统设计与实现

基于SpringBoot+Vue的科创项目管理系统设计与实现 1. 项目概述与整体设计思路1.1 为什么要做科创项目管理系统每年大学生创新创业训练计划简称大创、各类学科竞赛项目的申报、中期检查和结题验收很多高校还在用Excel表格加微信群的方式管理。材料散落在各个老师的电脑里学生不知道项目审核到哪一步了指导老师要反复催交材料教务管理员在汇总时面对几十个格式不统一的Excel表头欲哭无泪。这个痛点我体验过不止一次所以当朋友提出要做一套科创项目管理系统时我几乎没有犹豫就接了下来。这套系统的核心定位很明确解决大学生科创项目从申报、审核、中期检查到结题验收的全流程线上化管理问题。技术栈选择了当下最主流的组合——SpringBoot Vue MyBatis MySQL前后端完全分离。系统上线后学生可以在线提交项目申报书指导老师在线审批教务管理员可以实时查看全校项目的整体进度所有流程节点都有记录可查工作效率提升非常明显。我把这套系统的完整源码和部署过程整理出来适合三类人参考一是正在做毕业设计、需要一套完整前后端分离项目的计算机专业学生二是高校里负责科创项目管理、想推动信息化建设的老师或管理人员三是想系统学习SpringBoot和Vue前后端分离开发实战的开发者。对于前两类人这份资料可以直接拿来用或者二次开发对于第三类人整个项目涵盖了权限认证、文件上传、流程审核、数据统计这些高频业务场景学完能少走很多弯路。1.2 系统核心业务流程拆解在动手写代码之前我先梳理了科创项目管理的完整生命周期。一个典型的科创项目从无到有大致经历以下阶段学生申报、指导老师初审、学院审核、学校教务处终审、立项公布、中期检查、结题验收。不同学校的管理流程会有细微差别但主体的骨架基本一致。这个流程拆解下来系统的核心角色自然就清晰了学生项目负责人和成员、指导老师、学院管理员、学校管理员。每种角色在系统里能看到的内容和能执行的操作完全不同这直接决定了权限模块的设计思路。我采用的方案是基于角色的访问控制模型RBAC即Role-Based Access Control把权限配置到角色上再把角色分配给用户这样新增用户时只要指定角色就能自动获得对应权限管理成本非常低。流程设计上我参考了实际管理中的两个关键场景。第一个场景是校级管理员需要能够灵活配置审核流程。有的学院是两级审核有的是三级审核如果我把流程硬编码在代码里后期调整会非常痛苦。第二个场景是每个项目的状态必须一清二楚学生提交后随时能看到待审核还是已通过避免反复打电话问管理员。基于这两个考虑我设计了一张项目状态机表来维护项目的生命周期状态前端根据状态值渲染不同的标签样式后端通过状态流转规则校验操作的合法性双端配合整个流程就非常顺畅了。2. 技术栈选型与工程结构解析2.1 为什么选SpringBoot而不是SSH早些年做Java Web项目用SSHSpring Struts Hibernate是标配但Struts的配置复杂度让人痛不欲生光是一个XML配置文件就能写几百行。SpringBoot的出现彻底改变了这个局面它把约定大于配置的理念发挥到极致内置了Tomcat很多场景下只需要一个注解就能跑起来一个Web服务。我选择SpringBoot核心原因有三个一是开发效率高省去了大量模板化配置二是生态成熟和MyBatis、Spring Security、JWT这些组件对接都非常顺畅三是招人容易现在Java后端开发几乎都要求SpringBoot经验这套项目学完直接对口就业需求。版本选择上我用了SpringBoot 2.7.x而不是最新的3.x。这里有一个很重要的考量SpringBoot 3.x要求JDK 17及以上JDK版本升级会带来很多兼容性问题而且部分老版本的MyBatis、连接池等依赖在新版本下可能出现奇怪的报错。对于毕业设计和企业实际项目来说稳定压倒一切SpringBoot 2.7 JDK 8是目前兼容性最好的黄金组合。如果读者本地装的是JDK 17甚至21我也不推荐直接换新更稳妥的做法是同时安装多个JDK版本具体切换方法后面部署章节会讲到。2.2 Vue 2还是Vue 3我做了个保守选择前端选型上我最终用了Vue 2 Element UI而不是Vue 3 Element Plus。这个选择可能让一些追求新技术的读者意外但回过头看这个保守决策在实际开发中省了非常多麻烦。原因有几个方面。首先是Element UI对Vue 2的适配非常成熟几乎所有组件都能直接开箱即用网上的踩坑经验也极多遇到问题基本一搜就有答案。而Element Plus在早期版本中存在不少细节问题表格性能、表单校验方面都需要额外处理。其次是若依、vue-element-admin这些成熟的后台管理脚手架都基于Vue 2可以快速借鉴优秀代码写法。第三这套系统面向的最终用户是高校师生浏览器环境多种多样Vue 2在浏览器兼容性上明显优于Vue 3。当然如果读者是纯学习目的或者打算长期维护这套系统完全可以在此基础上迁移到Vue 3 Vite Element Plus整体架构不用大变只需要重写部分组件的生命周期和响应式逻辑。前端框架的选型永远没有绝对正确只有适合当前场景。2.3 MyBatis还是MyBatis-PlusMyBatis作为持久层框架核心价值是让开发者可以用XML或注解的方式灵活编写SQL避免了JDBC的样板代码。它的学习曲线平缓对SQL的控制力很强特别适合业务逻辑复杂、SQL需要手工优化调优的场景。在项目开发中我大量使用了动态SQLif标签、foreach标签配合MyBatis的缓存机制查询性能相当可观。不过如果现在从头开发一个新项目我可能会优先考虑MyBatis-Plus。MyBatis-Plus在MyBatis基础上做了增强提供了通用的Mapper方法单表CRUD不需要手写XML还有分页插件、代码生成器开发效率能再提升30%。在后续的业务迭代里我逐步引入了MyBatis-Plus的Wrapper构造器来实现条件查询确实省去了一堆XML文件的编写。两者并不冲突很多生产项目是混用的最关键的是自己清楚哪些场景用两个框架的哪个能力。MySQL作为底层存储是最稳妥的选择它的事务机制、存储引擎、主从复制能力足以支撑学校级别的并发访问量。这里提醒一句表结构设置utf8mb4字符集、InnoDB存储引擎是所有项目的默认前提千万不要用默认的MyISAM不然事务回滚和行级锁这些能力都用不上。具体设计细节下一节展开。2.4 工程目录结构与代码分层一个好的项目结构是后续可维护性的基础。我沿用了主流的前后端分离开发包管理方式前端和后端分成两个独立目录前端代码放一个仓库后端代码放另一个仓库。本地的运行方式是前端启动Node服务代理请求后端启动SpringBoot服务通过Nginx配置的/api前缀做反向代理这样可以完美绕过开发环境下的跨域问题。后端代码采用标准的Controller-Service-Mapper三层架构。Controller层只负责接收请求参数和返回统一响应结果不写任何业务逻辑Service层处理核心业务逻辑事务控制也在这层Mapper层负责数据库操作。此外config包放各种配置类common包放统一返回结果、异常处理、工具类entity包对应数据库表结构dto包用于接收前端传来的视图对象vo包用于封装返回给前端的数据结构。前端部分则按照vue-element-admin的组织方式src目录下分为api、views、components、router、store、utils、styles等模块。api目录统一管理请求接口每个模块对应一个JS文件views目录是页面级组件按功能模块划分子目录router集中配置路由和路由守卫store用来管理全局共享状态比如用户信息和权限列表。这样的分层设计好处是新人接手时能快速定位功能的代码位置上下文切换成本极低。3. 数据库设计与权限模型3.1 核心数据表设计数据库设计直接决定了系统能够承载的业务边界这套系统我一共设计了11张核心业务表先看最关键的前5张表。为了便于理解我用表格把重点字段列出来。表名字段示例核心用途关键说明userid, username, password, real_name, role_id, college_id, phone, email存储所有系统用户密码经过MD5加盐加密存储不能明文roleid, role_name, role_code, description系统角色定义支持超管、校管理员、学院管理员、指导老师、学生等projectid, project_name, category, leader_id, college_id, status, detail, budget, file_url项目申报主表status字段对应项目状态机project_memberid, project_id, user_id, is_leader, join_time项目成员表一个项目对应多个成员approval_recordid, project_id, approver_id, action, comment, create_time审核记录表记录每一步审核人、动作和意见除此之外还有几张辅助表college表存学院信息notice表存系统公告score表存结题评分file表统一管理上传附件operation_log表记录用户关键操作日志。对于科创管理这种业务日志表非常重要一旦出现项目状态被误改或审核意见丢失的情况日志表就是排查问题的唯一线索。3.2 项目状态机与审核流程设计我强烈建议所有做管理系统的开发者把业务中的状态流转设计成一张独立的状态机表而不是在代码里用魔法值散落着写。这个系统里项目的状态流转我做成了八个节点草稿0、待指导老师审核1、待学院审核2、待学校审核3、已立项4、待中期检查5、待结题验收6、已结题7中间还有被驳回-1和已终止-2两个异常状态。这个状态定义写在哪呢写在Redis缓存里可以写在MySQL配置表里也可以甚至直接在前端定义好枚举值都行但一定要让全系统的状态流转逻辑有一处统一的地方可以查阅和修改。状态流转的规则是指导老师可以驳回状态1的项目学院管理员可以审核状态2的项目学校管理员处理状态3已立项的项目才可以提交中期报告中期检查通过才能提交结题材料。在Service层我封装了一个checkStateTransition(currentState, targetState)方法每次状态变更前都校验一下是否合法非法操作直接抛出业务异常。这个方法看起来不起眼但在实际使用中帮我拦截了大量误操作。3.3 权限模型设计细节权限模型我采用RBAC规范但做了轻量处理用户表直接关联角色表没有引入菜单权限表和按钮权限表因为科创管理系统不需要太细粒度的操作权限控制。如果硬要加菜单权限反而会让前端动态路由的实现复杂很多。角色划分上我用了固定五种角色ADMIN系统管理员、SCHOOL校级管理员、COLLEGE院级管理员、TEACHER指导老师、STUDENT学生。每种角色对项目的操作权限在代码里通过注解控制比如学生端接口统一加上PreAuthorize(hasRole(STUDENT))保证学生只能看到自己创建的项目指导老师接口校验当前用户是否为项目指导老师防止越权操作。前端这边路由守卫会根据本地存储的角色信息动态渲染菜单未登录的用户跳转到登录页。两端的权限控制互为补充前端控制的是显示内容后端才是真正的安全防线。4. 后端核心功能实现4.1 统一响应结果与全局异常处理后端接口设计的第一件事是定义一个统一的返回格式。我采用的是比较标准的RESTful风格所有接口返回Result对象包含三个字段code状态码、message提示信息、data业务数据。200表示成功400表示参数校验失败401表示未登录或token过期403表示无权限500表示服务器内部错误。前端拿到这个格式后统一处理尤其是401和403需要在响应拦截器里做全局跳转否则每个页面都要单独写判断代码冗余度会非常高。全局异常处理是后端开发中极具性价比的一个模块。我用RestControllerAdvice注解配合ExceptionHandler写了一个全局异常处理器捕获自定义的业务异常、参数绑定异常未知异常。这样一来Controller层就不需要写大量的try-catch写业务代码的时候直接抛出异常统一由异常处理器处理代码非常清爽。实际开发中我遇到过印象最深的坑是文件上传时抛出的MaxUploadSizeExceededException如果不做处理前端接收到的错误信息是一大段英文堆栈对用户极不友好加上全局异常处理之后就能转换成文件大小不能超过20MB这样通俗的提示。4.2 JWT认证与登录流程登录认证这块我选了JWTJSON Web Token方案而不是传统的Session方案。前后端分离架构下Session的模式需要处理跨域携带Cookie的问题而JWT把用户信息编码在Token里前端每次请求在请求头加Authorization: Bearer token后端直接解析验证无需在服务端保存会话状态天然适合分布式部署。登录流程的具体实现是用户提交用户名和密码后端用BCryptPasswordEncoder校验密码哈希校验通过后生成JWT TokenToken的有效期设置为24小时里面包含了用户的id、用户名和角色信息。后端写了一个JwtInterceptor拦截器在请求到达Controller之前验证Token的有效性验证通过后把用户信息放入ThreadLocal后续的业务逻辑直接从ThreadLocal取当前用户即可。这里需要注意JWT的密钥要写配置在application.yml里不能硬编码在代码中一旦密钥泄露任何人都可以伪造Token。一个朋友在复用这套系统时问了句JWT过期之后怎么办我给出的方案很简单前端在拦截器里捕获到401响应后跳转到登录页并清理本地存储的用户信息即可。单点登录和Token自动续期属于更高阶的需求科创管理系统并发量不大不需要引入复杂的方案保持简单反而是最大优势。4.3 项目申报与审核的完整实现项目申报是整个系统最核心的交互场景。学生在前端填写项目名称、类型创新训练项目、创业训练项目、创业实践项目、所属学院、指导老师、项目成员、经费预算上传申报书附件点击提交后后端进行字段校验和附件存储然后生成一条状态为1的项目记录。指导老师审核的场景比较有意思。审核列表页需要展示学生提交的项目详情还要展示同一位指导老师名下的所有待审核项目。我用了MyBatis的动态SQL来写这个列表查询通过if标签做条件拼接当传入的参数不同时生成不同的查询语句。在ServiceImpl里我把审核操作设计成了一系列不可分割的操作更新项目状态、记录审核日志、可能发送站内通知。这三步必须放在同一个事务里我用Transactional注解搞定任何一步失败都会整体回滚。学校管理员审核通过之后项目进入已立项状态系统自动给项目负责人的账号发送一条站内消息提醒。到中期检查和结题验收阶段流程逻辑类似。这套审核逻辑写完后我发现代码复用度非常高所有的审核操作都可以抽象成一个统一的处理入口区别仅在于操作类型和前置状态校验不同。4.4 文件上传与存储科创项目申报中免不了要上传申报书、中期报告、结题报告、成果证明等附件。文件存储方案我并没有引入OSS之类的对象存储服务而采用了本地磁盘存储加数据库记录的方式。服务器上建一个/data/upload目录按日期划分子文件夹上传成功后把文件路径保存到file表下载时根据表里的文件路径去服务器读取。这里有几个细节要处理到位。第一上传的接口需要限制文件大小我设置了20MB的上限超过会抛出异常第二文件名要重命名不能直接用用户上传的文件名避免中文文件名和重复文件名带来的问题第三下载接口需要设置Content-Disposition响应头确保浏览器能正确识别文件类型并触发下载行为。我在上传之前用UUID生成文件名把原始文件名存在数据库里下载时再从数据库取出来拼接到响应头中这样既避免了文件名冲突又能保证用户下载到文件名和上传时一致。如果以后文件量特别大可以考虑迁移到MinIO或者阿里云OSS核心业务代码不用改动只需要替换文件存储的服务类实现。4.5 SpringBoot核心配置解析最后把后端配置文件里几个值得注意的点单拎出来说一下。数据源配置上我用了Druid连接池不仅性能可靠还自带了监控页面开发环境可以实时查看SQL执行情况和慢查询统计定位性能问题非常方便。为了便于排查问题我在配置里打开了MyBatis的SQL日志打印这样每一条执行的SQL都会在控制台输出配合id-idea-plugin这样的IDEA插件格式化输出调试SQL时非常舒服。再一个重要的配置是CORS跨域处理。虽然在正式环境用Nginx反向代理之后不存在跨域问题但本地开发时前端项目跑在8080端口后端跑在9090端口两者端口不同必然产生跨域请求。我在后端配置里明确了allowedOrigins为http://localhost:8080allowedMethods为GET、POST、PUT、DELETE、OPTIONS这里有一点常被忽视如果是生产环境线上前端域名变了记得同步修改这个配置否则前端用户会遇到所有请求都报错的情况。5. 前端Vue核心功能实现5.1 前端工程与开发环境搭建前端部分是一个基于Vue 2 Element UI Vuex Vue Router的单页应用。开发环境需要先安装Node.js我建议安装14或16 LTS版本因为Vue 2的依赖和Webpack 4在高版本Node上偶尔会报OpenSSL错误。具体的解决方案我遇到过一次在打包时提示digital envelope routines::unsupported这是因为Node 17以上的版本改用OpenSSL 3导致的解决办法是在package.json的scripts里加一句set NODE_OPTIONS--openssl-legacy-provider不同系统的写法不一样。这一段代码很多人在网上搜过当时我找到这个解决方案时心情堪比救火成功。项目创建用的是Vue CLI 4.x创建命令是vue create frontend手动选择Vue Router、Vuex、ESLint。入口文件main.js中引入Element UI、路由实例、状态管理实例。为了接口调用的统一我把axios封装成了一个request工具模块设置了baseURL、超时时间和请求拦截器自动加上Token请求头、响应拦截器统一处理错误码所有API模块都从这个工具中导出请求方法这是保证前端代码整洁的关键一步。5.2 路由与权限控制的配合前端路由设计核心思路是根据角色生成动态菜单。我把路由分为两部分一部分是静态路由包含登录页、404页、首页等所有角色都能访问的页面另一部分是动态路由包含项目管理、审核管理、系统管理等功能页面这些路由不直接注册而是等用户登录后根据后端返回的角色信息动态添加路由并生成侧边栏菜单。这一块落地的时候有点绕建议第一次写前端路由守卫的同学们先理解一下router.beforeEach的执行时机。我的实现逻辑是用户登录成功后系统把用户信息存到Vuex和localStorage每次路由跳转前路由守卫判断用户是否有登录态。如果有登录态再判断动态路由是否已经添加过用Vuex里的一个标记字段控制。如果是第一次进入系统就根据用户的角色信息调用一个generateRoutes方法动态添加对应权限的路由表并调用router.addRoutes至此完成整个权限路由的装配过程。整个过程看起来长但是一气呵成实际使用体验非常流畅。5.3 核心页面组件拆解项目申报页是学生端最常操作的页面。我把它设计成了一个大表单组件用el-form配合rules做字段校验项目成员编辑用了动态增减的表格行用户点击添加成员按钮时新增一行输入框填写完成员姓名和学号后点击保存前端把整个表单的数据组装成一个JSON对象提交给后端。这里有一个坑是Element UI的日期选择器默认返回格式是Date对象直接提交给后端会报格式不对需要在提交前用qs或者dayjs格式化一遍。我在前端工具模块里写了一个formatDate工具函数统一处理时间格式。项目管理页面是一个包含搜索、筛选、列表、分页的复合页面。顶部是搜索栏支持项目名称、当前状态、学院三个维度的条件组合查询底部是分页表格。表格每一行都有详情、编辑、提交审核、删除等操作按钮根据当前项目的状态动态渲染。比如草稿状态的项目才允许编辑和删除已提交审核的项目只允许查看。这些逻辑通过一个computed属性动态计算当前行的操作权限代码可读性非常好。审核页面面向指导老师和各级管理员核心功能是待办列表加详情弹窗。点击一个待审核项目右侧弹出项目的完整信息面板底部是审核按钮区域。审核时需要填写审核意见必填校验做好。我额外加了一个历史审核记录的时间线组件展示该项目之前所有审核节点的时间和意见审核人与被审核人沟通不畅的问题在这里得到了极大的缓解。5.4 前端性能与打包优化前端性能优化这块我做了三个动作。第一个是按需引入Element UI组件通过babel-plugin-component插件大幅减小打包体积首屏加载速度改善明显。第二个是路由懒加载所有页面组件都用import()动态导入Vue Router会把这些组件自动拆分成单独的JS文件只有访问对应路由时才加载对应资源。第三个是打包配置里设置了productionSourceMap: false防止源代码暴露在浏览器的调试面板中这既是安全要求也减少了部署包体积。构建出来的dist目录是纯静态文件放在Nginx的/usr/share/nginx/html目录下即可。Nginx还需要配置几个关键点单页应用需要配置try_files指令让所有前端路由都回退到index.html避免刷新页面时出现404/api开头的请求反向代理到后端SpringBoot服务端口。这两段配置我写在了Nginx的server块中部署部分会给出完整示例。6. 部署上线全流程6.1 本地运行环境准备本地把项目跑起来环境准备是第一关。需要安装JDK 8、Maven 3.6、MySQL 8.0、Node.js 14。MySQL安装后要手动创建数据库并导入项目的sql/init.sql文件里面包含了建表语句和初始数据。初始数据里有一个超级管理员账号admin/admin123和几个测试账号登录不同的账号可以体验不同的角色权限。后端项目修改application.yml里的数据库连接配置把用户名密码改成自己本地的然后在项目根目录执行mvn spring-boot:run看到SpringBoot启动成功的日志就说明后端OK了。前端项目进入目录执行npm install安装依赖再执行npm run serve启动开发服务器。默认情况下前端跑在8080端口后端跑在9090端口本地开发环境通过vue.config.js里的代理配置解决跨域问题。前后端都启动后浏览器打开http://localhost:8080即可登录系统。这里提醒一下npm install首次执行通常会比较慢如果网络不佳可以配置淘宝镜像源速度会快很多。执行命令是npm config set registry https://registry.npmmirror.com装完依赖之后记得改回来避免后续发布的包版本和官方源不一致。6.2 阿里云服务器部署详细步骤线上部署我选了一台阿里云轻量应用服务器配置是2核4G安装的是CentOS 7.9系统。如果是新买的服务器先要把安全组的入方向规则放开80端口和443端口。系统装好后依次安装JDK、MySQL、Nginx。这几个服务用systemctl命令管理全部设置成开机自启避免服务器重启后服务不自动恢复的情况。部署的核心流程分四步第一步本地把后端项目用Maven打成JAR包生成的文件在target目录下通过scp或者宝塔面板上传到服务器的/app/springboot目录第二步前端项目本地执行npm run build生成dist目录也上传到服务器放在Nginx的网站根目录下第三步配置Nginx核心配置如下server { listen 80; server_name your-domain.com; root /usr/share/nginx/html; index index.html; # 单页应用路由回退 location / { try_files $uri $uri/ /index.html; } # 后端接口反向代理 location /api/ { proxy_pass http://127.0.0.1:9090; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 上传文件访问路径 location /files/ { alias /data/upload/; } }第四步启动后端JAR包。后端服务我用了nohup java -jar xxx.jar app.log 21 的方式启动方便把日志输出到文件里排查问题。也可以把Java服务注册成系统服务用systemd管理支持开机自启和崩溃重启生产环境更推荐后者。安全加固方面有两个细节必须做。第一个是MySQL一定要设置强密码千万不要用默认密码部署完服务器之后可以执行mysql_secure_installation脚本一键完成基础安全设置。第二个是后端服务不要用root用户直接跑单独创建一个普通用户运行Java进程即便Java应用被攻破攻击者拿到的权限也非常有限。6.3 HTTPS证书配置现在的网站如果还是纯HTTP浏览器会直接提示不安全对于学校类的信息管理系统安全形象很重要而且很多功能比如密码修改、文件上传都需要加密传输。我在阿里云上申请了免费的SSL证书下载Nginx版证书后把证书文件传到服务器修改Nginx配置增加443端口的监听核心配置如下server { listen 443 ssl; server_name your-domain.com; ssl_certificate /etc/nginx/cert/your-domain.pem; ssl_certificate_key /etc/nginx/cert/your-domain.key; ssl_protocols TLSv1.2 TLSv1.3; # 同80端口的核心配置 # ... }配置完成后记得把80端口的HTTP请求重定向到HTTPS这样用户不管输入哪个地址都会被引导到安全的访问地址。执行nginx -t检查配置语法确认无误后nginx -s reload让配置生效。如果配置过程中遇到证书加载失败通常是证书文件权限问题执行chmod 400权限设置即可。7. 常见问题与排查技巧7.1 高频问题速查表我把开发过程中遇到过、以及读者反馈过的高频问题整理成一个速查表遇到问题先对照排查大概率能解决。问题现象根本原因解决方案前端请求后端报CORS错误后端未允许前端域名跨域检查CORS配置中的allowedOrigins是否包含前端地址登录成功但访问接口返回401JWT Token未传递或已过期检查请求拦截器是否在请求头加入了Authorization字段数据库中文乱码连接URL未指定字符集在JDBC连接地址中增加characterEncodingutf8useSSLfalse上传文件报超出大小限制默认限制了上传大小SpringBoot配置中设置spring.servlet.multipart.max-file-size20MB打包时提示Node版本不支持Node版本过高与Webpack冲突降级Node 14或设置NODE_OPTIONS--openssl-legacy-provider刷新页面出现404未配置单页应用路由回退Nginx配置try_files $uri $uri/ /index.htmlMyBatis控制台不打印SQL日志级别设置未生效配置mybatis.configuration.log-impl或设置mapper包日志级别为DEBUG日期参数绑定失败前端传了字符串后端没加格式化注解后端字段加JsonFormat(pattern yyyy-MM-dd HH:mm:ss)前端统一格式化7.2 我踩过的三个最深坑第一个坑和MyBatis动态SQL有关。当时写项目列表的分页查询用了if标签拼接查询条件当项目名称条件传入null或者空字符串时拼接出来的SQL会变成WHERE project_name 这种语法错误。排查了很久最后发现是if标签的判断条件写法不够严谨没有排除空字符串的情况。正确写法是if testprojectName ! null and projectName ! 。这个细节所有用过MyBatis动态SQL的人应该都体会过看似简单实际报错的时候让人抓狂。第二个坑是跨库联表查询的性能问题。系统初期把学生信息和项目信息放一个库里数据量小没感觉后来导入了一批历史数据查询项目的列表接口响应突然从300毫秒涨到了3秒。用Druid监控一查问题出在联表查询没有走索引加上项目表的学生外键、学院字段缺少索引全表扫描导致慢查询。解决方法是在外键字段、状态字段、类型字段上一一加上组合索引并把列表页默认只加载最近一年的数据。从那以后所有上线项目我都会提前检查索引设计而不是等慢查询了再去救火。第三个坑和前端部署有关。第一次打包部署后发现用户刷新页面就出404当时第一反应是Nginx配置错了检查了好几遍也没发现问题。后来搜了半天才恍然大悟是单页应用的路由机制导致的前端访问/project/detail时后端Nginx找不到这个路径对应的物理文件自然返回404。解决方案就是刚才部署部分提到的try_files指令。这种问题不实际部署一次光看教程很难理解很多同学本地开发的时候天天点路由从来没有发现过这类问题直到部署上线才突然遇到所以建议所有人在开发阶段就要用npm run build加本地Nginx模拟真实的部署环境。7.3 二次开发与业务扩展建议这套系统目前的业务边界已经覆盖了科创项目管理的核心流程但它仍然有非常大的扩展空间。顺着实际业务往下想首当其冲的是增加校级优秀项目评审模块。目前结题验收只能提交材料和评分但没有实现专家在线打分、答辩现场评分、优秀项目自动推送展示这些场景。如果加上这一块系统的价值会大幅提升。数据统计可视化的维度也值得深化。目前的统计报表只是简单的柱状图如果能把历年项目的立项数量、各学院占比、项目成果转化情况做成多维度的可视化看板对学校管理层的决策会非常有帮助。技术实现上可以用ECharts数据源直接复用现有接口工作量不大。通知模块目前用的是站内消息实际使用中师生更习惯微信和邮箱。可以考虑接入邮件服务和企业微信的Webhook在关键节点审核通过、驳回、中期提醒自动推送通知这样师生就不用总是登录系统查看状态了。技术难度不高价值提升却非常明显这也是我个人认为值得优先做的扩展功能。8. 总结与实际使用体验整个项目的开发周期我用了大概三周从数据库设计、接口开发到前端页面完成再到部署上线每一步都有各自的难点。回过头来盘点这个项目最大的收获并不是某个框架的使用技巧而是对全栈这个词的分量有了真正清晰的认知。后端设计得再好前端对接不顺畅系统就是难用的前端做得再漂亮后端接口响应缓慢用户照样吐槽。让我比较安心的是这套系统的稳定性。上线运行至今没有出现过一次因并发问题导致的服务中断数据库CPU正常情况下占用率不超过10%。每天的访问高峰出现在项目申报截止前三天负载也完全扛得住。这说明对于学校这类事务管理系统2核4G的服务器配置已经绰绰有余真正需要关注的是数据备份和账号安全。在带新手使用这套系统的过程中我发现一个规律能顺利跑通本地环境的人往往能顺利学会整个项目而连环境都搭建不起来的人通常卡在了JDK环境变量配置或者Maven依赖下载上。所以如果是初学者建议先把环境搭建作为第一个目标然后把代码读一遍再动手改一两个小功能最后才算真正掌握了这套系统。这个过程走下来SpringBoot和Vue的实战能力会有一个质的变化。最后分享一个我在实际使用中养成的小习惯每次上线新功能之前都会先在测试环境完整走一遍核心流程包括学生申报、老师审核、管理员通过、财务填报这几个环节全部跑通之后再上生产环境。这个习惯帮我挡掉了至少五次低级错误推荐给所有开发者。如果你在这套系统的基础上做了二次开发遇到了有意思的问题或者做出了好用的新功能欢迎交流我随时愿意和同行探讨。
返回列表