基于Java的药房购药系统:Spring Boot+Vue全栈开发详解
快到毕业季了后台总有人私信问我“药房购药系统”这类题目该怎么下手。作为经常帮毕业生审代码、理思路的老学长我今天就以这套基于JAVA的药房购药系统为例子把从需求拆解、技术选型、数据库设计到核心代码实现的完整链路掰开揉碎讲一遍。这套系统不只是应付答辩你要是真能把它吃透Spring Boot Vue 的前后端分离开发、RBAC权限模型、订单状态机这些硬技能都能实实在在落到简历上。先给还不清楚状况的同学定位一下这是一个典型的JavaWeb方向的管理信息系统业务边界清晰技术栈主流特别适合计算机专业、软件工程、信息管理类专业的毕业设计。系统解决的核心痛点很朴素——传统药房靠手工记账、纸质处方管理药品库存靠人工盘点效期管理靠肉眼排查而这套系统要做的就是把这些线下流程搬到线上实现药品信息管理、库存预警、前台购药结算、订单追踪、角色权限控制的一体化闭环。如果只是随便找个开源项目改改名字交差那你大概率会在答辩时被问懵。我这篇博文的目标是让你真正理解每个设计决策背后的原因为什么订单金额用BigDecimal而不是double为什么用户表和角色表要拆开为什么库存扣减要放在数据库事务里做把这些“为什么”搞明白你不仅能顺利通过答辩还能在以后的面试里多几分底气。1. 项目整体设计与需求拆解1.1 从“购药”到“管药”一个完整的业务闭环很多人拿到这个题目第一反应是“这不就是个网上商城吗把卖衣服换成卖药不就行了”。这是最大的误区。药房购药系统虽然长得像电商系统但它的业务复杂度远超普通商城核心差异在于三个地方第一个差异是药品的双重属性。药品既是商品也是特殊监管对象它有关联的批准文号、生产厂家、批号、有效期、处方类型处方药与非处方药、储存条件这些额外字段。普通商城只需要管理SKU和价格药品管理系统必须管理效期和批号因为临近过期的药不能卖过了效期的药必须锁定下架。第二个差异是用户角色的多样化。一套完整的药房系统至少要有四类角色管理员管人和管数据、药师审核处方、上下架药品、收银员销售开单、普通用户浏览药品、下单购药。不同角色看到的界面不同操作的权限不同这就牵扯到RBAC权限模型的设计。第三个差异是库存精度要求更高。普通商品库存少一个多一个影响顶多是补货药品库存出错会直接影响患者用药安全。所以库存操作必须做事务控制每次出库入库都要留操作日志方便事后追溯。搞清楚这三点你再回来看这个选题就会发现它其实是个“麻雀虽小、五脏俱全”的综合训练——既有常规CRUD又有权限控制、事务处理、状态流转、报表统计该有的难点全都有。1.2 核心需求逐条拆解我习惯先画功能树再写代码。这套系统的功能规划大致如下前台用户端针对普通购药用户用户注册、登录、个人信息维护、密码修改药品分类浏览、关键字搜索、药品详情查看含说明书、用法用量购物车管理加入、修改数量、删除、批量结算提交订单、在线模拟支付、查看订单状态与历史订单常见问题FAQ与留言反馈后台管理端针对管理员、药师、收银员登录认证与基于角色的菜单权限控制药品管理增删改查、上架/下架、药品图片上传、效期预警分类管理药品类别维护支持二级分类库存管理入库登记、出库登记、库存盘点、低库存预警订单管理订单列表筛选、订单状态更新发货、完成、取消、订单明细导出用户管理用户列表、禁用/启用账号、重置密码轮播图与系统公告管理这里要特别说明一下处方药流程。很多毕设偷懒把所有药品都当普通商品直接下单这是不专业的。但在毕业设计阶段完整实现处方上传、药师审核、审核通过后才能支付的流程工作量确实偏大。实际操作中多数优质毕设会把处方药设计成“加入购物车时需要填写用药人信息并勾选已确诊声明”然后在后端加一道药师审核节点这样既体现了业务理解深度又不至于把项目周期拖得太长。1.3 系统架构前后端分离还是单体应用这个问题几乎每个来问我的人都纠结过。我的建议很直接有基础就上前后端分离没基础就用单体Bootstrap模板引擎两种方案都能做出优质毕设关键看你怎么选。前后端分离方案是当前工业界的主流形态后端用Spring Boot暴露RESTful API前端用Vue 3 Element Plus构建单页应用通过JSON交换数据。好处是技术栈新、代码组织清晰、简历上好看坏处是你要同时掌握后端接口设计和前端组件开发调试跨域、处理token过期这类问题的排查链路更长。单体模板方案是Spring Boot Thymeleaf或者JSP页面由后端渲染逻辑简单直接没有跨域烦恼开发速度快。缺点是技术栈相对传统前端交互体验一般。我个人强烈推荐前后端分离因为答辩时老师大概率会问“为什么选前后端分离”这个问题的标准答案本身就体现了你对现代开发流程的理解。而且后端API的测试、前端组件的复用这些实践都是可以直接带到工作中的。后面我讲的代码示例也是以后端API为视角展开的。2. 技术选型与开发环境搭建2.1 技术栈逐项解析这套系统我采用的是Java生态里最经典也最稳妥的组合后端主体JDK 8 或 JDK 11JDK 11是分水岭毕业设计用8也行但11的局部变量类型推断等特性更好用Spring Boot 2.7.x不用最新的3.x因为3.x要求JDK 17而且很多配套组件版本变化较大容易给自己挖坑MyBatis-Plus 3.5.x数据持久层相比纯MyBatis省去大量单表操作的XML配置MySQL 8.0关系型数据库8.0以上更好用支持窗口函数Redis 可选用于缓存验证码、token如果不想引入中间件本地Map也能应付前端主体Vue 3 Vite构建速度快组合式API写逻辑更顺手Element Plus组件库表格、表单、弹窗、分页都是现成的Pinia状态管理比Vuex更简洁AxiosHTTP请求库ECharts可视化图表用于首页统计辅助工具Maven依赖管理JWT Spring Security 或者 Sa-Token认证授权Lombok简化实体代码Hutool工具类库处理日期、加密、验证码很方便这个组合是目前B站和培训机构主流的教学组合资料多、报错网上都能搜到解决方案对毕设来讲是风险最低的选择。2.2 为什么不用SSM框架很多同学在选题时后台老师会列“Spring SpringMVC MyBatisSSM”让你选。我的意见是能不用SSM就不用。SSM属于上一个时代的开发方式配置繁琐——光一个Spring配置和MyBatis配置就要写几十行XML而Spring Boot通过自动配置把这些问题全部抹平了。你做毕设是为了展示工程能力不是为了证明自己能手工拼装XML。同理为什么不推荐用ShiroShiro和Spring Security都能做权限控制但Spring Security在最近版本中不断演进社区活跃度更高与Spring Boot的集成更无缝。当然如果你擅长Shiro选它也完全没问题核心是你要能讲清楚Session认证与Token认证的区别。我这个项目用的是Sa-Token它的学习曲线平缓API设计对初学者非常友好文档又全属于小众但非常香的选择。2.3 环境搭建的坑与版本匹配环境搭建这一步我见过太多人卡死在版本匹配上。直接给一套我已验证可用的版本组合JDK1.8.0_202 或 Amazon Corretto 8Maven3.6.3 或 3.8.xSpring Boot2.7.14MyBatis-Plus3.5.3.1注意3.5.4之后分页插件写法有变化MySQL8.0.32 或 5.7.265.7也可以但注意时区配置Node.js16.20.x 或 18.xVite 4需要Node 16.20npm8.x一个非常容易踩的坑是Maven仓库依赖下载缓慢或版本冲突。建议在Maven的settings.xml里配置阿里云镜像并且只用spring-boot-starter-parent做统一版本管理不要自己随意指定子模块版本否则极容易出现NoSuchMethodError之类的问题。遇到启动报错先别急着怀疑代码按这个顺序排查Maven依赖是否下载完整 → 数据库连接配置是否有误 → 端口是否被占用 → 启动类位置是否放对Spring Boot默认扫描启动类所在包及其子包。80%的启动失败都能用这四步解决。3. 数据库设计药房业务的地基3.1 数据表全景数据库设计是面试和答辩时老师最爱深挖的地方也是最能体现你水平的地方。这张表结构图我建议直接背下来并能讲出每一张表为什么这么设计。核心表sys_user用户表用户ID、用户名、密码、昵称、头像、手机、邮箱、角色标识、状态、创建时间sys_role角色表角色ID、角色编码、角色名称sys_user_role用户角色关联表多对多关系drug_category药品分类表分类ID、父分类ID、分类名称、排序drug_info药品信息表药品ID、批准文号、药品名称、通用名、规格、剂型、单位、生产厂家、储存条件、处方类型、零售价、会员价、库存数量、预警值、图片、说明书、创建时间drug_stock_log库存变动日志表日志ID、药品ID、变动数量、变动类型入库/出库/盘点调整、操作前后数量、操作人、操作时间、备注cart_item购物车表购物车ID、用户ID、药品ID、药品数量、加入时间order_info订单主表订单号、用户ID、订单总金额、实付金额、订单状态、收货人、联系电话、收货地址、下单时间、支付时间、完成时间order_item订单明细表明细ID、订单ID、药品ID、药品名称快照、单价快照、数量、小计金额sys_notice公告表公告ID、标题、内容、发布时间sys_pic轮播图表图片ID、图片地址、跳转链接、排序这几张表覆盖了一个药房系统的全部核心链路。多说一句订单明细表里的药品名称快照字段特别重要它是为了防止药品信息被修改后历史订单数据跟着变脏的做法。毕业设计能考虑到这一点答辩时是明显的加分项。3.2 关键字段设计意图解读我挑几个容易踩坑的字段详细说说。药品价格字段必须使用DECIMAL(10,2)。我审过不少毕设代码发现有人图省事用double存价格这是严重的低级错误。float和double在二进制浮点运算中会产生误差0.1 0.2输出的结果不是0.3这在涉及金额累加、优惠折扣计算时会造成分级别错误。Java后端对应使用BigDecimal所有价格计算必须通过BigDecimal的add、subtract、multiply方法完成禁止直接使用算术运算符。库存字段药品表冗余存一个当前库存字段同时用库存变动日志表记录每一次出入库明细。为什么这么设计因为如果只靠日志表时时SUM统计库存订单并发高的时候性能撑不住而且查询历史维度特别麻烦如果只存一个当前库存数字又无法追溯“这个月总共入库多少、出库多少”。两者互补才是完整方案。订单状态字段用int类型TINYINT存状态值配合后端状态机做流转校验。不要用字符串状态直接存因为不同模块对状态的叫法可能不一致比如前端叫“待付款”后端叫“PENDING_PAY”用数字枚举后端统一维护并配合状态机限制流转路径比如“已发货”状态下不能直接跳到“已取消”这种限制能防止脏数据。3.3 物理外键与逻辑外键的选择这是个很经典的开发争议话题。很多教科书鼓励建外键约束但我实际做项目时的习惯是数据库层面不建物理外键逻辑外键由代码控制。原因很简单——物理外键会导致几个问题一是每次插入子表都要检查主表写并发高的时候性能受损二是删除主表数据时如果被外键约束拦住会出现一堆“删除失败”的诡异报错三是项目运行中如果要调整表结构比如分库分表外键是最难迁移的。所以在互联网公司里物理外键几乎绝迹都是靠开发人员在业务层保证引用完整性。但在答辩时如果老师质疑“为什么没有外键”你要能解释清楚这套逻辑而不是支支吾吾答不上来。这本身就是设计思维的体现。4. 核心功能模块的实现细节4.1 用户认证JWT令牌机制用户登录是整套系统的第一道门。我不建议用传统的Session方案因为前后端分离的场景下Session天然要依赖Cookie而跨域场景下Cookie处理很麻烦。这里采用JWTJSON Web Token方案。简单讲用户输入用户名密码后端校验通过后生成一个带签名的令牌前端把令牌存到本地每次请求在请求头里带上Authorization: Bearer xxx后端过滤器拦截并验签。这套机制的核心价值是无状态——服务器不需要保存会话信息天然支持水平扩容。JWT的生成代码在用Sa-Token时非常简单PostMapping(/login) public ResultString login(RequestBody LoginDTO dto) { // 1. 校验验证码防止暴力破解 // 2. 根据用户名查用户 SysUser user userService.getByUsername(dto.getUsername()); // 3. 密码加密比对BCrypt加密 if (user null || !BCrypt.checkpw(dto.getPassword(), user.getPassword())) { return Result.error(用户名或密码错误); } // 4. 账号是否被禁用 if (user.getStatus() 0) { return Result.error(账号已被禁用请联系管理员); } // 5. 签发token StpUtil.login(user.getUserId()); return Result.success(StpUtil.getTokenValue()); }这里要强调一个核心原则数据库里的密码绝不能存明文。正确的做法是使用BCrypt或Spring Security自带的加密器对密码做哈希处理登录时用BCrypt.checkpw比对。如果你在项目里发现密码直接明文存储答辩时这就是被攻击的点——老师只要问一句“数据库泄露了怎么办”你就无言以对。4.2 库存扣减事务控制药品下单是整个系统里并发风险最高的操作。比如100个用户同时争抢库存仅剩3盒的药品如果代码写成“先查库存-判断足够-再减库存”在高并发场景下会产生严重的超卖问题。因为查库存和减库存两步之间有时间窗其他请求可能在这期间插进来大家都查到库存是3都以为自己能买结果最终扣成负数。正确做法是用数据库层面的原子更新加事务控制Transactional(rollbackFor Exception.class) public void deductStock(ListCartItem items) { for (CartItem item : items) { // 原子更新库存大于购买数量时才扣减 int rows drugInfoMapper.deductStock(item.getDrugId(), item.getQuantity()); if (rows 0) { throw new RuntimeException(库存不足商品 item.getDrugName()); } // 记录库存变动日志 drugStockLogService.recordLog(item.getDrugId(), -item.getQuantity(), ...); } }对应Mapper中的SQLUPDATE drug_info SET stock stock - #{quantity} WHERE drug_id #{drugId} AND stock #{quantity}注意这段SQL的巧妙之处它在一条语句里同时完成了“判断库存是否充足”和“扣减库存”两个操作利用数据库行锁保证了并发安全。如果影响行数为0说明条件不成立那就抛异常让整个事务回滚订单也不会创建。这种写法比你“先select后update”的方式在性能和安全性上高出不止一个档次。库存扣减还有两个细节需要注意。第一必须在Transactional里执行一旦后面的订单创建、明细写入任何一个环节报错库存能跟着回滚不会出现“钱没收到、药却扣了”的局面。第二可以额外设计一个库存预警机制——当库存低于预警值时后台首页会提示采购员补货这个逻辑在数据字典里有预警值字段。4.3 订单状态机与异常处理订单模块看起来只是简单的insert和update但真正折磨人的是各种边界状态。用户下单后不支付怎么办支付了但不发货怎么办发货了但用户要退货怎么办如果代码里没有约束就会出现任意状态跳到任意状态的混乱情况。我建议用一个私有方法集中处理状态流转public boolean changeOrderStatus(String orderNo, int targetStatus) { OrderInfo order this.getByOrderNo(orderNo); // 合法状态流转映射 MapInteger, ListInteger validTransitions new HashMap(); validTransitions.put(0, Arrays.asList(1, 5)); // 待支付 - 已支付 / 已取消 validTransitions.put(1, Arrays.asList(2)); // 已支付 - 已发货 validTransitions.put(2, Arrays.asList(3, 4)); // 已发货 - 已完成 / 已退款 ListInteger allowed validTransitions.get(order.getStatus()); if (allowed null || !allowed.contains(targetStatus)) { throw new BizException(非法的订单状态流转); } // 执行更新 }这200行不到的状态映射表是你答辩时说明“对业务有完整理解”的绝佳材料。老师问“你怎么保证订单状态不乱”你就可以拿这个类直接讲设计思路。订单模块还有几个容易遗漏的细节生成订单号要保证唯一且有序一般用时间戳加随机数或雪花算法保存收货地址要单独存字符串快照而不是存地址ID防止用户修改地址后历史订单地址跟着变删除订单只能做软删除避免破坏与明细表之间的引用关系。4.4 前端页面的核心交互逻辑前端部分药房购药系统的核心页面包括首页轮播图 药品展示 公告、药品列表分类筛选 关键词搜索 分页、药品详情、购物车页、订单结算页、个人中心、后台管理页。这里提两个前端页面里最值得优化的交互点。第一个是购物车数量加减的防抖处理。用户在购物车里面连续点击“”号时如果每次都发一次请求更新数据库会产生大量无用请求而且容易导致数据错乱。正确做法是前端在200毫秒内合并点击操作只发最后一次请求或者更稳妥的做法是购物车数量变动只在内存中操作等用户点击“去结算”时才批量提交后端。后端再根据提交的数据进行数量重新校验避免用户直接篡改价格或数量。第二个是订单提交前的秒杀式重复点击防护。用户点击“提交订单”后按钮立刻变成loading状态同时生成一个前端请求序列号后端判断该序列号是否已处理过处理过就直接返回结果而不是再建一次单。这些细节虽然不起眼但答辩时被问“系统有哪些安全设计”时你能说出这些点老师会非常认可。前端还有一块容易被忽视的是路由权限控制。Vue Router里定义路由meta信息比如meta: { roles: [admin] }路由守卫里根据当前用户的角色过滤。这不难但能让后台管理系统的不同角色进入不同菜单属于必须有的体验。5. 开发全流程记录与踩坑实录5.1 从建表到跑通首个接口的开发顺序很多同学拿到题目不知道先干什么。我梳理一个我认为最高效的开发顺序第一步画数据库ER图建表并插入测试数据。这一步花两天时间都不为过因为后续的所有代码都围绕表结构写。测试数据要造得像样药品名、批准文号、生产厂家都要真实比如“阿莫西林胶囊 0.25g*24粒 国药准字H20003263”这种。第二步搭后端骨架建项目、配置数据库连接、写实体类、Mapper先跑通一个登录接口。到这里你的项目已经能启动了。第三步实现用户端核心链路注册登录 - 药品列表 - 药品详情 - 加入购物车 - 提交订单 - 模拟支付 - 查看订单。这个流程打通之后系统的大梁就算是立住了。第四步实现后台核心链路药品CRUD - 分类管理 - 库存出入库 - 订单处理发货/取消 - 用户管理。到这里你的系统已经可以真实使用了。第五步做辅助功能轮播图管理、公告管理、数据统计图表、个人中心。这些都是锦上添花的内容工作量可控但非常提升完成度。最后是测试和补充用Postman把每个接口测一遍记录异常情况并修复检查权限接口是否被正确拦截处理前端控制台警告编写部署说明文档。5.2 前后端分离联调时的跨域问题前后端分离项目第一个拦路虎就是跨域。前端跑在5173端口后端跑在8080端口浏览器的同源策略会直接拦截Ajax请求控制台报错CORS policy。有三种主流解决方案一是在后端写全局跨域配置类二是前后端通过Nginx反向代理同一域名下转发三是用Spring Cloud Gateway之类的东西做网关代理。对毕设而言第一种最简单直接。Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }注意allowedOriginPatterns(*)与allowCredentials(true)必须同时使用只写allowedOrigins(*)在部分浏览器版本上会与credentials冲突。跨域问题排查不难但如果你不知道原理改半天代码都找不到问题在哪最后往往是后端过滤器把OPTIONS预检请求拦截了。5.3 MyBatis-Plus分页失效问题分页可以说是查询功能里必踩的坑。MyBatis-Plus使用分页需要配置一个分页插件Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; }如果你忘记配置这个插件调用selectPage不会报错但数据会全部返回分页完全失效。更隐蔽的问题是分页查询返回的total值默认是普通count如果数据量极大这种count是全表扫描的性能很差。MyBatis-Plus默认做了优化但如果你的查询SQL里包含多表joincount语句可能会统计出错误的总数需要手动指定optimizeCountSql或单独的处理方式。另一个常见问题是分页时带上条件查询MyBatis-Plus会自动拼接条件但如果你在条件里传了模糊匹配的搜索词而这个词带%或_这种SQL通配符就会导致查询结果异常。需要用QueryWrapper的like方法配合Escape处理或者自己手动转义。5.4 文件上传药品图片的存储策略药品管理里图片上传看似简单其实有个规划问题图片存到哪里常见三种方案。方案一是存本地磁盘上传路径写在配置文件里前端通过Nginx映射访问。这种方案适合毕设简单可靠但要注意服务器重启后路径配置不能写死。方案二是存到数据库的Blob字段但这种方案极度不推荐数据库文件过大会拖性能备份和迁移都是灾难。方案三是存到云端对象存储阿里云OSS/MinIO毕设用MinIO自建就够。如果不想引入额外组件方案一在本地环境足够了。上传接口用Spring Boot自带的MultipartFile接收配合Hutool的FileUtil生成随机文件名限制文件大小2MB校验文件后缀名。这些代码网上都有但你要能讲清楚为什么限制大小和类型答案是防恶意上传这属于系统安全设计的一部分。5.5 报表统计模块的数据组织药房系统的首页仪表盘通常要展示今日销售额、今日订单数、会员总数、库存预警药品数、近一周销售趋势图。这部分我用ECharts来实现效果很直观。数据库层面的做法是写聚合SQLSELECT DATE(create_time) AS order_date, SUM(total_amount) AS amount, COUNT(*) AS cnt FROM order_info WHERE create_time DATE_SUB(CURDATE(), INTERVAL 6 DAY) GROUP BY DATE(create_time) ORDER BY order_date;后端把这个List返回给前端前端ECharts直接把日期和金额作为x轴、y轴渲染成折线图。这部分在答辩时是非常出彩的展示亮点建议认真做。5.6 常见的启动与运行异常速查表记一份异常排查手册可以省掉很多上网搜索的时间。异常现象可能原因解决方案启动报Consider defining a bean of type xxxMapperMapper接口没有被扫描到在启动类加MapperScan注解前端请求返回401 UnauthorizedToken缺失或过期检查前端请求拦截器是否带了请求头用Postman直接测后端验证中文写入数据库变成?数据库连接URL未指定characterEncoding在JDBC URL中加?useUnicodetruecharacterEncodingutf8上传图片后访问404静态资源路径未映射配置WebMvcConfigurer的addResourceHandlersjava.sql.SQLException: Access denied for user数据库账号密码错误或权限不足在MySQL里执行GRANT ALL PRIVILEGES ON db_name.* TO rootlocalhost启动时端口被占用其他进程占了8080用netstat -anoRedis连接超时Redis未启动或密码错误启动Redis服务或检查密码如果使用Windows版Redis检查服务状态前端npm run dev启动失败Node版本过低或依赖不完整升级Node到16.20删掉node_modules重新安装6. 项目优化方向与答辩准备经验6.1 比基本功能再多走一步的优化方案如果你的系统已经按上述功能完成了且还有时间精力我建议按性价比从高到低挑几个方向做强化第一药品效期管理。在药品信息表中增加生产日期和有效期字段用定时任务扫描即将过期的药品假设有效期低于3个月在后台首页生成警告列表临期药品在列表页打上特殊标签。这个功能尤其贴合医药行业属性答辩时说“我用Scheduled定时任务实现了效期预警”这是非常亮眼的工程亮点。第二操作日志审计。用一个AOP切面记录管理员的所有敏感操作比如删除药品、修改价格、强制下架。在设计层面体现合规意识医药行业对操作留痕要求很高。第三订单超时未支付自动取消。用户下单后15分钟不支付订单自动关闭并回滚库存。这里有两个实现方案一是后端定时任务扫描超时订单批量处理二是使用延迟消息或者Redisson的延迟队列精准触发。毕设用定时任务就够了但如果你能主动讲出两种方案的区别说明你真的理解系统设计而不只是能写出代码。第四数据导入导出。药品信息支持Excel批量导入订单列表支持导出Excel。用EasyExcel或Hutool的Excel工具就能做工作量半天起步但“批量导入”功能对管理员来说很实用也是答辩时容易被追问的点。6.2 答辩时的高频问题与回答思路我能猜到你最紧张的是什么没错就是答辩。整理几个高频问题及回答思路老师问“你这个系统的角色权限是怎么实现的”回答主线RBAC模型 用户-角色多对多表 菜单权限拦截器。在拦截器里判断当前登录用户的角色标识决定哪些接口能访问。前端再根据角色渲染对应的菜单。强调RBAC的核心理念是“权限不直接绑定用户而是绑定角色”这样新增角色、调整权限不用改代码。老师问“药品库存你是怎么保证数据准确性的”回答主线数据库事务 原子更新SQL 库存变动日志。解释清楚UPDATE drug_info SET stock stock - quantity WHERE stock quantity这条SQL在并发场景下如何避免超卖事务回滚如何保证数据一致性库存日志如何实现事后追溯。这一套逻辑下来老师基本不会继续追问了。老师问“订单支付这块你做的是模拟支付安全和真实支付有什么区别”回答主线坦率回答这是模拟支付真实支付需要对接微信支付或支付宝流程包括下单时生成支付二维码、支付回调通知、回调验签、订单状态异步刷新。重点说出“真实支付的核心难点在于回调处理与幂等设计”展示出你对真实业务的理解而不是硬吹自己实现得多完善。老师问“你的系统有哪些地方可以继续优化”回答主线千万不要说“没有了”。准备两个方向一是引入Redis做缓存把药品热门数据查询放缓存降低数据库压力二是引入消息队列在订单高峰期削峰填谷提高系统的并发处理能力。这样既展示了你的问题意识也说明你有架构演进思维。6.3 源码管理与论文撰写的配合最后聊聊源码管理和论文。如果你用Git做版本管理每次写完一个功能模块就提交一次commit message写清功能含义比如feat: 实现购物车结算功能。答辩时展示Git提交记录能直观证明项目是你一步步做的而不是网上搬的。论文写作方面核心章节要对应系统设计第三章写系统分析第四章写系统设计功能模块图 数据库E-R图 表结构第五章写系统实现每个核心功能的截图 核心代码片段完美呼应。论文里引用的每张图表都是你系统里真实运行出来的这种真实性就是高分的基础。写在最后的一点体会做毕业设计这个东西说穿了是一个“一个人扮演一个团队”的过程。你可能要在同一个项目里同时当产品经理、后端工程师、前端工程师、测试工程师、部署运维还得当自己的答辩教练。这个过程确实累但请相信我只要你按“理解业务 - 拆分功能 - 设计数据 - 实现链路 - 打磨细节”的顺序走下来你得到的收获绝对不只是那一纸成绩单。你会在不知不觉里搞明白什么叫事务、什么叫状态机、什么叫权限模型而这些概念写在简历上比任何修饰词都更有说服力。这套药房购药系统不算难但也不简单它的业务闭环天然适合作为JavaWeb的综合性训练项目。不管你是打算照着这个思路自己写一遍还是拿到了完整源码想把它吃透改成自己的东西我的建议都一样把每个模块的代码读一遍自己动手改两个功能把数据库里的数据查一查然后在答辩前自己把系统从头到尾操作三遍。做到这个程度你就能自信地说——这个项目里每一行代码的意图你都清楚。祝顺利。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →