1. 项目概述
"药知道"家庭药事管理平台是一款基于SpringBoot框架开发的药品管理与服务系统,旨在为家庭用户提供一站式的药品信息查询、购买和管理服务。作为一个完整的毕业设计项目,它涵盖了从药品展示、购买到后台管理的全流程功能实现。
这个平台最核心的价值在于解决了家庭药品管理的三大痛点:
- 药品信息分散难查询
- 家庭药品库存管理混乱
- 药品购买渠道不透明
我在开发过程中特别注重系统的易用性和安全性,采用了前后端分离的架构设计,后端使用SpringBoot+MyBatis,前端采用Vue.js,数据库选用MySQL,确保系统既具备良好的性能表现,又能满足高并发的业务需求。
2. 技术选型与架构设计
2.1 后端技术栈
SpringBoot 2.7.0作为基础框架,主要基于以下考虑:
- 自动配置特性大幅减少了XML配置
- 内嵌Tomcat服务器简化部署流程
- 完善的Starter机制方便集成各种组件
- 活跃的社区和丰富的文档资源
数据库访问层采用MyBatis 3.5.6,相比Hibernate:
- SQL编写更灵活可控
- 性能优化空间更大
- 更适合复杂的业务查询场景
实际开发中发现,MyBatis的注解方式虽然简洁,但对于复杂SQL还是XML映射文件更易维护。建议在项目中统一使用XML配置方式。
2.2 前端技术方案
Vue 2.6 + Element UI构建管理后台,主要优势:
- 组件化开发提高代码复用率
- 响应式数据绑定简化DOM操作
- 丰富的UI组件库加速开发进程
- 完善的DevTools方便调试
移动端采用Uniapp框架,实现一套代码多端发布:
- 兼容微信小程序和H5
- 接近原生应用的体验
- 丰富的插件市场
2.3 系统架构设计
整体采用分层架构,分为:
- 表现层:Vue/Uniapp实现用户界面
- 业务逻辑层:SpringBoot处理核心业务
- 数据访问层:MyBatis操作数据库
- 数据存储层:MySQL持久化数据
这种架构的优点是:
- 各层职责明确,便于维护
- 组件松耦合,可独立扩展
- 适合团队协作开发
3. 核心功能实现
3.1 药品管理模块
3.1.1 药品基础信息管理
采用树形分类结构设计药品类别表:
@Entity @Table(name = "drug_category") public class DrugCategory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private Integer parentId; private Integer sort; // 其他字段... }药品信息表设计考虑因素:
- 药品通用名和商品名分开存储
- 规格字段支持多种单位
- 药品图片存储相对路径
- 设置库存预警阈值
3.1.2 库存管理实现
库存变更采用事务处理:
@Transactional public void updateStock(Long drugId, Integer quantity) { // 1. 检查库存是否充足 Drug drug = drugMapper.selectById(drugId); if(drug.getStock() < quantity) { throw new RuntimeException("库存不足"); } // 2. 更新库存 drugMapper.updateStock(drugId, quantity); // 3. 记录库存变更日志 StockLog log = new StockLog(drugId, quantity, "销售出库"); stockLogMapper.insert(log); }3.2 订单交易模块
3.2.1 购物车设计
购物车数据结构:
{ "userId": 123, "items": [ { "drugId": 456, "quantity": 2, "selected": true } ], "totalPrice": 58.00 }3.2.2 订单状态机
订单状态流转设计:
待支付 → 已支付 → 已发货 → 已完成 ↘ 已取消使用状态模式实现:
public interface OrderState { void pay(Order order); void cancel(Order order); void ship(Order order); void complete(Order order); } @Component @Scope("prototype") public class PaidState implements OrderState { // 实现各状态方法 }3.3 用户权限系统
3.3.1 RBAC模型设计
四张核心表:
- 用户表(user)
- 角色表(role)
- 权限表(permission)
- 用户角色关联表(user_role)
- 角色权限关联表(role_permission)
3.3.2 权限拦截实现
自定义注解进行权限控制:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermissions { String[] value(); } @Aspect @Component public class PermissionAspect { @Before("@annotation(requiresPermissions)") public void checkPermission(RequiresPermissions requiresPermissions) { // 权限校验逻辑 } }4. 关键问题与解决方案
4.1 药品搜索性能优化
问题:药品名称模糊查询性能差
解决方案:
- 添加药品名称前缀索引
ALTER TABLE drug ADD INDEX idx_name_prefix (name(10));- 使用Elasticsearch实现全文检索
- 引入缓存减轻数据库压力
4.2 高并发下单问题
问题:秒杀场景下超卖
解决方案:
- 乐观锁实现:
UPDATE drug SET stock = stock - 1 WHERE id = ? AND stock >= 1- Redis分布式锁:
public boolean tryLock(String key, long expire) { return redisTemplate.opsForValue() .setIfAbsent(key, "1", expire, TimeUnit.SECONDS); }- 消息队列削峰填谷
4.3 安全性设计
- SQL注入防护:
- 使用MyBatis参数绑定
- 禁止拼接SQL语句
- XSS防护:
- 前端使用vue-sanitize过滤
- 后端统一转义存储
- CSRF防护:
- 启用Spring Security的CSRF保护
- 重要操作增加二次确认
5. 部署与运维
5.1 服务器环境
推荐配置:
- 2核4G云服务器
- CentOS 7.6
- JDK 1.8
- MySQL 5.7
- Nginx 1.18
5.2 部署脚本
使用Shell脚本自动化部署:
#!/bin/bash # 停止现有服务 ps -ef | grep java | grep drug | awk '{print $2}' | xargs kill -9 # 备份旧版本 mv /app/drug.jar /app/backup/drug_$(date +%Y%m%d).jar # 部署新版本 cp target/drug-1.0.0.jar /app/drug.jar nohup java -jar /app/drug.jar --spring.profiles.active=prod > /app/logs/drug.log 2>&1 &5.3 监控方案
- Spring Boot Actuator健康检查
- Prometheus + Grafana监控
- ELK日志分析系统
6. 项目扩展方向
- 药品过期提醒功能
@Scheduled(cron = "0 0 9 * * ?") public void checkExpiredDrugs() { // 查询临近过期药品 // 发送提醒通知 }- 用药提醒服务
- 药品知识图谱构建
- 对接医保支付系统
7. 开发心得
数据库设计要预留扩展字段,比如在各表中添加extra_json字段
接口版本控制很重要,建议从v1开始:
/api/v1/drugs /api/v2/drugs- 日志规范建议:
- 使用SLF4J+Logback
- 区分access log和business log
- 重要操作记录操作日志
- 测试建议:
- 单元测试覆盖率不低于70%
- 使用Postman进行接口测试
- 压力测试使用JMeter
这个项目从技术选型到最终上线历时3个月,期间遇到了不少挑战,特别是库存并发控制和药品搜索性能优化方面。通过这个项目,我深刻体会到良好的架构设计对系统可维护性的重要性,也掌握了SpringBoot+Vue全栈开发的核心技能。