恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

基于Spring Boot的药房订单管理系统设计与实战解析

  • 首页
  • 资讯中心
  • /
  • 基于Spring Boot的药房订单管理系统设计与实战解析

相关资讯

Python+CARLA分布式自动驾驶仿真平台:架构、搭建与避坑指南 2026/10/22 4:20:09
影视剧片段细粒度描述:从镜头切分到微调的全流程实践 2026/10/22 4:20:09
Linux内核调度器源码深度解析:从CFS到EEVDF的演进与实战调优 2026/10/22 4:20:09

最新资讯

双系统开机直接进Ubuntu?GRUB引导菜单修复全攻略
自动驾驶CNN视觉感知包部署实战:从ZIP解压到Jetson Nano 18FPS
智能面积:AI Agent应用版图与多代理协同落地指南
AI编码代理长会话失忆?用init.d自举模型对抗上下文压缩
AI关键词优化框架:从词库建设到机会评分的完整实操指南
深度学习驱动的量子错误缓解:从噪声建模到算法优化

今日推荐

电商智能运营体系从0到1:架构设计、落地步骤与避坑指南
压缩空气储能与热网热惯性联合优化调度:热电联产系统建模与求解
若依框架AI代码生成不稳定?用Agent Skill三层结构+五步法搞定

本周热门

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

基于Spring Boot的药房订单管理系统设计与实战解析

