在医药流通领域,高效精准的药品管理是保障企业正常运营和财务健康的核心。传统依赖手工台账或零散Excel表格的管理方式,常常导致信息记录分散、库存盘点不准、进销存流程脱节等问题,直接引发药品积压、缺货或过期等经营风险。医药流通企业、零售药店及医疗机构药房迫切需要一套集中化、流程化的数字管理平台来应对这些挑战。
该系统采用经典的三层架构模式,以SSH框架作为技术基石。表现层由Struts框架负责,通过Action类集中处理前端请求,利用Struts标签库简化JSP页面开发,实现了清晰的MVC分离。业务逻辑层依托Spring框架的IoC容器进行组件管理,通过声明式事务管理确保核心业务操作的原子性与数据一致性。数据持久层基于Hibernate实现对象关系映射,将药品、供应商、库存记录等实体类与数据库表关联,通过HQL进行复杂查询,显著提升了开发效率和系统可维护性。
数据库架构设计亮点
数据库设计充分考虑了药品管理业务的特殊性和数据完整性要求,其中几个核心表的设计尤为值得关注。
药品信息表的设计不仅包含了基础信息字段,还针对医药行业特性增加了关键控制字段:
CREATE TABLE drug (
drug_id INT PRIMARY KEY AUTO_INCREMENT,
drug_name VARCHAR(100) NOT NULL,
drug_specification VARCHAR(50),
manufacturer VARCHAR(100),
drug_type VARCHAR(30),
unit_price DECIMAL(10,2),
stock_quantity INT DEFAULT 0,
min_stock_level INT DEFAULT 10,
production_date DATE,
expiry_date DATE NOT NULL,
supplier_id INT,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (supplier_id) REFERENCES supplier(supplier_id)
);
该表通过expiry_date字段实现药品效期管理,min_stock_level字段支持库存预警功能,supplier_id外键关联确保供应商信息的完整性。这种设计为系统的核心业务逻辑提供了坚实的数据基础。
库存流水表采用细粒度记录方式,为库存追踪和审计提供了完整的数据支持:
CREATE TABLE inventory_transaction (
transaction_id INT PRIMARY KEY AUTO_INCREMENT,
drug_id INT NOT NULL,
transaction_type ENUM('PURCHASE','SALE','RETURN','ADJUSTMENT') NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10,2),
transaction_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
operator_id INT,
reference_no VARCHAR(50),
FOREIGN KEY (drug_id) REFERENCES drug(drug_id),
FOREIGN KEY (operator_id) REFERENCES employee(employee_id)
);
通过transaction_type枚举字段区分业务类型,结合reference_no字段与具体业务单据关联,实现了完整的库存变动追溯链条。
核心业务功能实现
药品采购入库流程
采购管理模块实现了从供应商选择到药品入库的全流程控制。系统通过Spring的声明式事务管理确保库存更新与财务记录的原子性。
@Service
@Transactional
public class PurchaseService {
@Autowired
private PurchaseDAO purchaseDAO;
@Autowired
private DrugDAO drugDAO;
@Autowired
private InventoryTransactionDAO inventoryTransactionDAO;
public void processPurchase(PurchaseOrder order, List<PurchaseItem> items) {
// 保存采购订单
purchaseDAO.save(order);
for (PurchaseItem item : items) {
// 更新药品库存
Drug drug = drugDAO.findById(item.getDrugId());
drug.setStockQuantity(drug.getStockQuantity() + item.getQuantity());
drugDAO.update(drug);
// 记录库存流水
InventoryTransaction transaction = new InventoryTransaction();
transaction.setDrugId(item.getDrugId());
transaction.setTransactionType(TransactionType.PURCHASE);
transaction.setQuantity(item.getQuantity());
transaction.setUnitPrice(item.getUnitPrice());
transaction.setReferenceNo(order.getOrderNo());
inventoryTransactionDAO.save(transaction);
}
}
}

采购流程中,系统自动生成采购单号,实时校验供应商资质,并在入库时同步更新库存数量和最近采购价格,为后续采购决策提供数据参考。
智能库存预警机制
库存管理模块通过Hibernate的查询机制实现多维度库存监控:
@Repository
public class InventoryDAOImpl implements InventoryDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public List<Drug> findLowStockDrugs() {
String hql = "FROM Drug d WHERE d.stockQuantity <= d.minStockLevel AND d.stockQuantity > 0";
Query query = sessionFactory.getCurrentSession().createQuery(hql);
return query.list();
}
@Override
public List<Drug> findExpiringDrugs(int days) {
String hql = "FROM Drug d WHERE d.expiryDate BETWEEN CURRENT_DATE AND :futureDate";
Query query = sessionFactory.getCurrentSession().createQuery(hql);
query.setParameter("futureDate", Date.valueOf(LocalDate.now().plusDays(days)));
return query.list();
}
}

系统支持设置库存下限预警和近效期预警,通过不同颜色标识风险等级,帮助管理人员及时采取应对措施。
销售出库与库存锁定
销售模块采用库存锁定机制防止超卖,确保库存数据的准确性:
@Controller
public class SalesAction extends ActionSupport {
private SalesService salesService;
private List<SalesItem> salesItems;
private String customerId;
public String execute() {
try {
SalesOrder order = salesService.createSalesOrder(customerId, salesItems);
addActionMessage("销售单创建成功,单号:" + order.getOrderNo());
return SUCCESS;
} catch (InsufficientStockException e) {
addActionError("库存不足,创建失败:" + e.getMessage());
return ERROR;
}
}
// Getter和Setter方法
public void setSalesService(SalesService salesService) {
this.salesService = salesService;
}
}

