药店管理系统作为医药行业数字化转型的核心工具,其重要性在近年来愈发凸显。传统药店管理往往依赖手工记录和Excel表格,这种方式在药品数量增多、业务复杂度提升时暴露出诸多问题:库存数据滞后、处方审核流程混乱、销售统计效率低下等。我们团队基于实际药店运营痛点,开发了这套前后端分离的Web药店管理系统。
这套系统采用SpringBoot+Vue.js+MyBatis+MySQL技术栈,实现了药品全生命周期管理。与市面上常见的单体架构系统相比,我们的方案具有三大核心优势:
后端选择SpringBoot框架主要基于以下考虑:
前端采用Vue.js+ElementUI组合是因为:
数据库选用MySQL5.7版本,主要考虑因素包括:
系统采用经典的三层架构,各层职责明确:
code复制表示层(Vue.js)
↓
业务逻辑层(SpringBoot)
↓
数据访问层(MyBatis)
↓
数据存储层(MySQL)
关键设计要点:
药品基础信息采用CRUD标准操作,重点在于:
java复制// 生成规则:分类代码(2位)+厂家代码(3位)+序列号(5位)
public String generateProductCode(String categoryCode, String manufacturerCode) {
String serial = String.format("%05d", sequenceGenerator.next());
return categoryCode.substring(0,2) +
manufacturerCode.substring(0,3) +
serial;
}
sql复制-- 使用LOAD DATA INFILE提升导入性能
LOAD DATA INFILE '/tmp/products.csv'
INTO TABLE med_product_info
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
实时库存监控通过定时任务实现:
java复制@Scheduled(cron = "0 0/30 * * * ?")
public void checkInventory() {
// 查询库存量低于安全库存的药品
List<Product> lowStockProducts = productMapper.selectLowStockProducts();
lowStockProducts.forEach(product -> {
// 发送企业微信预警通知
wechatService.sendStockAlert(
product.getProductName(),
product.getStockQuantity()
);
// 记录预警日志
alertLogService.record(
product.getProductId(),
AlertType.STOCK
);
});
}
库存预警规则配置:
处方审核状态机设计:
mermaid复制stateDiagram
[*] --> 待审核
待审核 --> 已通过: 药师审核
待审核 --> 已驳回: 信息不全
已通过 --> 已配药: 药品发放
已驳回 --> 待审核: 重新提交
关键业务规则:
药品信息表(med_product_info)索引设计:
sql复制-- 主键索引
ALTER TABLE med_product_info ADD PRIMARY KEY (product_id);
-- 分类查询索引
CREATE INDEX idx_category ON med_product_info(category_code);
-- 组合查询索引
CREATE INDEX idx_name_manufacturer ON med_product_info(product_name, manufacturer);
销售记录表(med_sales_record)分区方案:
sql复制-- 按月份范围分区
PARTITION BY RANGE (TO_DAYS(sales_time)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
java复制// 使用Elasticsearch构建搜索服务
@Repository
public interface ProductSearchRepository extends ElasticsearchRepository<ProductEs, String> {
List<ProductEs> findByProductNameOrManufacturer(String name, String manufacturer);
}
sql复制-- 使用物化视图预计算
CREATE MATERIALIZED VIEW mv_daily_sales
REFRESH COMPLETE ON DEMAND
AS
SELECT
DATE(sales_time) AS sales_date,
product_id,
SUM(quantity) AS total_quantity,
SUM(total_amount) AS total_amount
FROM med_sales_record
GROUP BY DATE(sales_time), product_id;
前端开发环境配置:
bash复制# 安装依赖
npm install -g @vue/cli
npm install element-plus axios echarts
# 启动开发服务器
npm run serve
后端开发环境准备:
Docker Compose部署方案:
yaml复制version: '3'
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123456
volumes:
- ./mysql/data:/var/lib/mysql
redis:
image: redis:6
ports:
- "6379:6379"
backend:
build: ./pharmacy-backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./pharmacy-frontend
ports:
- "80:80"
Nginx配置要点:
code复制server {
listen 80;
server_name pharmacy.example.com;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
}
}
问题:SpringBoot应用启动报循环依赖错误
解决方案:
问题:Vue页面空白无内容
排查步骤:
处方审核流程卡顿优化:
库存数据不一致处理:
java复制@Update("UPDATE med_product_info SET stock_quantity=stock_quantity-#{qty}
WHERE product_id=#{id} AND stock_quantity>=#{qty}")
int reduceStockWithLock(@Param("id") String id, @Param("qty") int qty);
基于现有API快速开发小程序:
销售预测功能实现路径:
医保接口对接注意事项:
在项目实际落地过程中,我们发现药店业务存在很强的地域特性,建议二次开发时重点关注: