☰
基于Spring Boot+Vue的智能药箱系统:药品管理、库存预警与用药提醒实战解析
2026/10/17 4:53:53 网站建设 项目流程

智能药箱?听名字像是物联网硬件项目,实际做出来才明白,它更像是一个“药品领域的进销存+提醒服务”的管理系统。作为计算机毕业设计选题,Spring Boot+Vue这套前后端分离的技术组合,加上药品录入、库存预警、用药提醒这些贴近真实场景的业务模块,既能展示扎实的CRUD基本功,又能体现定时任务、权限控制、可视化统计这类加分项,是性价比很高的一个方向。这篇内容我把整个项目的拆解思路、核心实现和调试中容易踩的坑完整梳理一遍,方便正在做类似选题的同学直接参考。

1. 项目整体思路与选题定位

1.1 这个系统到底解决什么问题

先别急着打开代码。任何一个毕业设计项目,动手之前必须把“系统给谁用、用来干嘛”想清楚。智能药箱系统表面上是管理一个物理药箱,实际上可以拆成两个层面的需求:

  • 家庭个人用户层面:家里老人慢性病多,药盒里堆了一堆药,经常忘记吃、重复买、放过期。需要一个工具来记录药品信息、设置服药计划、到点提醒、库存不够时预警。
  • 药品管理层面:不管是家庭小药箱还是药店/医务室,药品都有入库、出库、库存盘点、有效期管理这些流程。系统本质上是一个带业务规则的药品信息管理系统。

明白了这一点,你就能在答辩时把“为什么做这个系统”讲得很有底气——它不是简单的增删改查,而是围绕药品生命周期(入库→存储→服用/出库→补货→过期处理)做了一套完整的业务闭环。

1.2 为什么技术栈选了Spring Boot + Vue

现在的Java毕设,十有八九是Spring Boot + Vue前后端分离。这个组合确实是最稳的选择,我拆开讲讲原因:

  • 后端Spring Boot:内置Tomcat,不用单独配置服务器;Starter机制让依赖管理变得极其简单;加上Spring生态自带的事务管理、AOP、定时任务支持,做药品提醒这类功能非常顺手。毕设答辩时,面试官或评委老师基本都懂这套,沟通成本低。
  • 前端Vue:Vue 3(或者Vue 2)配合Element Plus组件库,做后台管理界面效率极高。表格、表单、弹窗、选项卡都现成的,一个药品管理页面半天就能拼出来。Vue的双向绑定和数据响应式机制,做搜索筛选、联动选择这种交互特别方便。
  • 前后端分离的优势:接口文档定好,前后端可以并行开发;部署时也可以分开,前端扔Nginx,后端打包成Jar跑起来就行。还有个很实在的好处——答辩演示的时候,前端挂了可以单独修,后端崩了也不影响静态页面讲解,这是我在实践中发现的小优势。

1.3 项目的功能边界怎么定

我见过很多同学一上来就想做“大而全”,结果卡死在某个模块上。以智能药箱系统为例,我建议功能边界这样划分(按MVP优先级排序):

  • 第一优先级(必做):用户登录注册、药品信息CRUD、入库/出库记录、库存列表、有效期展示。
  • 第二优先级(体现含金量):库存预警(低于阈值变色提醒)、过期药品自动识别(通过@Scheduled定时任务扫库)、服药提醒(每天定时推送消息)、用药记录打卡。
  • 第三优先级(锦上添花):数据统计(ECharts展示药品分类占比、库存消耗趋势)、家庭成员多用户权限、药品二维码扫码识别、导出Excel报表。

如果时间紧张,第一优先级做完就能毕业,第二梯队的定时任务和预警做好就是“亮点功能”,第三梯队属于加分项,做不做得看个人进度。清醒地评估自己能力,比盲目堆功能强得多。

2. 核心业务模块与数据交互流程拆解

2.1 药品管理模块的底层逻辑

药品是整个系统的核心实体,但它不是孤立的一张表。我拆解一下围绕药品的数据流,你照着这个思路去设计后端接口,逻辑会非常清晰。

药品信息表(drug_info)建议字段:

字段名类型说明
idbigint主键
drug_namevarchar药品名称
batch_novarchar批号,用于区分不同批次
specvarchar规格,比如“0.5g*24片”
manufacturervarchar生产厂家
production_datedate生产日期
expire_datedate有效期至,核心字段
stock_quantityint当前库存数量
min_stockint库存预警阈值
categoryvarchar药品分类(心脑血管/感冒/肠胃等)
create_timedatetime创建时间

