别小看“药店销售管理系统”这种题目,第一眼确实不如人脸识别、推荐算法那些题目炫,但在计算机毕设里,它恰恰是最能体现完整工程能力的一类选择。Java + Spring Boot + Vue 的组合做药品管理、销售收银、库存预警、会员积分、用药咨询,业务闭环完整,演示效果好,论文也好写,答辩的时候老师基本问不出能把你问倒的问题。这篇就把我当时做这套亭湖区药店销售管理系统的完整思路、技术选型、数据库设计、核心代码逻辑,以及最后答辩怎么准备,一次性讲清楚。
1. 选题定调:为什么药店销售管理这类题目最不容易翻车
每年毕业设计题目里,管理系统类的占比都是最大的,这是有原因的。毕设考察的不是你会不会某个炫技算法,而是你有没有独立完成一个完整项目的能力——需求分析、数据库设计、后端接口、前端页面、部署演示、论文撰写,这是一条完整的链路。药店管理系统在这个链条上,每一个环节都有足够的内容可以做,又不至于复杂到一个人做不完。
1.1 业务复杂度恰好在“够写”和“能做完”之间
选题目最怕两个极端:太简单导致论文没东西写,太难导致做不完。药店销售管理系统的复杂度刚好卡在中间偏上的位置。它本质上是一个进销存系统,但比普通的图书管理系统、学生管理系统多了几个很有分量的业务点:
- 药品有特殊属性:处方药和非处方药要区分标记,药品有有效期、批号、生产厂家、批准文号,近效期药品需要预警。
- 库存管理更严格:药品不能断货,也不能积压,需要安全库存和补货建议。
- 销售流程有细节:要支持购物车批量结算、会员折扣、积分累计,还要有退货流程。
- 业务数据有分析价值:哪些药卖得快、哪些药滞销、营业额趋势如何,这些都是报表模块的内容。
也就是说,同样写三千行代码,图书管理系统只能写“借书还书”,药店管理系统能写出好几个模块的深度。论文的第三章需求分析、第四章总体设计、第五章功能实现,每一章都有具体业务支撑,不愁没内容。
1.2 “智能”两个字不一定要上AI算法
这个题目里带了“智能药店销售平台”,很多同学一看“智能”就心虚,觉得得上机器学习。其实在管理系统语境下,“智能”完全可以落在数据驱动的业务逻辑上:
- 智能补货提醒:根据安全库存、日均销量、采购周期,自动计算建议补货数量。
- 近效期预警:有效期不足90天的药品自动列表提醒。
- 销售趋势分析:按天/按周统计营业额变化,辅助店主决策。
- 用药咨询智能匹配:根据顾客输入的问题关键词,自动关联常见问题知识库,再交由药师确认回复。
这套做法在答辩时非常好讲。老师说“你这智能体现在哪”,你直接把补货计算公式和预警规则摆出来,比任何花哨的算法都更有说服力。管理系统类的“智能”,核心是规则引擎和数据驱动,不是算法竞赛。
1.3 和AI类、算法类题目比,管理系统类稳在哪里
如果你正在纠结要不要追热点选AI相关的题目,我劝你先想清楚一个问题:你有没有能力在三个月内独立训练一个效果能现场演示的模型?大多数人的情况是,环境配置折腾了两周,数据集找到了但标注质量堪忧,训练出来的效果不敢在现场跑demo。管理系统类题目就没有这个问题,它的功能全部是可预期、可复现的。你今天写的代码,明天打开还能稳定运行。
从找工作角度看,Java后端岗位的需求量远大于算法岗位,一套完整的Spring Boot项目经历在简历上是加分项。你完全可以靠这个项目去投Java开发岗,面试时聊业务场景、聊数据库设计、聊并发扣库存,这些都是真实工作中会面对的问题。
2. 需求梳理:亭湖区社区药店的业务画像决定功能边界
做系统之前先别急着写代码,先搞清楚你服务的对象是谁。题目里写的是“盐城市亭湖区药店销售管理系统”,亭湖区作为盐城主城区,药店形态主要是社区店和商圈店,目标客户是周边居民,中老年顾客占比高,买药场景集中在感冒发烧、慢性病长期用药(高血压、糖尿病)、肠胃不适这几类。
2.1 四类用户角色和他们的核心动作
我梳理下来,系统要服务的角色一共有四个:
| 角色 | 核心业务动作 | 关注点 |
|---|---|---|
| 系统管理员 | 员工账号管理、角色权限分配、基础数据维护 | 系统安全、操作留痕 |
| 店长/老板 | 查看销售报表、库存情况、补货建议、员工绩效 | 经营决策、数据准确 |
| 收银员 | 药品扫码/搜索、购物车结算、退货处理、会员登记 | 操作效率、不出错 |
| 药师 | 药品信息维护、近效期检查、顾客用药咨询回复 | 知识库准确、服务闭环 |
为什么药师的端口一定要单独拎出来?因为这是“药品管理与咨询服务系统”里的“咨询服务”落地的关键。如果你只做销售和库存,那这个系统和普通商超收银系统没有区别,体现不出药店行业的特性。加了药师咨询模块,整个系统的服务属性就出来了。
2.2 从业务场景倒推功能模块
把四个角色的日常动作翻译成系统功能,大概就是下面这些模块:
- 登录认证与权限管理:JWT签发token,拦截器校验,不同角色访问不同菜单。
- 药品信息管理:药品CRUD、分类管理、药品状态(在售/停售/下架)、处方药标记。
- 采购入库与供应商管理:供应商档案、入库单创建、库存自动增加、采购记录查询。
- 门店销售:购物车药品添加、结算(现金/扫码/记账)、会员折扣与积分、销售小票生成。
- 退货管理:根据销售单退货、库存回补、退货原因记录。
- 库存管理:库存列表、库存预警、近效期预警、智能补货建议。
- 会员管理:会员注册、储值/积分余额、积分流水、会员等级。
- 咨询服务:常见问题库、药品说明书查询、顾客咨询工单、药师回复。
- 统计报表:营业额日/周/月趋势、药品销售TOP10、分类占比、库存周转情况、Excel导出。
- 操作日志:记录关键操作(登录、删除药品、退货、修改库存)。
这些功能做出来,系统在答辩现场从登录演示到报表导出,流程非常顺畅,每个模块都有看得见摸得着的成果。
2.3 刻意砍掉哪些功能(边界控制是这个题目的加分项)
毕设翻车的一个常见原因是什么都想要:做个药店系统还想加微信小程序、想加在线支付对接、想加电子处方流转、想加医保接口。这些都是真实业务里存在的诉求,但不是一个本科毕设能独立完成的。
我当时明确砍掉了三块内容:第一,不接真实的医保结算接口,订单表里预留一个“结算方式”字段,支持“医保”这个选项值,但底层不做任何外部接口对接,答辩时直接说是模拟实现;第二,不做在线问诊/远程开处方,咨询模块只做药品信息咨询和用药注意事项科普,不做任何诊断建议,这个边界既是为了合规,也是为了避免业务复杂度失控;第三,不做复杂的进销存财务管理,不做应收应付、不做利润总账,只做到销售流水和基础毛利统计。
砍掉这些之后,系统的实现范围非常清晰,每个模块都能完整做完。在论文里主动写清楚“系统的边界和不足”,反而会让老师觉得你对项目有清醒的认知。
3. 技术选型:Spring Boot + Vue这套组合的选择逻辑
技术栈选型是毕设开头就要定的,而且会在答辩时被第一个问到。不要只写“用了Spring Boot”就完事,你要能讲清楚为什么是它。
3.1 为什么主语言选Java而不是Python
看到题目带“java”字样,主语言基本就定了。客观说,Java在这个项目里确实比Python合适:第一,药店管理系统的核心是事务性业务处理,Java的Spring框架在事务管理、数据校验、权限控制上非常成熟;第二,Java的部署环境简单,一个jar包扔服务器上就能跑,客户现场演示不会因为依赖问题翻车;第三,国内企业级后端岗位绝大多数是Java,这个项目做完可以直接写在简历上。Python更适合做数据分析、人工智能,拿来做进销存系统属于杀鸡用牛刀,而且代码的可维护性反而不如Java工程化组织得好。
3.2 各组件的具体选择和理由
我的建议搭配是这样一套,也是目前最容易找到资料、最容易跑通的组合:
- JDK 1.8 或 JDK 17:学校机器环境普遍有1.8,稳妥为主;如果是自用电脑且想新一点,17也支持得很好。
- Spring Boot 2.7.x:稳定版,资料最多,提问也最容易搜到答案。不建议一上来追Spring Boot 3,部分老资料不兼容。
- MyBatis Plus:单表CRUD真的能少写一半代码,内置分页插件、条件构造器,对毕设来说非常好用。
- MySQL 8.x:社区版免费,性能足够,Navicat/Sqlyog做图形化管理。
- Vue 2 + Element UI或Vue 3 + Element Plus:选一个自己更熟的。如果都没试过,直接Vue3 + Element Plus,现在教程多。
- JWT + 拦截器做登录认证和权限控制,不引入Spring Security。Spring Security配置复杂,学习成本高,用在毕设里有点过度设计。
- ECharts做报表图表,Apache POI或EasyExcel做Excel导出。
3.3 为什么这套组合答辩时好交代
答辩老师问“技术选型理由”,你回答的口径应该是:业务访问量不大、系统规模中等,单体应用 + 经典前后端分离是最经济和最易维护的架构。没有微服务、没有分布式中间件,不是因为我不会,而是因为系统规模和团队人数决定了这样最合理。讲清楚“架构服务于业务规模”这个道理,老师不仅不会扣分,还会觉得你有工程判断力。相比之下,如果只是一个简单的药店系统却上了微服务、上了Redis集群、上了消息队列,老师追问每个组件的作用时,你基本答不上来,反而暴露问题。
项目结构上,Maven标准结构,包名可以用com.yancheng.pharmacy这样的风格,按模块分包:controller、service、mapper、entity、dto、config、common。不要一个类几百行,控制层只做参数接收和结果返回,业务逻辑全部下沉到Service层,这个好习惯在答辩时会被夸。
4. 数据库设计:药品、订单、库存、咨询四条主线怎么建模
数据库是管理系统的心脏。我见过太多毕设项目最终代码写了但演示时数据一塌糊涂,原因就是表结构设计不合理,查个报表要五六层嵌套子查询。药店管理系统的表设计,我建议按四条主线来组织。
4.1 核心表设计总览
我实际使用的表如下(字段做了精简,但都是能落地的):
- sys_user(用户表):id, username, password(BCrypt加密), real_name, role_id, phone, status, create_time。
- sys_role(角色表):id, role_name, role_code(ADMIN/MANAGER/CASHIER/PHARMACIST)。
- drug_category(药品分类表):id, parent_id, name。
- drug_info(药品信息表):id, drug_code(药品编码), generic_name(通用名), product_name(商品名), category_id, dosage_form(剂型), spec(规格), unit, manufacturer, approval_number(批准文号), prescription_type(处方类型:RX/OTC), storage_condition(存储条件), shelf_life_months(保质期), status, create_time。
- supplier(供应商表):id, supplier_name, contact, phone, address。
- purchase_order(采购入库单表):id, order_no, supplier_id, total_amount, operator_id, create_time。
- purchase_order_item(入库单明细):id, order_id, drug_id, quantity, purchase_price, valid_date(有效期)。
- stock_info(库存表):id, drug_id, quantity, safety_quantity(安全库存), last_update_time。
- sale_order(销售单表):id, order_no, member_id(可空), operator_id, total_amount, discount_amount, payable_amount, received_amount, pay_method(CASH/SCAN/MEMBER/MEDICARE), status, create_time。
- sale_order_item(销售明细):id, order_id, drug_id, sale_price, quantity, total_price。
- sale_return(退货表):id, return_no, order_id, operator_id, reason, total_amount, create_time。
- sale_return_item(退货明细):id, return_id, drug_id, quantity, return_price。
- member(会员表):id, name, phone, level, points, balance, create_time。
- points_log(积分流水):id, member_id, change_value, source_type, order_id, create_time。
- consultation(咨询工单表):id, consult_no, member_id(可空), customer_name, question_type, question_content, status(PENDING/REPLIED/CLOSED), create_time。
- consultation_reply(咨询回复表):id, consultation_id, reply_content, replier_id, create_time。
- faq(常见问题知识库):id, question, answer, category, keywords, view_count。
- operation_log(操作日志表):id, user_id, operation_type, detail, create_time。
4.2 订单与库存的几个关键建模思维
第一个关键点是销售明细里必须有价格快照。为什么?药品价格会变,半年后你想统计“某药上个月卖了多少钱”,如果关联实时价格表,历史订单金额会被当前价格污染,报表就废了。所以sale_order_item里直接冗余一份sale_price,订单历史永远按当时的成交价计算。报表准确性的前提是历史数据不可变,这个理念一定要有。
第二个关键点是库存独立建表,而不是drug_info表直接放quantity字段。逻辑上,库存是动态变化的业务数据,药品基础信息是相对静态的档案数据,两者混在一起会导致每次修改药品信息都要小心翼翼。库存独立表之后,药品表负责描述“这个药是什么”,库存表负责描述“现在有多少”,各自职责明确。
第三个关键点是所有订单类表都要有单号字段(order_no/return_no/consult_no),用日期+随机数生成。单号在退货、对账、审计时是唯一的业务主键,用户沟通时也只需要报单号。
4.3 建表顺序和MyBatis Plus相关的讨论
建表顺序建议按依赖关系来:先建分类、供应商、用户/角色这些基础表,再建药品表,然后建采购、销售、库存这些业务表,最后建会员、咨询、日志这些扩展表。在建表时把主键、索引、唯一约束都定义好,特别是drug_code要唯一,会员phone要唯一。
有同学问要不要用MyBatis Plus的反向工程或代码生成器直接根据实体类生成建表SQL。我的建议是:这个项目里的建表SQL一定要自己手写一遍。手写建表SQL能帮你把数据类型、约束、索引都想清楚,答辩被问“你这个索引建在哪、为什么建”时你说得出来。代码生成器可以留着生成实体类、Mapper接口和Service代码,但表结构的设计必须是脑力劳动,不能偷懒。
5. 销售主链路的实现细节:从购物车到库存扣减再到智能补货
销售模块是整个系统的核心,也是面试和答辩最容易针对提问的部分。这一节我把代码逻辑讲细一点,你可以直接照着这个思路实现。
5.1 购物车是前端临时状态,后端只管一次性提交
不要让后端去管理购物车,购物车本身就是顾客当前这次购买的临时集合,放在前端内存里就够了。前端把购物车数据整理成一个药品ID + 数量的数组,提交到后端时接口大致长这样:
POST /api/sale/create { "memberId": 1, "items": [ { "drugId": 1001, "quantity": 2 }, { "drugId": 1005, "quantity": 1 } ], "payMethod": "CASH", "receivedAmount": 50.00 }后端Service在同一个事务里完成下面几件事:
- 校验药品状态,过滤已停售药品;
- 累计总金额,按会员等级计算折扣;
- 插入
sale_order主表; - 循环插入
sale_order_item明细; - 循环执行库存扣减SQL;
- 更新会员积分;
- 返回订单号和小票数据。
这七步必须在一个事务里面,任何一步失败全部回滚。用@Transactional(rollbackFor = Exception.class)注解,注意要标注异常类型,只标默认的RuntimeException可能在业务异常时不会回滚。
5.2 防止超卖:扣库存SQL的正确写法
毕设答辩必问的问题就是“你这个系统怎么防止库存超卖”。很多人的写法是先select quantity from stock where drug_id = ?,然后在代码里判断数量够不够,够的话再update stock set quantity = quantity - ?。这在高并发场景下会出大问题,因为两个请求可能同时读到同一个库存数字,都判断能扣,然后都执行更新,数据就超卖超了。
正确做法是把判断和扣减合并成一条SQL,利用数据库的行级锁保证原子性:
UPDATE stock_info SET quantity = quantity - #{quantity} WHERE drug_id = #{drugId} AND quantity >= #{quantity}执行这条SQL后,影响行数为1代表扣减成功,为0代表库存不足或者药品不存在。Spring的 @Transactional 配上这条SQL,就能做到并发安全。为什么?因为数据库更新行记录时会对该行加锁,后来的事务必须等前面的事务提交后才能执行同一行的更新,所以两个请求不可能都成功扣到同一批库存。MySQL默认的InnoDB引擎在UPDATE语句执行时会自动加行锁,这个机制本身就是安全的。
用这条SQL有个要注意的点:不要在Service层先查库存再去更新,除非你每次查询都加上FOR UPDATE(SELECT ... FOR UPDATE是悲观锁),但那样会增加锁竞争。扣减条件直接写在UPDATE语句里是性能最好也最简单的方案,完全够这个场景用。
5.3 退货流程:校验、回补、记录三步走
退货不能随便把库存加回去,必须有单据。退货接口接收原始订单号 + 要退的药品明细,业务逻辑是:
- 校验原始订单存在且状态正常;
- 按明细执行
update stock set quantity = quantity + ?回补库存; - 插入
sale_return和sale_return_item记录; - 如果原订单用了会员积分,按商品金额比例扣减积分(或者保留积分,但要在退货单中记录清楚)。
这里有个业务细节:药品退货后,如果重新入库销售,有效期和批号可能与原来不同。但毕设系统里可以简化,统一按回补到库存处理,这个简化在论文里说明一下即可。真实药店对批号追踪要求高,但作为毕设展示核心业务逻辑已经足够了。
5.4 智能补货建议的计算逻辑
补货功能是“智能药店平台”的直观体现,公式不要设计得太复杂,但要能自圆其说。我当时用的是这个逻辑:
建议补货量 = (日均销量 × 采购周期天数) + 安全库存 - 当前库存其中日均销量取最近30天的销售总量除以30,采购周期天数按药品设定(比如普通药品3天、慢病用药7天),安全库存就是stock_info.safety_quantity。如果计算结果小于等于0,说明库存足够,不生成补货建议;大于0则生成一条补货提醒,推荐供应商信息一起带出来。
这个公式是完全可解释的。答辩时你把参数说清楚,老师一听就知道你理解“为什么要有安全库存——为了应对采购周期内的销量波动;为什么加日均销量×采购周期——因为在补货到货之前,还会消耗这些库存”。任何懂业务的人听了都会觉得合理。
5.5 报表统计用SQL聚合而不是Java内存计算
销售报表的统计建议直接写SQL聚合,不要从数据库把所有记录查出来放到内存里用Java的Stream去算。数据量小的时候两种方式都行,但SQL聚合写起来更简洁,而且查询效率高。举个例子,按日统计最近7天营业额:
SELECT DATE_FORMAT(create_time, '%Y-%m-%d') AS day, COUNT(*) AS order_count, SUM(payable_amount) AS total_amount FROM sale_order WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND status = 'NORMAL' GROUP BY day ORDER BY day统计分类销售占比,就是用sale_order_item关联drug_info再关联drug_category,按分类汇总数量。这些SQL写在Mapper的XML文件里,前端用ECharts展示折线图、柱状图、饼图,效果非常直观。
6. 咨询与服务模块:让系统有“服务感”,但别越界
很多人做药店管理系统只做到销售和库存就停了,我觉得这有点可惜。这个题目最大的加分项其实是“药品管理与咨询服务系统”里的“咨询服务”四个字。把咨询模块做出来,功能上就和其他人的纯进销存系统拉开了差距。
6.1 模块定位:不做在线问诊,只做信息服务和工单闭环
涉医功能非常敏感,一个处方药、一个用药指导如果措辞不当,很容易出问题。所以咨询模块的定位必须想清楚:系统只提供药品信息咨询、基础知识科普、药师人工回复,不做疾病诊断,不给治疗建议,不开放电子处方。在这个边界内,功能反而是清晰的。
药品说明书查询是咨询模块的基础能力。把药品的适应症、用法用量、不良反应、禁忌这些字段结构化地维护进drug_info的附加表或者单独建一张drug_manual表,顾客或前台员工可以按药品名/商品名检索说明书内容。注意“适应症”的字段内容是照搬说明书原文,系统只做展示,不做任何二次加工判断。
6.2 常见问题知识库:让“智能匹配”有落地点
咨询工单进来之前,很多问题其实是重复的:感冒了该买什么非处方药、降压药能不能和感冒药一起吃、过期药品怎么处理。与其让这些内容都走人工,不如做成常见问题知识库。
faq表里维护问题和答案,同时存一组关键词。顾客提交咨询时,后端做一次最简单的关键词匹配:把问题文本拿到FAQ表里按关键词查询,能匹配到就直接推荐给顾客“您可以先查看以下常见问题”,匹配不到才进入人工工单流程。这个功能不需要复杂的NLP算法,一个LIKE查询加几个分词结果就够了,但“推荐相关常见问题”这个交互在演示的时候非常亮眼。
6.3 药师的咨询处理闭环
药师角色的工作台能看到所有待处理的咨询工单,回复之后工单状态变为已回复,顾客(或前台)可以在系统里查看回复内容。一次有价值的咨询结束后,药师可以把这条问答整理成新的FAQ条目,沉淀到知识库中。这就形成了一个完整的闭环:顾客提问 -> 智能匹配 -> 药师回复 -> 知识沉淀。答辩时把这个流程画清楚,老师会认为你考虑的不只是代码功能,还有业务运营的长期价值。
技术实现上,咨询模块就是两张表(咨询工单 + 回复记录)加几个接口,没有难度,但它在系统里的存在感极强。系统演示时,点开咨询管理、创建一条工单、药师回复,这组操作能让评审老师直观感受到系统不是冷冰冰的收银机,而是一个有服务温度的平台。
7. 从开发到答辩:演示脚本、论文框架和最容易踩的坑
代码写完只是开始,毕业设计最终要过答辩这一关。我见过不少代码做得不错的同学,一到现场演示手忙脚乱,点错菜单、数据没准备、网络没连上,最后分数反而一般。这部分讲的全是实操经验。
7.1 提前编排好演示顺序和测试数据
答辩演示不要现场随机点,要提前编一个“演示脚本”,按商业逻辑顺序来走:
- 登录页面:管理员登录,显示系统首页的统计卡片(今日营业额、订单数、库存预警数)。
- 药品管理:按关键词搜一个药,展示详细信息(处方类型、有效期、库存)。
- 销售收银:添加三种药品到购物车,选一个会员,演示折扣和积分,结算。
- 库存变化:回到库存列表,确认刚才售出的药品库存减少了。
- 退货演示:把刚才那张订单选一个商品退货,库存回补,金额退回。
- 智能补货:展示库存预警列表,解释建议补货量的计算公式。
- 咨询工单:演示一个顾客提问,药师回复,FAQ匹配。
- 报表导出:展示近7天销售趋势,导出Excel。
演示之前要把测试数据铺好:库存预警的药品要正好处于低于安全库存的状态、销售报表要有连续两周的数据、会员积分要是整数方便看变化。现场的每一步都要可控,提前录一个备用视频以防现场出bug,这些都是实战过来的经验。
7.2 论文框架怎么组织最划算
论文不用长,但要结构清楚。我当时用的框架是:摘要 -> 绪论(背景与意义、国内外现状)-> 需求分析(业务流程、功能需求、非功能需求)-> 总体设计(架构图、模块划分、数据库设计)-> 功能实现(核心代码与界面截图)-> 系统测试(测试用例、结果分析)-> 总结与展望。
写摘要时,把核心关键词“药店销售管理系统”“Java”“Spring Boot”“智能补货”“咨询服务”在第一段全部带出来,摘要写完基本就是你的答辩开场白。功能实现部分不需要贴所有代码,贴核心的扣库存SQL、事务边界、补货计算逻辑就够了,配合运行截图。系统测试部分,列一个测试表格:模块、测试项、操作步骤、预期结果、实际结果、是否通过,这比写大段文字更受老师认可。
7.3 答辩高频问题:提前把答案背熟
结合这套系统,老师大概率围绕下面几个点展开:
- “为什么不用Spring Security?”:答,系统只有四个角色,权限模型简单,用JWT加拦截器实现RBAC足够,Spring Security学习成本高但对本系统收益有限。
- “这个事务怎么保证数据一致?”:答,使用@Transactional包裹下单主链路,所有数据库操作要么全成功要么全回滚,扣库存用条件更新SQL避免覆盖更新。
- “金额为什么用BigDecimal不用double?”:答,double存在二进制浮点误差,关于钱的所有计算都必须用BigDecimal。
- “药品价格变了,历史报表怎么算?”:答,销售明细表保存成交价快照,历史数据不随当前价格变化。
- “询咨询模块会不会有医疗风险?”:答,系统定位为信息查询与药师人工服务,不提供诊断建议,说明书内容均引用药品说明原文,药师回复内容可追溯留痕。
这些问题都不难,答案就在你做的系统里,关键是自己要理解背后的原理,而不是死记硬背。
7.4 开发过程里最容易踩的一串坑
最后集中盘点我实际踩过的坑,能避一个是一个:
- 逻辑删除和唯一索引冲突:MyBatis Plus默认逻辑删除会在删除时给逻辑删除字段赋值,如果你在
drug_code上建了唯一索引,删过一次再插入同编码就会冲突。解决方案是在唯一索引里拼接is_deleted字段,或者在逻辑删除时把被删行的drug_code拼一个时间戳后缀。 - 前端日期格式传给后端报错:前端传入的日期字符串必须匹配后端
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")的格式,或者干脆统一用时间戳传输,减少格式层面的问题。 - 跨域问题:前端Vue跑在8080端口,后端Boot跑在9000端口,需要在后端加上
@CrossOrigin或者写一个全局CORS配置类,不然演示的时候接口全部被浏览器拦截,非常尴尬。 - 金额精度踩坑:所有金额字段数据库用
DECIMAL(10,2),Java实体用BigDecimal,前端展示时注意不要用toFixed(2)去踩浮点问题。 - 订单号和数据库唯一约束:生成订单号时用
yyyyMMddHHmmss + 随机4位,并发较高时可能重复,数据库order_no必须建立唯一索引兜底。 - Redis不是必选项:搜热词能看到很多项目都在用Redis,但你这个系统没有高频缓存需求,不引入完全正确。不要看别人的项目有Redis就非要加,答辩老师问一句“缓存的key是什么、过期时间怎么定、缓存和数据库一致性怎么解决”,三个问题就能问穿。
写到最后我想说,毕设题目看起来朴实,不代表它能拿的分数就低。药店销售管理系统最大的优势是“你可以在答辩现场把每一步逻辑讲得明明白白”,从业务需求到源码实现,从数据库关系到报表呈现,它是一个完整的、诚实的、经得起追问的项目。当时我把系统在某次演示时跑出一单95块钱收银小票时,那感觉比写了一个“看上去很厉害”但自己都说不清原理的AI项目,要踏实得多。就这个方向做下去,认真把每一步想清楚,你完全可以交出一份自己满意的毕业设计。