销售过程中,系统实时校验库存余量,对销售数量进行预占锁定,待出库完成后解除锁定并扣减实际库存。
实体模型与数据关系
系统的实体模型设计充分体现了业务领域的复杂性,通过Hibernate注解实现对象关系映射:
@Entity
@Table(name = "drug")
public class Drug implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "drug_id")
private Integer drugId;
@Column(name = "drug_name", nullable = false, length = 100)
private String drugName;
@Column(name = "drug_specification", length = 50)
private String specification;
@Column(name = "unit_price", precision = 10, scale = 2)
private BigDecimal unitPrice;
@Column(name = "stock_quantity")
private Integer stockQuantity = 0;
@Column(name = "min_stock_level")
private Integer minStockLevel = 10;
@Temporal(TemporalType.DATE)
@Column(name = "expiry_date")
private Date expiryDate;
@ManyToOne
@JoinColumn(name = "supplier_id")
private Supplier supplier;
@OneToMany(mappedBy = "drug", cascade = CascadeType.ALL)
private Set<InventoryTransaction> transactions = new HashSet<>();
// 省略getter和setter方法
}
供应商管理实体通过一对多关系与药品信息关联,支持复杂的业务查询:
@Entity
@Table(name = "supplier")
public class Supplier {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "supplier_id")
private Integer supplierId;
@Column(name = "supplier_name", nullable = false, length = 100)
private String supplierName;
@Column(name = "contact_person", length = 50)
private String contactPerson;
@Column(name = "contact_phone", length = 20)
private String contactPhone;
@Column(name = "supplier_status", length = 10)
private String status = "ACTIVE";
@OneToMany(mappedBy = "supplier")
private Set<Drug> suppliedDrugs = new HashSet<>();
// 省略getter和setter方法
}

系统安全与权限控制
系统采用基于角色的访问控制机制,通过Struts拦截器实现权限验证:
<!-- Struts配置中的拦截器栈 -->
<interceptor-stack name="secureStack">
<interceptor-ref name="authenticationInterceptor"/>
<interceptor-ref name="authorizationInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
员工管理模块支持多角色权限分配:
@Entity
@Table(name = "employee")
public class Employee {
@Id
@Column(name = "employee_id")
private String employeeId;
@Column(name = "employee_name", nullable = false, length = 50)
private String employeeName;
@Column(name = "password", nullable = false, length = 100)
private String password;
@Column(name = "role", length = 20)
private String role;
@Column(name = "department", length = 30)
private String department;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "last_login_time")
private Date lastLoginTime;
// 省略getter和setter方法
}

性能优化与数据一致性
系统在数据一致性方面采用了多种保障机制。通过Spring的声明式事务管理,确保关键业务操作的原子性:
@Service
@Transactional
public class InventoryService {
@Transactional(propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
rollbackFor = Exception.class)
public void adjustInventory(Integer drugId, Integer quantity,
String reason, String operator) {
Drug drug = drugDAO.findById(drugId);
if (drug == null) {
throw new DrugNotFoundException("药品不存在");
}
// 库存调整
int newQuantity = drug.getStockQuantity() + quantity;
if (newQuantity < 0) {
throw new InsufficientStockException("库存调整后数量不能为负");
}
drug.setStockQuantity(newQuantity);
drugDAO.update(drug);
// 记录调整流水
InventoryTransaction transaction = new InventoryTransaction();
transaction.setDrugId(drugId);
transaction.setTransactionType(TransactionType.ADJUSTMENT);
transaction.setQuantity(quantity);
transaction.setReferenceNo("ADJ_" + System.currentTimeMillis());
inventoryTransactionDAO.save(transaction);
}
}
在查询性能优化方面,系统通过Hibernate的二级缓存和查询优化提升响应速度:
<!-- Hibernate二级缓存配置 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
<property name="hibernate.cache.use_query_cache">true</property>
未来优化方向
移动端支持:开发基于React Native或Flutter的移动应用,支持库存盘点、销售开单等移动办公场景。通过RESTful API与现有系统集成,实现数据实时同步。
智能预测分析:引入机器学习算法,基于历史销售数据预测药品需求,实现智能补货建议。采用时间序列分析模型,考虑季节性因素和促销活动影响。
供应链协同:实现与供应商系统的API对接,支持电子数据交换,自动生成采购订单和收货确认,减少人工干预环节。
条码/RFID集成:集成硬件设备支持药品条码或RFID标签管理,实现快速入库、出库和盘点操作,大幅提升作业效率。
多仓库管理:扩展系统支持多仓库、多门店的分布式库存管理,实现库存调拨、虚拟库存合并等高级功能。
该系统通过严谨的架构设计和细致的业务功能实现,为医药流通企业提供了完整的数字化管理解决方案。基于SSH框架的技术选型确保了系统的稳定性和可扩展性,而针对医药行业特性的功能设计则切实解决了实际业务痛点。随着技术的不断发展和业务需求的演进,系统具备良好的扩展基础,能够持续为企业创造价值。