注意这里的批号字段非常关键。同一款药品,不同批次的过期时间可能不一样,所以药品信息表要允许同一名称多条记录,不能简单用“药品名”做唯一约束。很多初学者在这里踩坑:用药品名关联库存,结果不同批次的药全混在一起了。

业务操作主要分三类:

  • 入库:新增一条药品记录(或已有批次上增加库存),同时写一条入库记录明细(入库数量、来源、操作人)。
  • 出库:减少对应批次的库存数量,写一条出库记录(服用/取药/销毁等类型)。
  • 预警:查询时自动计算当前库存是否 <= min_stock,以及当前日期是否接近expire_date(比如30天内),前端展示预警标识。

2.2 用药提醒模块的设计思路

这是智能药箱系统区别于普通库存管理系统的地方。它本质上是一个定时任务 + 提醒记录的组合。

设计思路是:用户可以给自己或者家庭成员建立“用药计划”,例如每天早上8点吃降压药1片、晚上7点吃阿司匹林1片。每条计划包含:

  • 关联的药品ID
  • 用药时间(时分)
  • 每次剂量
  • 用药人(家庭成员)
  • 是否启用

后端用一个@Scheduled(cron = "0 0/30 * * * ?")的任务,每30分钟扫描一次用药计划表,把“当前时间到了但今日还没记录”的计划捞出来,生成一条提醒记录(可以是站内消息形式,演示时在首页消息列表展示;也可以预留对接微信/短信通知的扩展点)。

这里有个常见误区:有人想在数据库里存“下次提醒时间”,然后定时任务去查“时间到了没”。但用户调整服药时间后,这个字段很难同步处理。更优雅的做法是通过Cron表达式或执行规则推算,比如计划表存的是“HH:mm:ss”的用药时间,每次跑批时用当前时间比对,加上“今日是否已用药”的标记来判断要不要提醒,这样用户改时间后下一次跑批自动生效,不需要额外维护状态字段。

2.3 多角色权限划分与数据隔离

大多数系统会有两个角色:管理员和普通用户。

  • 普通用户:只能操作自己名下的药箱/药品数据,看自己的提醒和记录。
  • 管理员:可以查看全部用户列表、药品总览、统计数据,甚至停用某个违规账号。

在Spring Boot里实现RBAC权限模型,最简单的做法就是:

  1. 用户表加一个role字段(1管理员,0普通用户)。
  2. 登录接口返回JWT令牌时,把角色信息放进Payload里。
  3. 后端写一个拦截器或AOP注解(如@RequireAdmin),在Controller方法上标注需要的权限,拦截器从token解析角色,没权限就返回403。

前端Vue侧配合做路由守卫:根据角色动态生成菜单,没有管理员权限的账号,登录后根本看不到管理入口。这块做好了,答辩时讲“系统安全性设计”就有实质内容可讲,而不是干巴巴的一句“我们用了JWT”。

2.4 数据统计模块怎么做得好看又实用

毕设答辩时,评委老师大概率会问“系统有没有数据分析相关功能”。统计模块不需要复杂算法,但要用图表把业务跑起来的数据展示出来。我建议做三个维度的统计:

  • 药品分类占比:饼状图,展示心脑血管类、感冒类、肠胃类等各占库存总量的比例,用ECharts的一行配置就能实现。
  • 库存消耗趋势:折线图,统计近30天每天出库了多少件药品,观察用药高峰期。
  • 近效期药品TOP10:表格+进度条,把距离过期时间最短的10条药品列出来,用进度条组件展示剩余天数占比。

统计数据的SQL要写对,聚合类查询建议放在后端Service层做,前端只负责调接口拿数据组装图表。ECharts的配置项非常多,但常用的其实就那么几个:title、legend、xAxis、yAxis、series,复制官网示例改改数据就行,不需要背配置。

3. 核心技术实现与关键参数选型

3.1 后端项目结构与架构分层

我自己的习惯是严格按照controller → service → serviceImpl → mapper → entity分层,这个结构老套但最清晰。针对这个系统,我推荐这样组织包结构:

