首页 / 资讯中心 / 文章详情

Spring Boot+Vue进销存系统实战:从需求拆解到部署避坑

Spring Boot+Vue进销存系统实战:从需求拆解到部署避坑 ★ FEATURED ARTICLE
先说一个我在毕业设计辅导里经常遇到的现象很多同学拿到“基于SpringbootVue的乡镇卫生所医用物资进销存系统”这个题目后第一反应是去搜源码、找模板然后发现搜到的项目要么跑不起来要么根本看不懂更别提写进论文里。原因很简单进销存听起来像是个管理系统但真正落地的时候涉及库存、出入库、报表、权限一整套联动逻辑不是堆几个CRUD就能糊弄过去的。这篇就结合我做过的一个医学实验室定制项目把这类系统的需求拆解、技术选型、核心实现和部署排查都捋一遍希望帮正在做类似题目或刚接触前后端分离项目的你少踩点坑。先说清楚这篇文章不是卖源码也不教你怎么改个登录页就交差。它帮助你把这类系统真正吃透知道字段为什么这么设计接口为什么这么写库存逻辑为什么要考虑并发以及真要部署到一台服务器上时该怎么做。所有内容都以Spring Boot 2.x Vue 2.x Element UI这套主流组合为例既贴近现实项目也符合大多数高校的毕设要求。如果你已经工作想快速了解药品耗材类进销存系统的设计要点这篇同样可以当快速入门的参考。1. 项目概述与需求拆解1.1 这类系统到底在解决什么问题乡镇卫生所和城市三甲医院有一个显著区别它没有庞大的仓储部门和专业的信息科很多药品和医用耗材的管理仍然依赖手工台账或Excel表格。进货单是一张纸出库记录是另一个本子盘点时对着电脑屏幕核对半天批号和效期的管理基本靠人肉记忆。等到月底想统计一下这个月某类耗材用了多少、还剩多少、哪些快过期往往要花掉半天时间结果还不一定准确。这个系统的核心价值就是把这套手工流程数字化的同时把进销存逻辑做成强约束。所谓进销存拆开看就是三个动作采购入库、领用出库、库存盘点。乡镇卫生所版本的“销售”通常不是面对患者收银而是科室领用、已做项目的耗材消耗、或者对上级机构的调拨所以出库类型的建模要稍微灵活一点。另外医用物资比普通商品多两个关键维度一个叫批号一个叫效期这两个字段直接决定物资能不能用、安不安全库存表里必须有不能省。1.2 为什么选Spring Boot Vue这套组合技术选型不是选最贵的而是选最合适的。Spring Boot和Vue的组合在近几年的毕设和中小型项目中几乎成了事实标准原因有三。第一Spring Boot极大降低了Spring配置成本你不用再面对一堆XML文件一个注解就能把应用跑起来。同时它的Spring Security、MyBatis、Druid这些周边生态都非常成熟代码示例一搜一大把遇到问题有大量现成方案可抄。第二Vue作为前端框架响应式机制很直观配合Element UI可以直接拼出界面后端开发同学也能在短时间内上手。更重要的是前后端分离模式下前端只调接口、后端只出接口职责边界清楚对需要写论文的同学来说系统架构图都能画得比别人清晰。第三这类组合对部署环境的要求很宽容。后端打成一个jar包前端构建成静态资源扔进Nginx或者直接把dist目录放在Spring Boot的static下都能跑。乡镇卫生所使用的老旧电脑也不至于带不动。2. 核心功能模块与数据库建模2.1 功能模块要考虑哪些人和哪些事做系统设计的第一步不是画界面而是把角色和业务流程理清。一个乡镇卫生所的医疗器械物资管理系统最基本的用户类型有这几种系统管理员、库管员、普通医护人员领用人如果做细一点还可以加一个“院长或统计员”这样的只读角色。不同角色能看到和操作的模块不一样。从业务模块来看大概需要这几个板用户管理、供应商管理、物资档案管理、仓库管理入库/出库/盘点、库存预警与效期管理、统计报表。这里面重点说一下台账和明细的关系。在做进销存系统时入库单、出库单这类“主表”记录的是单据的整体信息比如单号、经办人、入库时间、备注、供应商或领用科室回到代码层面来看其实就是一主多从的关系设计一个主表入库单id对应多条物资明细。领取科室信息、保存单据的操作者、单据类型等都属于主表字段明细表才关联到具体物资。至于库存预警分为数量下限和效期两件事。数量预警简单某类物资当前库存低于预设阈值就标红效期预警则是判断某个批次的物资距离到期日还有多少天低于一个设定值比如30天就要提示尽快处理。这里需要注意的是预警不是定时任务才能做也可以在一次库存查询或者登录后加载首页时顺手把预警数据算出来对毕设来说这种实时计算的方案更直观论文里也好解释。2.2 数据库表的设计思路与关键字段数据库设计是进销存系统的地基。我见过太多人一上来就建表做到库存扣减的时候发现字段不够用又回头改表来回折腾好几次。这里直接给一套比较稳妥的建表思路。第一张是用户表。关键字段包括id、用户名登录账号、密码加密存储、姓名、角色类型、创建时间。不要用明文存密码这个必须提醒。第二张是物资表这块要给的信息比较多物资名称、物资编号、分类、规格型号、单位、生产厂家、批号、效期存储采购时更新的或作为默认值、预警库存下限、当前库存量。注意实际库存推荐单独建表因为物资的库存状态和基础档案的属性应该分离不然查一次物资还得关联一大串冗余。但毕设为了方便也可以直接在物资表上维护一个stock字段我建议至少做成单独的库存表字段包含库存ID、物资ID、总数量、药库ID、更新时间。第三类是单据主表和明细表入库单主表字段有入库单号、供应商ID、入库日期、经办人ID、状态、备注入库明细表字段是明细ID、入库单ID、物资ID、批号、效期、生产日期、采购单价、采购数量出库单主表字段包含出库单号、领用科室或领用人、出库日期、操作人ID、状态、备注出库明细表字段是明细ID、出库单ID、物资ID、批号、效期、出库数量、销售或调拨单价。在字段类型上要注意小数和数量用decimal不用float。库存运算如果用float很容易出现0.99999这种诡异值入库单号和出库单号可以用年月日加随机数生成比如RK20250101001保证可读性和唯一性。表之间的外键关系建议在Service层维护不在数据库里强行建一堆物理外键这样删除和修改都会灵活很多。最终表结构的质量直接决定了后面代码的复杂程度和能不能顺利通过答辩。3. 后端工程结构与核心业务逻辑实现3.1 工程目录结构和基础环境搭建后端工程建议用Maven管理依赖Spring Initializr生成基础工程。包结构按controller、service、mapper、entity、config、common公共返回类或工具类来分包。Controller里面只做参数接收和返回结果封装不写业务逻辑Service里写具体的业务判断Mapper层用MyBatis注解或XML写SQL。这样分层的好处是代码看着清爽排查问题的时候也容易定位是哪个环节出了问题。基础依赖方面pom.xml里需要引入spring-boot-starter-web、mybatis-spring-boot-starter、mysql-connector-java、lombok减少实体类样板代码、druid连接池、jwt或spring-security相关依赖做登录鉴权。注意Spring Boot 2.x兼容的是JDK 8或JDK 11如果你的电脑装的JDK 17需要改Sprng Boot版本或者降级JDK很多同学项目起不来都是这个原因。基础环境搭好后application.yml里需要配好几项内容数据源URL、用户名、密码、MyBatis的mapper扫描路径、端口号。配置时连接数据库的用户名密码务必要跟本机相一致。如果遇到中文乱码问题数据库连接URL后拼上characterEncodingutf8及serverTimezoneAsia/Shanghai即可。3.2 登录鉴权与用户权限控制登录这块不要做得太复杂但也不能完全没有。大多数毕设级别项目使用JWT做Token鉴权是性价比较高的方案。流程是用户在登录页输入账号密码后端先根据用户名查出用户用MD5或BCrypt校验密码校验通过后生成一段Token里面包含用户id、用户名、角色类型、过期时间返回给前端。前端拿到Token后存在localStorage里之后每次请求在拦截器里带上Authorization请求头。后端用一个拦截器或过滤器验证Token是否合法、是否过期如果不合法则返回未登录状态的错误码。权限控制落实到菜单和按钮层面。菜单根据角色动态生成容易实现后端在返回用户信息时同时返回该角色能访问的菜单列表前端根据这个列表渲染路由。按钮级别比如只有管理员能删除物资、库管员才能做入库出库操作可以在前端v-if判断也可以在后端用Spring Security注解做二次拦截。我个人建议前端先挡一层后端再做校验否则懂点技术的人直接调接口就能越权操作。3.3 入库、出库和库存联动进入正题这是进销存系统的灵魂也是最容易出逻辑bug的地方。入库操作的业务流程里前端提交一个表单包含供应商信息及入库物资明细列表。后端在Service层需要做两件事第一生成主单ID和入库单号保存入库主表记录再批量保存明细子表记录第二遍历明细表逐条更新对应物资的库存表检查该批次的物资是否已有库存记录如果存在则累加数量没有则创建一条。插入的这些操作要放在同一个事务里通过注解Transactional在类或方法上加保证原子性避免主单保存成功但库存更新失败脏数据产生。出库操作比入库复杂的地方在于校验。出库时不仅需要判断当前物资的库存总数是否充足还要考虑批次效期原则上临近效期的批次优先出库先入先出最接近实践。但乡镇卫生所业务量不大通常不会做复杂的批次分配只需要按入库批次里的效期时间排序优先出库最早的批次即可。同时如果出库数量超过了库存前端直接提示不能提交后端也要校验一次防止别人跳过前端直接调接口这也是我上面说的“后端再拦截一次”。库存查询接口里要完成三个动作某一种物资当前总库存、该物资的所有批次明细含效期、低于阈值的预警列表。这里优质实践是尽量用SQL做聚合统计查询一个库存表并按物资分组返回总数量再把低库存的物资单独查询出来。与此同时物资效期预警要换算当前日期与效期之间的天数差小于30天的单独标记出来。这一部分建议在实体类里加一个显示字段专门用来接收天数差值方便前端做展示。3.4 报表统计怎么设计才能兼顾查询速度和展示效果报表模块通常是这类型系统的亮点能出图就比单纯表格好看很多。技术上可以使用后端统计接口返回数据给前端再配合ECharts图表展示。采购入库报表按日期范围分组统计采购总金额科室领用报表按科室或领用人分组统计领用总数量、总金额库存结构报表按物资分类统计当前库存的金额占比。SQL语句需要重点掌握日期范围条件的写法与group by的配合使用统计类SQL比单纯的列表查询复杂些要多测试几个边界条件。另外要注意报表查询往往需要按日期筛选接收参数时建议前端传入开始日期和结束日期后端用LocalDate类型接收再在SQL中做范围判断即可不要自己拼接字符串否则很容易踩格式化或注入的坑。这里提醒一点如果你对SQL不熟分组统计时select后面出现的字段要么在group by里要么是聚合函数如sum、count、max这是SQL语法规则绕不过去。遇到“字段在select列表中但不是group by子句”的报错原因就是这里。4. 前端工程搭建与页面交互4.1 Vue工程初始化、路由与请求封装前端工程推荐Vue 2.x Element UI组合用vue-cli快速初始化一个项目。src目录下建议分成views页面级组件、components公共或子组件、router路由配置、api接口请求列表、utils如request.js封装、store可选Vuex或Pinia用于存储用户信息、Token等。路由配置需要区分静态路由和动态路由。静态路由包括登录页、404页动态路由是登录后根据用户角色返回的页面。典型页面划分是首页仪表盘、物资管理列表页新增/编辑页、入库管理入库单列表添加入库单、出库管理、库存查询与预警、统计报表、用户管理、供应商管理。每个页面对应一个vue文件路由的path和组件映射要一一对应如果组件路径写错会在控制台报错并显示空白页面排查时先看路由文件和views文件名是否一致。请求封装使用Axios实例配置baseURL指向后端接口地址注意在后端接口统一前缀再写路径否则部署时改路径会非常痛苦。利用Axios的请求拦截器自动从localStorage取Token并加到请求头响应拦截器中统一处理返回状态。需要特别注意加载数据时注意异步回调顺序不要在数据还没返回时就去读取this.list并试图赋值页面就会偶发报错。4.2 核心页面与交互细节登录页是门面长得丑很影响第一印象。表单校验至少要有账号非空、密码非空和长度校验提交按钮带loading状态防止重复提交。登录成功后不要把整个用户对象存本地只存Token和必要的用户信息用户名、角色即可。物资管理列表页用表格组件展示配合分页、搜索、操作列。搜索条件通常包含物资名称、分类、是否预警这几个维度。新增或编辑物资用对话框表单校验时数量必填且须大于等于0分类建议用固定字典或者从基础数据里查询不要让用户随手填文本。入库和出库单的添加页面是整个前端的重头戏推荐采用主表和明细表同时编辑的模式。页面顶部是单据基本信息供应商或领用科室、日期、备注下方是明细表格由用户点击“增加一行”来动态添加待入库或待出库物资。添加时通过下拉框选择物资选择完毕后自动带出单位、规格、批号、效期等只读信息用户只需要填数量。使用Element的Table组件时动态增删行需要维护一个明细数组变量注意数组的索引和表格行的绑定关系删除行时如果绑定index没处理好经常会出现删错行的诡异情况。库存查询页面除了表格展示还要配合进度条或状态标签把低库存和近效期的物资标红或打上警示标签。报表页面用ECharts做柱状图代表各科室领用数量饼图代表库存金额占比。这里需要提醒ECharts初始化时DOM容器必须已经渲染完成通常在mounted生命周期里执行初始化是安全的。4.3 前后端联调时最容易翻车的3个点联调就是考验接口约定的时候前端工程师觉得前端没错后端工程师觉得后端没错结果前端对不上是最常见的情况。根据我自己的经验最容易出问题的有这么几个点。第一跨域。本地开发时前端跑8080端口、后端跑8081端口浏览器会有跨域限制。解决办法是在后端加一个CORS配置类允许指定的前端地址跨域访问或者通过Vue的devServer proxy把请求转发到后端地址推荐用后端CORS配置最简单直接。第二接口路径或参数名不一致。前端代码里写的是axios.post(/api/user/login, { username, password })后端Controller映射的地址没有加/api前缀参数名也不是username而是account这就会一直报404或参数接收不到。强烈建议在开始写前端前先用Swagger或Postman把后端每个接口测通再让前端对接。第三数据类型和结构不一致。后端返回的日期字段是LocalDateTime序列化后可能是一长串数字前端需要指定日期格式或后端返回时直接格式化为字符串否则前端就显示一个莫名其妙的数字。返回的id如果是Long类型前端在JavaScript中处理精度也会出问题建议后端统一返回String类型或前端用字符串解析方式绕过精度问题。5. 部署流程与常见问题排查实录5.1 从本机环境到正式部署的完整流程我第一次带一个同学部署这类系统时从头到尾走了一遍。当前后端联调结束准备部署到服务器上做演示或给卫生所试用时大致步骤如下。先在服务器安装MySQL 5.7以上版本和JDK 1.8配置好Java环境变量。JDK装完之后在命令行输入java -version如果提示没有这个命令说明环境变量没配好或没有重开终端。然后把本地的数据库导出成SQL文件放到服务器上执行导入。建库语句和本地保持一致否则后端配置的数据源和服务器数据库对不上接口会全部报500或数据库连接异常。后端打包时需要确保application.yml文件的数据库地址改成服务器地址不要把localhost当成服务器否则就算代码部署上去了也连不上数据库。然后在项目根目录执行mvn clean package生成target文件夹下的jar包用java -jar命令后台运行并提供日志输出重定向到某个文件里。前端执行npm run build生成dist目录把它放到Nginx的html目录下然后在Nginx配置文件里设置监听端口与根目录指向配置反向代理把/api开头的请求转发到后端jar端口。其中server_name可以用localhost也可以写服务器IP将location /api节点与proxy_pass配置正确即可。所有静态资源和页面都由Nginx返回后端只负责处理接口请求这样结构和日常实践一致答辩时也说得清楚。部署完成后有个细节如果你用的是阿里云、腾讯云这类云服务器一定要在安全组里放行前端端口不然浏览器访问不了。包括后端端口外网无法访问时优先排查它不要老怀疑代码问题。5.2 常见报错整理与速查表这类项目报错来来去去就那么几个下面这张表是我整理的实操速查出现同样错误可以直接按顺序排查。报错或异常现象可能原因解决方向数据库连接失败URL写错、密码不对、服务没启动、端口被占用检查服务状态、核对配置、使用客户端工具先连一次接口报404路径不一致或Controller没扫描到检查RequestMapping与Method映射确认包扫描范围登录后Token失效或没有权限JWT密钥不一致、过期时间太短、拦截器放行路径没配统一密钥检查Token解析逻辑和放行规则前端页面空白路由配置错误或组件名称不匹配查看控制台报错依次检查router表项与views目录Maven依赖下载不下来网络问题、仓库源配置不对把仓库源换成国内镜像重启IDEA强制刷新依赖nginx转发后端失败proxy_pass配置的地址不对或后端没启动先直接访问后端地址确认再检查Nginx配置另外要说的一个典型坑是本地跑得好好的部署到服务器就登录不上了。这种情况先看服务器时区和本机时区是否一致如果数据库服务器时钟和Web服务器时钟差太多JWT的过期校验就会出问题。解决办法是调统一系统时间和时区。5.3 数据安全与备份的实操建议卫生所使用的系统和普通的管理系统有一点不同它涉及药品耗材数据万一数据丢失或出现库存混乱补起来会非常麻烦。所以除了功能开发我还是建议做一个简单的备份方案。最低成本的做法是写一个脚本在每天凌晨固定时间执行mysqldump命令把数据库导出成SQL文件保存到另一个目录同时保留最近七天的备份超过期限的自动删除。就一段十几行的批处理脚本或linux的crontab任务就能搞定但能避免灾难情况发生是值得写进论文里的一个亮点。再谈一谈库存盘点。手工盘点之后需要把实际盘到的数量录入系统同时修正库存表中的字段。对于盘盈或盘亏的情况需要一个调整类型例如“盘盈入库”“盘亏出库”在出入库类型中要提前预留这个值。不预留的话做盘点时只能硬编码比较难看。6. 论文答辩与项目扩展的个人建议6.1 这类项目在答辩时老师最爱问哪些问题每年到答辩季总有学生慌慌张张来问我“老师会问什么”。结合我带过的模拟项目和同行反馈针对这个题目大概会有这么几类问题需要提前准备。一是为什么用Spring Boot而不是SSH或者SSM。回答思路围绕“简化配置、快速开发、生态完善、前后端分离趋势”展开同时提一下Spring Boot与Spring MVC的关系能说得清楚这两者的区别老师通常就放心了。二是为什么库存要单独设计表而不直接放在物资表里。可以从数据冗余度、扩展性、批次效期管理三个角度回答如果能把先入先出、批次扣减逻辑讲明白这套东西的含金量会上升不少。三是如何保证数据一致性。可以回答通过事务控制解决关联操作同时结合数据库字段约束和前端表单校验减少脏数据。四是系统能不能应对高并发。乡镇卫生所本身业务量不大回答专注于轻量级易部署即可不用硬拗分布式那套但可以适当说清楚系统设计上预留了哪些扩展空间。回答问题的核心技巧是“不要背代码要讲思路”。代码写得好不好老师其实可以一眼看穿但如果你能把业务逻辑、表结构关系、供应链管理的基本闭环讲清楚就已经达到毕设考察的本意了。6.2 后续可以继续扩展的几个方向做完基础版之后系统还可以往这几个方向扩展提升选题深度。上策是加入移动端或小程序端因为乡镇卫生所的人员并不是每个人都在电脑旁边一些人完全可以用小程序扫码出库这个点一加上技术含金量和实际应用价值立即上升。中策是引入更完整的批次管理逻辑比如增加近效期自动锁库、过期批次自动禁用等功能让仓储管理更贴近医院药事的真实规则。下策是把统计报表做得更智能一点比如按月份自动生成科室领用趋势图和分类占比图甚至导成Excel文件。都不是多难的事对毕设来说却很有延展余地。6.3 我踩过几次坑之后的体会如果要给一个最重要的经验那就是在写代码前一定要花半天时间把业务和数据流理清楚。进销存系统最累人的地方不是页面画得多好看而是入库出库库存这三个环节的联动逻辑要想明白。我见过有同学写了一个星期最后发现库存扣减写反了导致越出库库存越多当场心态崩掉。也有同学为了赶进度跳过数据库设计直接建了三张表后面补表补字段补到头大。另一个体会是这类系统写起来并不难但写明白和能交付是两回事。建议把“自动化部署”和“数据备份”这两件事至少做形式的落地这样无论答辩时还是真实使用场景里你都会比同一批做相似题目的人更有底气很多。最后分享一个小技巧。在调试库存不准确这类bug时不要只在页面里点按钮试去数据表里把入库单、出库单、库存表一起查出来按照时间顺序把每一笔操作的库存变化捋一遍通常几分钟就能定位问题。前端报错看network面板后端报错看日志文件养成这个习惯你会少走很多弯路。
阅读完成 · 觉得有帮助?
咨询建站