ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

SpringBoot2+Vue3高校物品捐赠管理系统:全栈设计与部署实践

SpringBoot2+Vue3高校物品捐赠管理系统:全栈设计与部署实践 在毕业设计和课程项目里捐赠管理系统这个题材一直不冷门但真正能做到逻辑完整、前后端分离、能直接演示的却不多。这套基于 SpringBoot2 Vue3 MyBatis-Plus MySQL8.0 的 Java Web 高校物品捐赠管理系统正好卡在了教学深度和工程实践之间——它不是一个只跑通 CRUD 的样板而是把用户注册、物品发布、捐赠审核、领取跟踪、公告管理和数据统计这些真实业务流程都串了起来同时自带文档本地跑起来约等于一个真实的校园闲置物品流转平台。这篇内容围绕这个项目源码展开我会先讲清楚技术选型背后的逻辑再拆目录结构和数据库设计然后分别解析后端和前端的核心实现接着给出 MySQL8.0、后端的启动配置和前后端联调的全过程最后把我在实际运行中踩过、补过、优化过的坑整理成一份排查清单。不管你是准备做课设、复习 Java Web 全栈还是想拿一套干净项目改造成自己的作品这篇文章都能让你少走不少弯路。1. 项目定位与技术选型为什么是这套组合1.1 高校物品捐赠管理系统到底解决什么问题先把这个系统的业务内核说清楚。高校里的闲置物品问题其实很典型毕业季成堆的教材和参考书、换宿舍淘汰的台灯和收纳箱、军训完再也不会穿的衣服扔了可惜留着占地方。另一边低年级贫困生和部分有需要的同学又确实存在学习和生活物资上的缺口。传统的捐赠模式靠辅导员通知、线下摆摊、QQ群接龙信息不透明管理成本高且无法追踪物品最终到了谁手里。这个系统做的事情就是把线下业务流程搬到线上注册用户学生或教职工可以发布待捐赠物品也可以浏览和申请领取他人发布的物品管理员负责审核物品信息、审批捐赠申请、管理用户和公告、统计捐赠数据。整个流程用状态字段跟踪——物品从待审核到上架申请记录从待处理到已完成每一步都有迹可循。本质上就是一个小型化的公益物资流转平台只是把场景限定在高校内部角色关系和流程边界都比社会级平台简单得多非常适合学习和二次开发。1.2 SpringBoot2、Vue3、MyBatis-Plus、MySQL8.0 这套组合的选型逻辑很多人拿到项目第一个问题就是为什么是 SpringBoot2不是 SpringBoot3为什么 MyBatis-Plus 而不是 Spring Data JPA先说 SpringBoot2。这个版本虽然已经有了后继者但在国内教学生态、企业存量项目和中间件适配方面2.x 依然是资料最全、最不容易卡壳的版本。SpringBoot2.7 作为 2.x 系列的收官版本既有 2.x 的稳定性又可以相对平滑地向 3.x 迁移思路。做课设、实训项目或者接外包短平快地交付SpringBoot2 意味着遇到任何报错都大概率能在社区找到现成答案。如果你选 SpringBoot3Java 版本要求 17部分老版本 MyBatis-Plus 和连接池也要跟着升级入门门槛直接抬了一截。再说持久层框架。Spring Data JPA 的强项是领域驱动设计和高度封装的仓储模式适合业务实体关系复杂、团队熟悉 DDD 的项目但它的复杂查询、动态条件拼接学习曲线比较陡SQL 失控的时候很难优化。MyBatis-Plus 走的是增强而非替换的路线——单表 CRUD 近乎零 SQL复杂查询可以退回到 XML 写原生 SQL兼顾效率和灵活度。配合 LambdaQueryWrapper代码可读性比拼接字符串高出一大截这也是国内大多数后台管理系统的首选组合。Vue3 这边Composition API 带来的逻辑复用能力和 Vite 的极速冷启动对比 Vue2Webpack 的开发体验完全是两个时代而且 Element Plus、Pinia、Vue Router4 等配套生态已经非常成熟前后端分离项目里根本找不到选 Vue2 的理由。MySQL8.0 的选型几乎不需要讨论。它默认字符集是 utf8mb4可以直接存 emoji窗口函数、公共表表达式这些新特性让统计类 SQL 好写到令人感动JSON 类型的支持也比 5.7 强很多。新项目如果不考虑老服务器兼容性直接上 8.0 就好。另外这套项目没有引入若依这类重量级脚手架而是保持一个相对精简的自有结构目的很明确让你能看懂每一行代码的来龙去脉而不是在一堆自动生成的代码里迷路。2. 系统功能模块与数据库设计先画清楚业务地图2.1 核心功能模块拆解整个系统的功能可以拆成用户端和管理端两条线。用户端普通学生/教职工核心功能包括账号注册与登录、浏览首页推荐的捐赠物品、按分类筛选物品、物品详情查看、发布捐赠物品含上传图片、申请领取某件物品、在个人中心查看自己发布的物品和提交的申请状态、修改个人资料与头像。这个角色主要解决我要捐和我要领两个诉求。管理端管理员核心功能包括后台登录、物品审核通过/驳回、捐赠申请审批确认发放/拒绝、用户管理启用/禁用、物品分类管理、公告发布与维护、捐赠数据统计总数、分类分布、每月捐赠趋势。管理员是业务流程的守门员所有状态流转都经过审核这保证了系统的公信力。值得注意的设计细节是物品本身有审核状态和流转状态两套状态。审核状态控制前台是否可见流转状态控制当前物品是否已经被申请或已发放。如果只用一个 status 字段会出现审核通过但已被申请这种状态叠加的混乱拆成两个字段后逻辑立刻清晰。申请记录则独立成表关联物品和申请用户一个物品同一时间只允许一个未完成的申请这条规则需要在后端写校验逻辑不能只靠前端按钮禁用。2.2 数据库表设计和关键字段说明数据库设计是这个项目里想清楚比写代码更重要的部分我建议表结构至少包含以下六张核心表表名中文含义关键字段说明user用户表id、username、password(BCrypt加密)、real_name、student_no、phone、avatar、role(1普通用户/2管理员)、status、create_timecategory物品分类表id、name、sort、statusdonation_item捐赠物品表id、title、category_id、description、image、owner_id、status(流转)、audit_status(审核)、create_timedonation_record捐赠申请记录表id、item_id、user_id、apply_message、status(待处理/已通过/已拒绝/已完成)、create_time、deal_timenotice公告表id、title、content、publisher_id、create_timesys_config系统配置表id、config_key、config_value如平台名称、捐赠须知设计原则上有几点想特别强调。第一时间字段统一用 datetimeJava 侧对应 LocalDateTime配合 Jackson 的时间格式化配置避免前端拿到一串难看的数字。第二物理外键建议不加。项目规模不大逻辑关联足够删数据时反而更灵活不用顾忌外键约束顺序。第三物品图片用单字段存一个 URL 路径不建子表因为一个物品目前只需要一张主图设计时不要过度泛化。第四删除用户关联数据时用逻辑删除MyBatis-Plus 的 TableLogic比物理删除安全保留捐赠历史的完整记录对后续统计和溯源很重要。2.3 前后端分离项目的标准目录结构目录结构的规范程度直接影响后期维护效率这里给出一套我验证过很顺手的标准布局。后端是典型的 Maven 单模块结构donation-server/ ├── src/main/java/com/xx/donation/ │ ├── common/ # 通用类统一返回结构、状态码、全局异常、常量 │ ├── config/ # 配置类MyBatis-Plus分页、跨域、文件映射 │ ├── controller/ # 控制层 │ ├── service/ # 业务层接口 impl │ ├── mapper/ # MyBatis-Plus Mapper接口 │ ├── entity/ # 数据库实体 │ ├── dto/ # 请求/响应的数据传输对象 │ ├── vo/ # 视图对象如统计报表VO │ └── util/ # 工具类JWT工具、文件上传工具 └── src/main/resources/ ├── mapper/ # MyBatis-Plus XML文件 ├── application.yml └── sql/init.sql前端采用 Vite Vue3 经典结构donation-web/ ├── src/ │ ├── api/ # 按模块拆分的接口请求文件 │ ├── assets/ # 静态资源 │ ├── components/ # 通用组件 │ ├── router/ # 路由配置 │ ├── stores/ # Pinia状态管理 │ ├── views/ # 页面组件admin/ user/ login等 │ ├── utils/request.js # Axios封装 │ ├── App.vue │ └── main.js ├── vite.config.js ├── package.json └── index.html很多初学者会犯的错是把所有 Controller 塞在一个类里、把所有 SQL 写在 Service 层。这套项目坚持了 Controller 只做参数接收和结果返回、Service 只做业务编排、Mapper 只做数据访问的分层原则。这样分的好处是以后想加缓存、加消息队列、换数据库改动的边界都清清楚楚。3. 后端核心实现SpringBoot2 与 MyBatis-Plus 的关键细节3.1 统一返回结构与全局异常处理所有接口风格一致做前后端分离项目第一个要统一的是接口返回格式。如果每个 Controller 返回的数据结构都不一样前端 Axios 封装就无从谈起。这个项目定义了一个泛型类 Result 标准结构是 code、msg、data 三件套。成功返回 Result.success(data)失败返回 Result.error(msg)。code 用什么规则自己定但建议 200 表示成功、500 表示业务异常、401 表示未认证、403 表示无权限和 HTTP 状态码保持语义一致排查问题的时候少一层心智负担。全局异常处理用 RestControllerAdvice 加 ExceptionHandler 实现。这样 Service 层不需要到处 try-catch 再塞错误信息到 Result 里只需要抛出我们自定义的业务异常 BusinessException由全局处理器统一捕获、记录日志并返回。这里有一个很多人忽略的细节参数校验失败Validated的异常会被封装成 MethodArgumentNotValidException默认返回内容非常冗长前端根本没法展示必须在全局异常处理里单独写一个方法把第一条字段错误信息提取出来返回。3.2 登录认证与权限控制JWT 拦截器的轻量方案若依这类框架默认引入 Spring Security整套 filter 链和用户体系绑定较深学习成本不低。考虑到这个项目角色只有用户和管理员权限控制用 JWT HandlerInterceptor 完全够用而且代码量少、逻辑直观。具体流程是登录成功后用用户 id、用户名、角色等信息生成 JWT过期时间建议 24 小时返回给前端前端把 token 存到 localStorage 或 Pinia每次请求在 Authorization 头带上 Bearer token后端注册一个拦截器 WebConfig implements WebMvcConfigurer把登录、注册、获取验证码这些接口加入 excludePathPatterns其余接口全部走 token 校验。拦截器里需要做的事包括解析 token 是否有效、从 token 中取出用户信息放入 ThreadLocal或直接放入 request attribute、把用户信息传给后续业务使用。管理端接口的权限校验通过自定义注解 RequireRole(admin) 配合另一个拦截器实现或者更简单地在拦截器中判断 URL 前缀/admin/**加上角色字段校验。我见过不少项目在拦截器里只校验token 是否有效不校验角色结果普通用户直接调管理端接口这是很严重的安全漏洞。3.3 MyBatis-Plus 标准写法和 Mapper 文件配置难点MyBatis-Plus 在这个项目里承担了绝大部分数据访问工作。继承 BaseMapper 后selectById、selectList、insert、updateById 这些方法直接用复杂条件用 LambdaQueryWrapper 构建比如多条件连查可以用 eq、like、between、orderByDesc 一行一行连接比手写 SQL 动态拼接安全也能避免 SQL 注入。重点说一下两个容易踩坑的配置点。第一是分页插件。MyBatis-Plus 的分页不是引入依赖就能用必须显式注册 MybatisPlusInterceptor 并添加 PaginationInnerInterceptor(DbType.MYSQL)。否则调用 Page 查询时你只会得到一个查全表后内存分页的结果严重场景下是 SQL 把所有数据查出来再手动截断数据量一大直接拖垮数据库。第二是 XML 与 Mapper 接口放在同一个文件夹下的配置问题。默认约定是 XML 放在 resources/mapper 目录但如果项目规范要求把 XML 和 Mapper 接口放在一起比如 com/xx/donation/mapper 下就必须在 application.yml 配置 mapper-locations 指向 classpath*:com/xx/donation/mapper/*.xml同时在 pom.xml 里把 src/main/java 目录下的 XML 文件也打包进最终的 jarbuild resources resource directorysrc/main/java/directory includes include**/*.xml/include /includes /resource resource directorysrc/main/resources/directory /resource /resources /build这个坑的典型表现是开发环境 Idea 里跑得好好的一打包部署就报 Invalid bound statement (not found)。根本原因就是 jar 包里根本没有那个 XML 文件。另外自动填充创建时间的 MetaObjectHandler 也要配置insert 时自动 set createTimeupdate 时自动 set updateTime业务代码里就不用天天写这两个字段了。3.4 文件上传与静态资源映射捐赠物品需要上传图片头像也需要支持更换。图片文件的存取是这个项目里比较工程化的一块。方案是本地存储后端接收 MultipartFile校验文件大小建议限制 5MB和扩展名jpg、png、webp用 UUID 生成新文件名避免重名和路径穿越然后保存到一个可配置的目录比如 application.yml 里的 upload.path 指向 ./upload。关键步骤是 WebMvcConfigurer 里添加虚拟路径映射Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceHandler(uploadPath /); }这样前端的图片 URL 可以直接拼成http://localhost:8080/upload/xxx.jpg后端只需要暴露这个虚拟路径不用额外写一个下载图片的 Controller。生产环境下如果部署到云服务器upload.path改成绝对路径即可如果以后要上对象存储改这一个配置类就能平移到 MinIO 或 OSS这是这个设计的便利之处。4. 前端核心实现Vue3 Vite 的工程化落地4.1 Vue3 项目搭建与依赖安装前端工程用 Vite 创建命令是npm create vitelatest donation-web -- --template vue。如果团队用 TypeScript选vue-ts模板但这个项目我建议先用 JavaScript减少类型报错对初学者的干扰。装依赖的时候有个实际经验Node 版本太新时部分旧版本 Vite 和依赖会报ERESOLVE unable to resolve dependency tree这时候别急着重装系统执行npm install --legacy-peer-deps跳过严格依赖校验即可。项目需要引入的依赖包括vue-router路由、pinia状态管理、axiosHTTP、element-plusUI 组件库、element-plus/icons-vue图标、sass样式预处理。Element Plus 在这个项目里建议直接全量引入虽然打包体积大一点但省去按需自动导入的插件配置对课设和中小项目来说性价比很高。全量引入只需在 main.js 里三行代码import ElementPlus from element-plus import element-plus/dist/index.css app.use(ElementPlus)4.2 Axios 请求封装与 JWT 注入前端所有接口请求在 utils/request.js 中统一封装。核心逻辑包括创建 axios 实例并设置 baseURL、请求拦截器读取 localStorage 中的 token 并写入请求头、响应拦截器统一处理业务状态码。响应拦截器的处理是这个项目的精髓——后端返回的 code 如果等于 401说明登录过期前端直接清空本地登录态并跳转登录页code 不等于 200 时用 Element Plus 的 ElMessage 弹出错误信息不需要每个页面重复写 try-catch 的差异化处理。开发环境下baseURL 和跨域问题用 Vite 代理解决。在 vite.config.js 里配置server: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } }这样前端请求地址写成/api/donation/list开发时由 Vite 代理转发到后端完美规避开发阶段的 CORS 问题。后端如果设置了跨域配置类生产环境用 Nginx 反代时同样作用有限所以这里建议开发用 Vite 代理生产用 Nginx 统一入口后端不要开放全局跨域能少很多安全风险。4.3 核心页面与组件写法从登录到数据看板登录页面是整个系统的门面除了表单校验视觉上可以用 CSS 画一个渐变动画背景增加演示时的第一印象。登录表单提交后调用登录接口成功后把 token 和用户信息写入 Pinia 并跳转到首页。物品列表页是整个系统交互最密集的地方。推荐用 Card 响应式 Grid 布局展示物品卡片每张卡片显示缩略图、标题、物品分类和捐赠人昵称。点击卡片进入详情页详情页展示大图、物品描述和申请领取按钮。这个页面的数据加载逻辑要注意物品列表接口返回的是物品信息和发布人昵称的拼接数据可以在后端用 VO 对象组装避免前端拿到数据后还要遍历关联查询否则页面渲染时会因为异步嵌套产生大量重复请求。管理后台的统计页用 ECharts 做可视化月捐赠趋势用折线图、分类占比用饼图。ECharts 和 Vue3 集成没有官方组件直接封装一个 ChartBox 组件通过 ref 拿到 DOM 实例后初始化在 onBeforeUnmount 里销毁实例防止内存泄漏。使用 Vue3 组合式 API 时有一个个人经验涉及定时器、图表实例、事件监听等需要清理的副作用一定要记得 onBeforeUnmount 清理。否则在 route 切换时会出现图表还挂在旧页面这种幽灵问题。Element Plus 的 Tabs 标签页样式定制也比较常见比如改变活动标签的下划线颜色和字体色要用 CSS 变量覆盖方式比如--el-color-primary这是这个项目贴合实际需求的典型细节。4.4 路由守卫与角色权限控制前端路由需要和后端权限角色配合否则会出现页面能进接口被拒的割裂体验。路由表分为公开路由登录页、注册页、首页部分内容和需要登录的路由以及管理端专属路由带有 meta.role admin。全局前置守卫 beforeEach 里有三个判断顺序访问的页面是否需要登录通过 meta.requiresAuth 判断未登录则跳转登录页并携带 redirect 参数登录后自动跳回原目标页已登录但访问了超出角色权限的页面管理员单独拥有 /admin 前缀下的路由无权限则跳转到 403 页面或首页这套逻辑配合后端的 RequireRole 双保险就能做到前端控制入口后端保证安全。另外不要把用户角色只存储在前端 localStorage 里就高枕无忧——角色信息同样可以通过后端接口获取每次刷新页面后用 Pinia 重新拉取用户信息避免用户改了 localStorage 越权访问。5. 环境搭建MySQL8.0 安装、后端配置与前后端联调5.1 MySQL8.0 安装与初始化Windows 和 Docker 两个方案本地调试 MySQL8.0 最省事的方式是 Docker 一行命令跑起来docker run -d --name mysql8 \ -e MYSQL_ROOT_PASSWORDroot123456 \ -e MYSQL_DATABASEdonation_db \ -p 3306:3306 \ mysql:8.0如果是 Windows 且没有 Docker 环境就下载 MySQL Installer 安装安装过程中选择 Server only 即可配置类型选 Development Machine 减少内存占用。安装完成后有个常见卡点默认 root 用户只允许 localhost 登录如果后续想用 Navicat 从外部连接需要执行授权命令ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY root123456; FLUSH PRIVILEGES;MySQL8.0 默认认证插件是 caching_sha2_password比较新的驱动和客户端都支持但如果遇到连接报错 Unable to load authentication plugin caching_sha2_password就用上面的命令切回 mysql_native_password。初始化数据库时直接把项目里 sql 目录下的 init.sql 导入注意指定编码mysql -u root -p --default-character-setutf8mb4 init.sql5.2 后端核心配置与启动步骤后端启动前只需改一个配置文件 application.yml。核心配置如下server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/donation_db?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: root password: root123456 mybatis-plus: mapper-locations: classpath*:mapper/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0这里的 url 参数是我反复强调的重点serverTimezone 不设会报时区错误useSSLfalse 是避免本地连接时的 SSL 警告allowPublicKeyRetrievaltrue 是为了适配 mysql_native_password 认证过程characterEncodingutf8mb4 是保证 emoji 和生僻字能正常存储。四个参数少一个都可能遇到诡异的坑建议直接照抄。mybatis-plus 配置中map-underscore-to-camel-case 实现下划线转驼峰这样数据库的 create_time 字段能自动映射到 Java 的 createTime 属性logic-delete-field 指定逻辑删除字段StdOutImpl 是开发时打印 SQL 的关键配置调试 SQL 没有它寸步难行。改完配置后启动主启动类看到端口 8080 的日志输出就完成了。5.3 前端启动与联调流程前端启动流程一般是 npm install npm run dev。接下来是联调阶段的重点检查清单登录页输入正确账号密码检查 Network 面板是否请求了/api/user/login登录成功后浏览器 Application 面板确认 token 是否写入 localStorage刷新页面看是否有请求发送 401确认拦截器是否放行了受保护接口提交一件新的捐赠物品确认图片能上传成功、列表页能显示新物品用管理员账号登录审核该物品然后切换到普通用户视角确认物品状态变化整个联调过程中前端页面卡住不动时先按 F12 打开 Network 和 Console看是网络错误、接口报错还是 JS 逻辑异常。后端接口报错时重点看后端控制台输出的 SQL 日志大多数 500 错误都是 SQL 字段匹配问题。前后端分离项目出现跨域报错时先确认是不是发了 OPTIONS 预检请求、后端是否允许了对应请求头。6. 常见问题与排查技巧实录实测中踩过的坑6.1 MyBatis-Plus 相关高频问题分页失效。现象是分页返回了所有数据Page 对象 total 是 0。原因是缺少分页插件配置MyBatis-Plus 默认只是内存分页添加 MybatisPlusInterceptor 后问题立刻消失。逻辑删除导致唯一索引冲突。如果 user 表的 username 字段建了唯一索引用户删除后再次注册同名账号会因为旧记录的 deleted 字段是 1 而和旧记录冲突。解法有两种唯一索引改成 (username, deleted) 联合索引或者删除时在 username 后追加#deleted_删除时间后缀。LambdaQueryWrapper 条件失效。比如 eq(user::getId, null) 时 MyBatis-Plus 会忽略这个条件查询结果和预期不符。这其实是合理行为但新手排查时容易懵遇到条件可能为空的场景用condition重载方法显式控制new LambdaQueryWrapperUser() .eq(StringUtils.isNotBlank(username), User::getUsername, username)6.2 前后端联调与鉴权问题CORS 跨域报错。开发阶段优先使用 Vite 代理而不是后端加 CrossOrigin 全局放开。后端全放开跨域之后生产环境和 Nginx 反向代理配置会出现更多问题而且非白名单来源也可以调用接口留有安全隐患。401 vs 403 的语义混乱。前端拦截器把 401 当成未登录但后端如果权限不足也返回 401就会出现已登录但跳回登录页的怪现象。建议后端按这个口径执行token 缺失或过期统一返回 401登录但无权限返回 403。前端对 401 处理为清空登录态跳转登录页403 则提示无权限访问两者不要混用。页面刷新后 Vuex/Pinia 状态丢失。解决办法是把用户信息和 token 持久化到 localStorage刷新页面后重新从存储中恢复。不要在刷新后重新调用获取用户信息接口除非接口响应足够快。6.3 数据库时区、编码与驱动兼容问题MySQL8.0 连接报错 Server returns invalid timezone 时是因为驱动和服务器时区不一致在 url 后加 serverTimezoneAsia/Shanghai 即可。本地数据库报错 Unknown character set: utf8mb4 大概率是 MySQL 版本低于 5.5.3升级到 8.0 就没有这种问题。驱动包方面SpringBoot2.7 默认引入的 mysql-connector-j 是 8.0.x驱动类名必须是 com.mysql.cj.jdbc.Driver如果看到 com.mysql.jdbc.Driver 的旧写法一并替换成新版。6.4 启动部署与构建阶段的其他问题前端执行 npm install 失败时优先检查 Node 版本和 npm 源。可以使用nvm管理多个 Node 版本将版本切换到 Vite 官方推荐的 LTS 版本或者使用国内镜像源。后端打成 jar 包运行时需要注意 XML 是否已被打进 jar。检查方法是在 jar 所在目录执行jar tf 你的jar包.jar | grep .xml如果发现 XML 缺失按照前面 pom.xml 的配置补 resource 即可。还有一个很容易被忽略的问题开发环境和生产环境的文件上传路径不一致开发时配置的是相对路径 ./upload部署后用 systemd 或 shell 脚本启动时当前工作目录可能不同导致图片上传后找不到目录。建议在配置中使用绝对路径并确保目录存在且有写权限。启动顺序也值得强调先确保 MySQL 服务正常、初始化 SQL 已导入再启动后端最后启动前端。如果 MySQL 还没就绪时后端先启动SpringBoot 默认不会重启数据源需要手动重启应用。Docker 场景下建议加 healthcheck 或者让后端启动时依赖 MySQL 服务健康状态。这个项目还可以怎么扩展文章最后聊一点个人经验。把这个系统跑通之后我建议你沿着几个方向继续折腾每一块都能让简历和项目经验再厚一点第一检索能力升级——目前物品搜索是基于 MySQL 的 LIKE 模糊查询数据量上来后性能堪忧可以引入 Elasticsearch 8 做全文检索同时把 MySQL 中的数据通过定时任务同步到 ES第二可视化大屏——管理后台目前的统计页是静态图表可以做成大屏模式轮播展示实时捐赠数据和分类对比第三消息通知——申请通过、物品被领取等关键节点通过邮件或微信模板消息通知用户把系统从被动查询变成主动触达第四部署自动化——把前后端分别做成 Docker 镜像用 docker-compose 一键拉起 MySQL、后端、前端三个容器这也是企业里最常见的部署形态。坚持把基础项目做完整、做深入远比换个标题换套代码更有价值。这套高校物品捐赠管理系统源码的架构和代码质量都在线但真正的加分项是你对它每一行代码的理解和在此基础上实现的增量功能。祝开发顺利。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进