com.example.medbox ├── common // 通用返回结果、常量、异常处理 │ ├── Result.java │ ├── ResultCode.java │ └── GlobalExceptionHandler.java ├── config // 配置类:拦截器、跨域、定时任务 ├── controller // 接口层 │ ├── DrugController.java │ ├── StockRecordController.java │ ├── RemindPlanController.java │ └── UserController.java ├── entity // 数据库实体类 ├── mapper // MyBatis-Plus的Mapper接口 ├── service // 业务接口 ├── service.impl // 业务实现 └── utils // JWT工具类、日期工具类

这样的好处是:Controller层只接收参数和返回结果,所有业务判断都写在Service里,后期扩展也好找地方。比如药品入库和库存扣减必须在一个事务里,直接在ServiceImpl方法上标@Transactional即可,不要散落在Controller层各个位置。

3.2 数据库表设计要点与关联关系

核心表建议设计5~6张,别贪多:

表名作用关键关联
sys_user用户表与药品、计划关联
drug_info药品信息表关联用户ID
stock_record出入库记录表关联药品ID和用户ID
remind_plan服药计划表关联药品ID
remind_log提醒/打卡记录表关联计划ID
operation_log操作日志表(可选)记录关键操作

注意一个细节:stock_record出入库记录表建议设计为双向通用,用一个type字段区分1入库、2出库。这样查询历史流水时只需要一条SQL按时间排序,不用维护两张结构几乎一样的表。

关联关系上,所有业务表都加上user_id字段,用用户的ID做数据隔离查询条件。不要用Java代码去过滤数据,而是在SQL的条件里直接写WHERE user_id = #{userId},既避免全表扫描,也防止越权看到别人的数据。

3.3 JWT登录认证的核心配置

JWT(JSON Web Token)做登录认证是Java毕设的标配。原理不复杂,关键是签名密钥和过期时间的设置。

在application.yml中:

jwt: secret: your-secret-key-change-it expire: 86400000 # 24小时,单位毫秒

生成的Token放在HTTP请求头的Authorization字段中,格式为Bearer xxxxxx。

后端拦截器里解析Token:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录接口 String uri = request.getRequestURI(); if (uri.contains("/user/login") || uri.contains("/user/register")) { return true; } String token = request.getHeader("Authorization"); if (token == null || !token.startsWith("Bearer ")) { // 返回未认证状态 response.setStatus(401); return false; } try { Claims claims = JwtUtil.parseToken(token.substring(7)); request.setAttribute("userId", claims.get("userId")); return true; } catch (Exception e) { response.setStatus(401); return false; } }

这里有一个实践心得:JWT密钥千万不要明文写死在代码里,起码放到配置文件中。曾经见过一个项目把密钥硬编码在工具类里,结果所有用这套模板的同学生成的Token都一样,换个人登录还能用别人的身份,这是严重的安全漏洞,答辩的时候被问到就非常被动。

3.4 跨域处理与前端联调配置

前后端分离开发时,前端跑在http://localhost:5173(Vite默认端口),后端跑在http://localhost:8080,两个端口不一样,浏览器会拦截跨域请求。解决办法有三种:

  • 后端加CORS全局配置(推荐):写一个配置类实现WebMvcConfigurer,在addCorsMappings方法里放行所有来源。
  • 前端Vite代理:在vite.config.js里配置proxy,把/api开头的请求代理到后端。
  • Nginx反向代理:部署时统一入口,效果最好。

开发阶段用第一种最快,部署阶段用第三种,这个顺序能帮你省下大量排查问题的精力。

跨域配置参考:

@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); } }

需要注意:如果开启了allowCredentials(true),前端axios请求就不能只设请求头,还要在axios实例中配置withCredentials: true,否则会丢失Cookie相关的认证信息。

3.5 定时任务实现过期与库存预警

Spring Boot的定时任务用起来非常无脑,在主启动类加@EnableScheduling,然后在某个Service方法上写@Scheduled注解即可。

@Component public class DrugWarnTask { @Autowired private DrugInfoService drugInfoService; // 每天凌晨2点执行一次:检查所有药品是否临期 @Scheduled(cron = "0 0 2 * * ?") public void checkExpireDate() { List<DrugInfo> allDrugs = drugInfoService.list(); for (DrugInfo drug : allDrugs) { long days = calculateDays(drug.getExpireDate()); if (days <= 30 && days >= 0) { // 记录预警信息 drugInfoService.saveWarnMessage(drug); } } } }

Cron表达式的格式是秒 分 时 日 月 星期,写错是常有的事。“0 0 2 * * ?”代表每天凌晨2点执行,看不太懂的时候上工具网站验证一下,比反复测试效率高得多。

优化细节:如果药品数据量大,全表扫描效率低。可以考虑在SQL层面直接筛选,SELECT * FROM drug_info WHERE expire_date BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 30 DAY),让数据库帮你过滤,Java代码只管拿结果处理。