发布时间:2026/10/22 4:20:09
基于Spring Boot的药房订单管理系统设计与实战解析 恒爱药房网上订购管理系统这套毕业设计我从选题到最终跑通差不多花了一个月。Spring Boot做后端MySQL存数据前端用Vue搭页面整体是当下毕业设计里非常主流的技术路线。先说清楚这套内容的价值它不是给你堆一堆代码而是把从数据库设计、登录权限、药品上下架再到下单事务和库存扣减这条核心链路全部串起来讲通让你拿着这套东西从开题报告、中期检查一路扛到最终答辩都有话可说。适合正在做类似“网上商城/订单管理系统”题目的同学也适合想快速上手Spring Boot业务开发的初学者。我尽量把每一步为什么这么设计、哪里容易踩坑、答辩时怎么解释都写明白。这里没有花架子全是实际操作过的经验。1. 项目整体设计与技术选型逻辑1.1 双向角色用户下单端和管理后台为什么必须拆分恒爱药房这个系统表面看是一个“网上买药”的商城但真正的核心其实是一个双角色的业务管理平台普通用户负责浏览药品、加购物车、下单、查看订单管理员负责药品维护、库存管理、处理订单、看销售数据。为什么必须拆开因为这两个角色对系统的需求完全相反。用户端讲究下单爽快、流程简单管理端讲究信息完整、操作可控。如果混在一个页面里权限容易混乱比如随便一个用户就能调接口把药品价格改了这在答辩演示的时候就是致命伤。实际设计里我用了一张user表通过role字段区分角色0是普通用户1是管理员。后端的接口统一走拦截器校验登录后返回一个JWT令牌请求接口时带上这个令牌拦截器解析出身份和角色再决定放不放行。这个做法既是主流方案也比较容易在答辩时讲清楚安全控制思路。1.2 Spring Boot为什么是毕业设计的最优解选题用Spring Boot真不是跟风而是它确实适合这个场景。第一内置Tomcat不用额外配置服务器写一个main方法就能跑起来。第二和MyBatis-Plus配套使用写单表的增删改查几乎不需要手写SQL这对毕设时间紧的同学太友好了。第三Spring Boot的自动配置把大量繁琐的XML配置消掉了项目结构清爽答辩演示时Launch一下就起来了不会出现配置半天起不来的尴尬。有人会纠结用不用Spring Cloud或者微服务我的建议是别加。毕设的核心是证明你掌握了完整业务开发链路单体应用加良好模块划分就已经足够。强行上微服务反而会被分布式事务、服务注册这些问题拖住得不偿失。1.3 开发前需要准备的东西在动手写之前先把环境确认好。我实际用过的是JDK 8和JDK 17两套方案都能稳定跑建议按你本机现有版本选没必要为了新而新。数据库用MySQL 8.0连接驱动要选对版本。IDE用IDEA社区版也行。前端我用的是Vue 2加Element UI主要是组件现成表格、表单、弹窗这些管理端页面常用的东西拖出来就能用省下大量写样式的时间。注意如果电脑配置一般跑前后端两个服务加上MySQL内存占用大概在2G左右建议装之前确认一下内存余量免得打开几个窗口就卡到怀疑人生。1.4 系统功能模块全览角色功能模块核心操作普通用户注册登录手机号/用户名注册、登录、退出普通用户药品浏览分类筛选、按名称搜索、查看详情普通用户购物车加入购物车、修改数量、删除、清空普通用户订单管理提交订单、在线支付模拟、取消订单、确认收货普通用户收货地址新增、编辑、删除、设置默认地址管理员药品管理新增药品、编辑信息、上架下架、传图片管理员库存管理查看库存、手动调整库存、低库存提醒管理员订单处理查看订单、发货操作、处理取消申请管理员数据统计销售总额、订单量趋势、热销药品排行这套功能覆盖了电商类系统最常见的业务场景既不会太少显得单薄也不会太多导致做不完是性价比很高的功能划分。2. 数据库设计与核心取舍2.1 八张核心表怎么设计数据库是整个系统的基础设计得合不合理直接决定后面写代码的顺畅程度。我最终采用了8张表用户表、药品分类表、药品表、购物车表、订单表、订单明细表、收货地址表外加一个管理员操作相关的映射。这里重点说订单和订单明细为什么要拆成两张表。订单表记录一次下单的整体信息比如订单编号、总金额、下单用户、订单状态、收货人信息和下单时间。订单明细表记录这次订单里到底买了哪些药每样药买了几盒、单价多少、当时快照的药名和图片。拆开的原因很简单一次订单可能包含多盒不同药品如果不拆订单表里就得用逗号拼接药品ID查询时要拆字符串统计销售数据时更是灾难。而且明细表里冗余保存药品名称和图片是为了防止管理员修改药品信息后历史订单显示错乱。这是一种典型的“用空间换稳定”的设计思路。药品表是另一个重点字段里必须包含商品规格比如“30片/盒”、生产厂家、零售价、库存数量、销量和上下架状态。药品和分类之间用category_id关联药品表只存分类的ID不存分类名称查询时再关联。这样分类改名时药品不用动也是正规的范式设计。2.2 三个容易让答辩老师皱眉的字段设计问题第一个是金额。药价这个字段一定不能用float或double必须用decimal(10,2)。浮点数在计算机里是近似存储0.1加0.2都可能变成0.30000000000000004药价算错一个小数点是大事。decimal是精确小数类型完全符合金额计算的场景。第二个是库存。库存字段我用int并且在扣减库存时配合“版本号”机制。这里先埋个伏笔后面下单部分详细展开。版本号存在的意义是防止两个人同时买最后一盒药时出现超卖这个概念在电商项目里是非常经典的面试点。第三个是订单状态。数据库里不存字符串比如“待付款”而是用一个tinyint存数字0代表待付款1代表已付款待发货2代表已发货3代表已完成4代表已取消。代码里用枚举或者常量映射。这样存储省空间查询更快状态流转也更明确。2.3 订单号的生成不能瞎写订单号我用的是“时间戳随机数”的组合取当前时间的yyyyMMddHHmmss格式字符串再加上4位随机数。实际代码里为了保证并发不重复我还会把当前用户的ID尾数拼进去生成的订单号是24位左右的长字符串既好看最关键的是不会重复。有人会用数据库自增ID直接当订单号我劝你别这么干。订单号在电商场景里是会给用户看、给物流用的自增ID容易暴露系统每天的订单量而且多表合并时容易撞。用时间戳随机数的方式天然有序看起来也专业。3. 核心后端模块的实现过程3.1 登录认证与接口拦截登录接口的逻辑不复杂用户提交用户名和密码后端查user表对密码做MD5加盐处理后比对匹配成功就生成一个JWT令牌返回给前端。这里的细节在于密码绝对不能明文存储。我用的是MD5加盐简单够用如果你想让安全层级更高可以用BCryptSpring Security里自带这个工具只不过那套体系对毕设来说稍微重了一点。JWT的生成代码大致如下String token Jwts.builder() .setSubject(String.valueOf(user.getId())) .claim(role, user.getRole()) .claim(username, user.getUsername()) .setExpiration(new Date(System.currentTimeMillis() 7 * 24 * 60 * 60 * 1000)) .signWith(SignatureAlgorithm.HS256, secretKey) .compact();拦截器才是这里的关键。我用的是Spring MVC的HandlerInterceptor在preHandle方法里先判断请求路径。像登录接口、注册接口、药品列表这些公开接口直接放行其余接口都要校验请求头里的Authorization字段。解析JWT失败就返回401让前端跳回登录页。这里有个特别容易掉的坑拦截器的放行路径写错了导致登录接口自己被拦截前端一调登录接口就401。我第一次写的时候就犯过这个错排查了半天。建议放行路径写成接口的完整前缀加通配符比如/api/auth/然后其他接口统一走/api/前缀在拦截器里排除掉/api/auth/就行。3.2 药品分页和条件查询用户端的第一屏就是药品列表这里要做成“分类筛选关键字搜索分页”的组合查询。MyBatis-Plus的分页插件非常省事配置一个PaginationInnerInterceptor然后调用分页方法即可。PageDrug page new Page(pageNum, pageSize); LambdaQueryWrapperDrug wrapper new LambdaQueryWrapper(); wrapper.eq(Drug::getStatus, 1) .eq(categoryId ! null, Drug::getCategoryId, categoryId) .like(StringUtils.hasText(keyword), Drug::getName, keyword) .orderByDesc(Drug::getSales); IPageDrug result drugMapper.selectPage(page, wrapper);这段代码里有两个细节值得留意。第一status必须等于1也就是只展示上架药品。如果管理员下架了某款药用户那边不管怎么搜都不应该再出现。第二排序按销量倒序销量越高的药排在越前面这符合药店“热销推荐”的业务习惯演示的时候也不会出现一堆销量为零的药品霸屏的尴尬。分页插件有个小坑如果MyBatis-Plus版本比较老需要在启动类上加MapperScan注解扫描Mapper接口否则分页插件无法生效会出现查出来的数据不对、总数永远是0之类的问题。配置好之后返回给前端的数据结构里包含records当前页数据、total总条数、pages总页数前端直接用分页组件绑定就行。3.3 下单事务与库存扣减下单是整个系统技术含量最高的一段也是答辩时老师大概率会追问的地方。核心流程是校验登录态、查询药品最新价格、校验库存是否充足、生成订单和订单明细、扣减库存、清空购物车对应商品。这整个流程必须在一个事务里完成——要么全部成功要么全部回滚不能出现用户下单成功了库存却没扣掉的情况。我在Service里的下单方法加了这个注解Transactional(rollbackFor Exception.class) public OrderInfo createOrder(Long userId, Long addressId, ListCartItem items) { // 1. 计算总金额 // 2. 生成订单主表 // 3. 遍历明细逐条扣减库存 // 4. 保存明细 // 5. 清空购物车 }扣减库存这一步与其先查库存再更新不如直接在SQL里做判断这是我强烈推荐的做法。核心SQL是这样写的update drug set stock stock - #{quantity}, version version 1 where id #{drugId} and stock #{quantity}注意看where条件里的stock #{quantity}这一句保证了只有在剩余库存足够时才会执行更新。如果受影响的行数是0说明库存不够直接抛异常整个事务回滚用户就能看到“库存不足”的提示。这种写法避免了“先查再扣”过程中的时间差能有效防住超卖问题。后面我在常见问题里专门展开讲一次。订单状态我用起始值0待付款。这里我做了个简单处理支付环节用模拟支付页面用户点击“立即支付”后调用一个支付回调接口把订单状态从0改成1。对于毕业设计来说这个完整闭环已经足够了真去接入微信支付反而需要商户资质不是学生项目能搞定的。3.4 购物车模块的两个贴心细节购物车我设计了两个前端觉得“理所当然”但后端很容易忽略的细节。第一个是添加购物车时如果购物车里已经有这个药品应该自动把数量累加而不是再插一条新纪录。第二个是在购物车列表里显示药品当前价格和库存状态如果药品已经下架或库存为零对应行要置灰并提示“已失效”不让用户勾选提交。这两个细节看似简单但实现时要小心。查购物车列表时不能只返回cart表本身必须联查drug表拿最新的价格和上下架状态。我在写购物车列表SQL时使用了LEFT JOIN这样即使药品被删了购物车记录还在只是前端多一个失效标识。4. 管理后台的关键实现与数据统计4.1 管理端页面怎么做到简洁又能撑住场面管理端的UI我用的还是Element UI布局采用常见的左侧菜单加右侧内容区。菜单项包含药品管理、库存管理、订单管理、数据统计。这里不需要花哨的设计重点是把表格、分页、表单弹窗、状态切换这些操作做顺这也是最标准的管理后台交互模式。药品管理页面里图片上传是一个绕不开的点。我建议图片不要存到数据库里而是在服务器上放一个静态资源目录上传后把图片的访问路径存到数据库。Spring Boot里配置一个虚拟路径映射把本地磁盘目录映射成/image/开头的URL这样前端就能用http://localhost:8080/image/xxx.jpg直接展示。提示图片上传后如果刷新就没了大概率是虚拟路径映射没配排查方向在WebMvcConfigurer的addResourceHandlers方法里。4.2 订单状态流转和取消时的库存回补管理端订单处理的核心是状态流待付款可以取消已付款可以发货已发货可以完成。我在接口层做了严格的状态判断防止前端乱跳状态。比如发货接口只接受当前状态为1的订单如果状态已经是2接口直接返回错误。这种状态校验在后端必须做前端隐藏按钮只是体验优化后端的校验才是真正的安全边界。这里有一个特别容易被忽视的逻辑取消订单后必须回补库存。用户下单买了2盒感冒灵付款前取消了数据库里的订单状态从0变成4但如果库存不恢复那2盒药就“凭空消失”了后面再有用户来买就会提示库存不足。回补库存的SQL很简单就是把库存加回来update drug set stock stock #{quantity} where id #{drugId}这段逻辑要写在取消订单的同一个事务里和扣库存一样要么一起成功要么一起回滚。4.3 数据统计怎么做出能讲五分钟的内容数据统计是管理端最能体现“完整度”的模块也是答辩时很加分的部分。我用的是ECharts图表后端提供统计数据接口前端绘制柱状图和饼图。三个统计亮点分别是近7天订单量趋势、本月的销售总额、销量前五的药品排行。统计SQL其实都很直白。比如近7天订单量就是按下单日期做分组统计每天的订单数量select date(create_time) as day, count(id) as count from orders where create_time date_sub(curdate(), interval 6 day) group by date(create_time)再比如热销药品排行从order_item表里按药品ID分组sum(quantity)排序后取前5。这里订单明细表的冗余设计就体现出好处了统计时不需要关联药品表也能拿到数据SQL简单明了。5. 常见问题与排查技巧实录5.1 库存超卖问题是答辩高频问题库存超卖是网上商城系统里最经典的问题。简单描述就是药品库存只剩1盒用户A和用户B同时下单两个人都查询到了库存大于0都执行了扣减结果库存变成-1订单却都成功了。如果只是“先查再扣”的普通写法在并发下确实会出现超卖。我采用的方案是上面提到的“SQL条件更新”用stocks #{quantity}作为更新的条件数据库的行锁保证同一时刻只有一个请求能更新成功另一个请求的更新受影响行数为0然后抛出“库存不足”异常。这样从根本上杜绝了超卖。答辩时老师可能会继续追问“如果请求量特别大怎么办”这时候你可以补充说高性能场景还可以引入Redis预减库存、消息队列异步扣减但毕业设计采用数据库层面的乐观锁方案已经足够严谨。这种回答既展示了你深入思考的能力又不会给自己挖坑。5.2 金额精度漂移如果药价字段用了double展示出来就是9.990000000000002这种奇怪数字用户看到绝对会觉得系统有bug。解决方法是统一用BigDecimal运算不要再拆成double来加减。数据库字段对应decimal(10,2)Java实体用BigDecimal前端保留两位小数。这是一条完整的链路任何一个环节变成浮点数都会出问题。5.3 LocalDateTime序列化报错Java 8的时间类型在Jackson序列化时如果没配格式返回给前端的可能是“2024-05-20T10:30:00”这种带T的格式或者直接报不支持序列化的错。解决办法是在日期字段上添加JsonFormat注解统一成“yyyy-MM-dd HH:mm:ss”。如果你用的是Spring Boot 2.3以上版本也可以在application.yml里配置全局的Jackson日期格式。5.4 分页插件不生效分页插件不生效的排查方向有两个。第一确认MyBatis-Plus的分页拦截器是否在配置类里注册了。只引入依赖是不够的如果没有注册PaginationInnerInterceptorselectPage方法查出来就是全表数据只是内存截取。第二确认Mapper接口是否被扫描到没加MapperScan的话Mapper根本不会注入到Spring容器里启动就会报错。5.5 常见问题速查表现象原因解决办法登录接口报401拦截器放行路径没配好检查放行路径前缀是否正确下单后库存没变事务没生效或没走扣减SQL检查Transactional注解看是否是同类调用图片上传后刷新失效静态资源映射未配置检查addResourceHandlers配置前端日期带“T”LocalDateTime序列化格式问题加JsonFormat指定格式分页总数恒为0分页插件没注册注册PaginationInnerInterceptor取消订单后库存少了没有回补库存取消事务里增加库存回补SQL数据库时间差8小时连接串时区问题在jdbc url上添加serverTimezoneAsia/Shanghai5.6 事务不生效这个坑一定要知道Service方法里的所有数据库操作想在一个事务里前提是Spring代理能拦截到这个方法。一个经典的坑是同类内部调用类A有一个方法method1内部直接调用this.method2那么method2上的Transactional注解不会生效因为事务是靠AOP代理实现的内部调用不走代理。解决办法是把需要事务的代码抽到另一个Service类里让方法从外部调用或者更简单的做法是直接把整个业务逻辑放在一个方法内完成。写下单Service时一定要注意这一点不然扣库存和保存订单是两次独立提交一旦后半段出错库存就被扣了但订单没生成整个数据就乱了。个人实操中的几点体会这套系统做下来我最深的感受是毕设项目不是代码越多越好而是流程越完整、逻辑越闭合越好。恒爱药房这个题目表面上只是“网上卖药”但真正把它做成一个能展示的系统需要把商品、购物车、订单、库存、权限、统计这些模块全部串起来每一步都踩在真实业务逻辑上。最后给做这个题目的同学一个建议先别急着写代码把订单状态机画出来把数据库表结构确认好再把下单和库存扣减这段事务链路写通之后再去填充剩余功能。核心链路通了这个项目的骨架就立住了后面再遇到任何问题都不会慌。我也把自己实际配置过的关键代码和数据表设计融入到了上面的内容里可以直接照着搭。祝顺利跑通。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号