4. 实操过程与核心环节落地

4.1 开发环境版本组合与初始化

这个系统我用过的稳定版本组合如下,你直接参照,避免踩版本坑:

工具版本说明
JDK1.8 或 11更推荐JDK 11,Spring Boot 2.7完全支持
Maven3.8+不用最新版,3.8最稳
Spring Boot2.7.x不要直接上Spring Boot 3,有些依赖不兼容
MyBatis-Plus3.5.x配合代码生成器能省一半时间
MySQL8.0+注意时区配置
Node.js16+Vite 4需要
Vue3.x + Vite或者Vue 2 + Element UI,都行
Element Plus最新版组件丰富

环境初始化有一个值得注意的点:MySQL连接串一定要加时区参数。jdbc:mysql://localhost:3306/medbox?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai,不加serverTimezone大概率报错,尤其在MySQL 8.0版本下。

4.2 后端快速生成与核心接口开发

MyBatis-Plus配合代码生成器,可以把单表CRUD代码自动生成出来,但这只适合标准增删改查,业务接口还是得手写。

以“药品入库”为例,完整时序是:

  1. 前端提交入库表单,字段包括药品信息+入库数量。
  2. 后端DrugController接收DrugDTO。
  3. Service判断该药品是否已存在(按名称+批号)。
    • 存在:在原库存上增加数量。
    • 不存在:创建新药品记录,初始库存为入库数量。
  4. 写入stock_record表,type为1(入库),记录数量和操作时间。
  5. 返回成功结果。

这段逻辑花10分钟就能写完,但要注意并发场景:如果两个请求同时入库同一个批次,库存更新可能出错。解决方案很简单,SQL层面用原子操作:UPDATE drug_info SET stock_quantity = stock_quantity + #{num} WHERE id = #{id},而不是先查再set,这个细节在答辩时提出来很加分。

4.3 前端页面搭建与关键组件实现

前端页面我建议用Vue 3 + Vite + Element Plus + Axios + Vue Router + Pinia(或Vuex)这套组合。核心页面也就5个:登录页、首页数据看板、药品管理页、出入库记录页、提醒计划页(加一个用户管理页用于管理员)。

药品管理页是重头戏。列表展示用el-table,顶部搜索区放药品名称输入框和分类下拉框,右侧放“新增”“入库”“出库”按钮。

一个很实用的技巧:药品列表的状态列用el-tag组件展示。库存 < min_stock时显示“库存不足”红色标签;expire_date距今 < 30天时显示“临期”黄色标签;正常则显示“正常”绿色标签。这种视觉反馈是评委最容易记住的功能点。

Axios请求封装的代码参考:

import axios from 'axios' import { ElMessage } from 'element-plus' import router from '../router' const request = axios.create({ baseURL: '/api', timeout: 10000 }) // 请求拦截器:自动附带JWT request.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = 'Bearer ' + token } return config }) // 响应拦截器:统一处理401跳转登录 request.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { ElMessage.error(res.msg || '请求失败') return Promise.reject(new Error(res.msg)) } return res }, error => { if (error.response?.status === 401) { ElMessage.error('登录已过期,请重新登录') router.push('/login') } return Promise.reject(error) } ) export default request

把拦截器做好的好处是:后续所有接口调用的代码都简洁干净,不需要每个页面都处理Token和错误状态。这个属于“一次配置,长期受益”的环节。

4.4 药品过期自动预警与首页看板联动

预警功能要做成“首页直接能看见”,不要藏在二级页面里。我的建议是:首页放一个“温馨提示卡片”,优先展示三种预警信息:

  • 未来30天内到期的药品(名称+剩余天数)。
  • 库存低于阈值的药品(名称+当前库存量)。
  • 今日待服药计划(来自提醒任务生成的数据)。

后端提供一个聚合接口,比如/drug/count/status,分别返回三类数据的数量,前端卡片展示数字;再提供一个列表接口,点开卡片能看到详细清单。

这个聚合查询可以用一条SQL带条件统计,也可以用多个Service方法分别查询组成一个Map返回,看数据量决定。毕设场景数据量不大,直接多次查询然后组装即可,简单直接。

4.5 部署演示前的自检清单

毕设演示翻车往往不是功能没做出来,而是环境问题。我整理了一份演示前自检清单:

  • [ ] MySQL服务已启动,数据库脚本执行成功。
  • [ ] 后端Jar包重新打包(mvn clean package -DskipTests),本地端口没被占用。
  • [ ] 前端npm run build产物能正常访问,接口地址配置正确。
  • [ ] 测试账号能登录,且预置了至少10条药品数据(其中包含几条临期和库存不足的,方便演示预警效果)。
  • [ ] 定时任务触发的提醒消息,确保今天已经由跑批生成了一条。

第4条特别重要。演示系统之前,一定要先准备一套“刚好能展示亮点”的测试数据。如果数据库里全是正常的药品,预警功能演示时冷场了,真的很尴尬。

5. 常见问题与排查技巧实录

5.1 接口报跨域错误

现象:前端页面打不开接口,浏览器控制台提示No 'Access-Control-Allow-Origin' header is present。

排查思路:

  1. 确认是否走了后端CORS配置,Spring Boot 2.7的CORS配置写法和我上面给的代码基本一致。
  2. 确认请求方式是否为OPTIONS预检,预检请求被拦截器拦截也会报跨域错误,需要在拦截器中对OPTIONS请求直接放行。
  3. 如果使用的是前端代理,确认vite.config.js的proxy配置已经生效,修改后要重启前端服务。

解法:优先用前端代理解决开发阶段的跨域,生产部署用Nginx统一入口,后端CORS配置作为兜底方案。

5.2 登录成功但获取不到用户信息

现象:JWT签发成功,前端保存Token,刷新页面后接口请求401。

排查思路:这多半是Token解析或传递环节的问题。

  1. 先看前端请求头里的Authorization字段是否携带了Token,可以在浏览器F12的Network面板确认。
  2. 再看后端拦截器里request.getHeader("Authorization")取到的值是否包含Bearer前缀大小写混淆。
  3. 还有一个小众问题:JWT的密钥不匹配。如果后端配置里改过jwt.secret,但前端缓存的Token还是旧密钥签发的,解析必然失败。解决方法是重新登录一次。

5.3 MyBatis-Plus分页查询失效

现象:使用MyBatis-Plus的Page对象查询,返回的总条数正确但实际列表只有前面前几条。

排查思路:缺少分页插件!MyBatis-Plus使用分页功能必须配置PaginationInnerInterceptor,否则分页逻辑不会生效。

@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }

很多教程里都提过要配置这个插件,但很多同学直接从网上拷代码时漏掉了这一环。排查时先看控制台有没有打印出LIMIT关键字,没有就是插件没配置上。

5.4 前端表格时间字段显示异常

现象:后端返回的时间字段正常(比如2025-06-01 12:30:00),但前端页面显示成了数字时间戳。

排查思路:这是JSON序列化格式问题。Java端LocalDateTime默认序列化成数组或时间戳,需要在application.yml里配置统一格式:

spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8

如果用了@JsonFormat注解在某几个字段上,也要确保pattern一致,避免有的页面有格式、有的页面没格式。

5.5 定时任务不生效

现象:启动类加了@EnableScheduling,任务方法也写了@Scheduled,但到了时间就是没执行。

排查思路:

  1. 检查任务类是否被Spring扫描到,确保所在包在启动类扫描范围内,或者组件上加了@Component。
  2. 检查Cron表达式是否写错。举个例子,“每天中午12点执行”的表达式是0 0 12 * * ?,很多人把“秒”位漏掉了,写成0 12 * * ?,意思就变成每秒的第0秒+每分钟12秒执行,完全不是预期效果。
  3. 如果任务方法内部有异常被吞掉,也会出现“看起来没执行”。建议在方法内加日志输出,异常往上抛,方便定位。

5.6 生产环境部署刷新页面404

现象:前端打包后用Nginx部署,首页能打开,但直接访问某个路由页面(刷新浏览器)就404。

排查思路:Vue Router默认是history模式(地址中没有#号),需要Nginx配置try_files回退到index.html:

location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; }

这个问题高频率出现,调好了部署基本就稳了。如果不想自己配Nginx,也可以用hash模式,地址栏有个#号,但演示时不太好看。

5.7 代码打包后前端访问后端接口404

现象:本地开发接口都通,打包部署后用Nginx访问前端页面,接口却404。

排查思路:前端静态文件里的接口地址可能是相对路径,导致请求打到了Nginx服务器的某个路径下而没转发到后端。解决方法是:

  1. 前端统一把接口baseURL配置为/prod-api这类带环境标识的路径。
  2. Nginx做代理,把/prod-api开头的请求转发到http://localhost:8080。

生产环境部署的代理配置:

location /prod-api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }

5.8 时间不足时的优先级取舍

如果临近提交,功能还有缺口,我给你的建议优先级是:

  • 保住:登录注册、药品CRUD、出入库记录(这是系统根基)。
  • 保住:库存预警、临期提醒(这是智能化的体现,功能实现成本低)。
  • 争取:图表统计(ECharts复制示例改数据就行)。
  • 放弃:扫码识别、短信通知、多端小程序(这些需要外部依赖,开发成本和不可控因素都高,毕设阶段性价比低)。

答辩时,把已实现功能讲得逻辑自洽,远比重功能多但全是半成品有用得多。

6. 项目演示与毕业设计答辩的经验补充

6.1 演示脚本要提前走一遍

不要低估答辩当天“紧张”对操作的影响。提前写一页演示脚本,按顺序列出操作步骤:

  1. 用测试账号登录,展示首页预警卡片。
  2. 进入药品管理页,搜索某药品,展示列表和状态标签。
  3. 点击入库,新增一条记录,展示库存联动变化。
  4. 点击出库,展示库存减少。
  5. 进入提醒计划页,展示已生成的今日提醒。
  6. 切管理员账号,展示用户管理和统计图表。

照着脚本过两遍,比临场发挥了半天才发现库存数据不对要强得多。

6.2 答辩常见问题怎么应答

根据我带过的毕设经验,评委大概率会问这几类问题,提前把回答准备到位:

  • “为什么选这个课题?”回答思路:人口老龄化趋势+家庭用药管理痛点+药品流通管理需求。结合具体场景说,不要空谈。
  • “库存预警怎么实现的?”回答思路:先讲阈值字段设计min_stock,再讲查询时状态判断逻辑,最后补充定时任务+前端视觉反馈的组合。
  • “JWT安全性和过期策略?”回答思路:讲清单密钥存储、过期时间设置、拦截器校验逻辑,顺带提一下后续可以引入Spring Security增强。
  • “系统最大的难点是什么?”回答思路:不要说“没什么难点”。可以讲“不同批次药品的库存管理和有效期并发更新问题”,把自己踩过坑又解决了的过程讲清楚,这个回答比任何吹嘘都有说服力。
  • “系统还有哪些可扩展的地方?”回答思路:对接语音提醒、开发微信小程序、引入低库存自动下单、对接挂号平台电子处方等,方向很多,选两三个说透即可。

6.3 说明文档与设计文档的写作建议

毕设交付除了代码,最重要的就是设计文档和说明文档。建议结构如下:

  • 系统概述(背景、意义、目标)。
  • 需求分析(功能需求表、用例图)。
  • 系统设计(架构图、功能模块图、数据库ER图、表结构说明)。
  • 核心功能实现(关键代码片段+逻辑说明)。
  • 系统测试(测试用例表、测试结果截图)。

一个实用技巧:截图比文字管用。功能页面截图、数据库执行结果截图、接口测试截图,都尽力补充进去。文档的排版和完整度在评选中占的比重超乎想象,这一块花时间不亏。

6.4 个人经验总结

智能药箱这类基于Spring Boot + Vue的管理系统,做出来的同学很多,但真正拉开差距的,不在技术复杂度,而在于业务逻辑的完整性和演示效果的自洽性。把这个“药品从入库到过期”的闭环讲圆了,再把提醒和预警这两个亮点功能做扎实,最后把文档整理清爽,就是一个能拿得出手的优秀毕设项目。我在实际开发中最大的体会是:多花20%的精力把边界情况和异常流程处理好(比如重复入库、库存扣到负数、跨天提醒),在答辩和评审时的观感会远远好于一个功能很多但细节粗糙的系统。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询