在医药零售行业数字化转型的浪潮中,一个高效、安全、合规的在线药品销售平台成为连接药店与消费者的重要桥梁。本文介绍的“医联商城”系统正是基于SSM框架构建的综合性医药电商解决方案,它严格遵循药品管理规范,同时具备现代电商平台的核心功能。
系统采用经典的三层架构模式:表现层使用SpringMVC框架处理用户请求和响应,业务层通过Spring框架管理核心业务逻辑,数据持久层则依托MyBatis实现与MySQL数据库的高效交互。这种架构确保了系统的高内聚、低耦合特性,为后续功能扩展和维护提供了良好基础。
数据库设计深度解析
系统的数据库设计充分体现了医药电商业务的特殊性,核心表结构设计严谨且符合业务规范。
药品信息表(medicine)的设计尤为关键,它不仅包含常规的商品属性,还增加了医药行业特有的字段约束:
CREATE TABLE medicine (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL COMMENT '药品名称',
description text COMMENT '药品描述',
price decimal(10,2) NOT NULL COMMENT '售价',
stock int(11) NOT NULL DEFAULT '0' COMMENT '库存数量',
prescription_flag tinyint(1) NOT NULL DEFAULT '0' COMMENT '处方药标志:0-非处方药 1-处方药',
manufacturer varchar(255) COMMENT '生产厂家',
approval_number varchar(100) COMMENT '批准文号',
category_id int(11) NOT NULL COMMENT '分类ID',
status tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:0-下架 1-上架',
create_time datetime DEFAULT CURRENT_TIMESTAMP,
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_category_id (category_id),
KEY idx_prescription_flag (prescription_flag),
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='药品信息表';
该表设计的亮点在于:处方药标志字段确保系统能够区分处方药与非处方药的销售流程;批准文号字段满足药品监管要求;状态字段实现药品的上下架管理;同时建立了合理的索引策略,优化查询性能。
订单表(orders)的设计体现了复杂的业务状态流转:
CREATE TABLE orders (
id int(11) NOT NULL AUTO_INCREMENT,
order_no varchar(50) NOT NULL UNIQUE COMMENT '订单编号',
user_id int(11) NOT NULL COMMENT '用户ID',
total_amount decimal(10,2) NOT NULL COMMENT '订单总金额',
status tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态:0-待支付 1-已支付 2-配送中 3-已完成 4-已取消',
prescription_approved tinyint(1) DEFAULT NULL COMMENT '处方审核状态:null-非处方药 0-待审核 1-审核通过 2-审核不通过',
payment_time datetime COMMENT '支付时间',
delivery_address text NOT NULL COMMENT '配送地址',
create_time datetime DEFAULT CURRENT_TIMESTAMP,
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_user_id (user_id),
KEY idx_order_no (order_no),
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
订单表通过status字段管理订单生命周期,prescription_approved字段专门处理处方药的审核流程,这种设计确保了处方药销售的合规性。唯一订单编号和复合索引的设置为系统的高并发处理提供了保障。
核心功能实现深度剖析
- 药品分类浏览与搜索功能
系统实现了一套完整的药品分类体系,支持用户按类别浏览和关键词搜索。前端页面采用响应式设计,确保在不同设备上都能提供良好的用户体验。

Controller层处理药品查询请求的核心代码:
@Controller
@RequestMapping("/medicine")
public class MedicineController {
@Autowired
private MedicineService medicineService;
@RequestMapping("/list")
public String listMedicines(
@RequestParam(value = "categoryId", required = false) Integer categoryId,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", defaultValue = "1") int pageNum,
Model model) {
int pageSize = 12;
Map<String, Object> params = new HashMap<>();
if (categoryId != null) {
params.put("categoryId", categoryId);
}
if (StringUtils.isNotBlank(keyword)) {
params.put("keyword", "%" + keyword + "%");
}
PageHelper.startPage(pageNum, pageSize);
List<Medicine> medicines = medicineService.findMedicinesByConditions(params);
PageInfo<Medicine> pageInfo = new PageInfo<>(medicines);
model.addAttribute("medicines", medicines);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("categoryId", categoryId);
model.addAttribute("keyword", keyword);
return "medicine/list";
}
}
Service层实现复杂的查询逻辑:
@Service
public class MedicineServiceImpl implements MedicineService {
@Autowired
private MedicineMapper medicineMapper;
@Override
public List<Medicine> findMedicinesByConditions(Map<String, Object> params) {
return medicineMapper.selectByConditions(params);
}
@Override
@Transactional(readOnly = true)
public Medicine findMedicineDetailById(Integer id) {
Medicine medicine = medicineMapper.selectByPrimaryKey(id);
if (medicine == null) {
throw new BusinessException("药品不存在");
}
return medicine;
}
}
- 处方药审核机制
系统对处方药销售实行严格的审核流程,确保符合医药监管要求。用户在购买处方药时需上传处方图片,待药师审核通过后才能完成购买。

处方审核服务的核心实现:
@Service
public class PrescriptionReviewServiceImpl implements PrescriptionReviewService {
@Autowired
private PrescriptionMapper prescriptionMapper;
@Autowired
private OrderMapper orderMapper;
@Override
@Transactional
public void reviewPrescription(Integer prescriptionId, Integer reviewerId,
Boolean approved, String reviewComments) {
Prescription prescription = prescriptionMapper.selectByPrimaryKey(prescriptionId);
if (prescription == null) {
throw new BusinessException("处方记录不存在");
}
if (!PrescriptionStatus.PENDING_REVIEW.equals(prescription.getStatus())) {
throw new BusinessException("处方不在待审核状态");
}
// 更新处方审核状态
prescription.setReviewerId(reviewerId);
prescription.setReviewTime(new Date());
prescription.setReviewComments(reviewComments);
prescription.setStatus(approved ? PrescriptionStatus.APPROVED : PrescriptionStatus.REJECTED);
prescriptionMapper.updateByPrimaryKey(prescription);
// 更新关联订单的处方审核状态
Orders order = orderMapper.selectByPrimaryKey(prescription.getOrderId());
order.setPrescriptionApproved(approved ? 1 : 2);
orderMapper.updateByPrimaryKey(order);
// 发送审核结果通知
sendReviewResultNotification(order.getUserId(), approved, reviewComments);
}
private void sendReviewResultNotification(Integer userId, Boolean approved, String comments) {
// 实现通知逻辑,如站内信、短信等
}
}
- 购物车与订单管理
系统实现了完整的购物车功能,支持商品添加、数量修改、批量删除等操作。订单生成过程包含库存校验、价格计算、处方药验证等多个业务环节。

购物车服务的关键代码:
@Service
public class CartServiceImpl implements CartService {
@Autowired
private CartMapper cartMapper;
@Autowired
private MedicineMapper medicineMapper;
@Override
@Transactional
public void addToCart(Integer userId, Integer medicineId, Integer quantity) {
// 验证药品存在且可售
Medicine medicine = medicineMapper.selectByPrimaryKey(medicineId);
if (medicine == null || medicine.getStatus() != 1) {
throw new BusinessException("药品不存在或已下架");
}
if (medicine.getStock() < quantity) {
throw new BusinessException("库存不足");
}
// 检查购物车中是否已存在该商品
Cart existingItem = cartMapper.selectByUserAndMedicine(userId, medicineId);
if (existingItem != null) {
// 更新数量
existingItem.setQuantity(existingItem.getQuantity() + quantity);
cartMapper.updateByPrimaryKey(existingItem);
} else {
// 新增购物车项
Cart cartItem = new Cart();
cartItem.setUserId(userId);
cartItem.setMedicineId(medicineId);
cartItem.setQuantity(quantity);
cartItem.setCreateTime(new Date());
cartMapper.insert(cartItem);
}
}
@Override
public List<CartVO> getCartDetails(Integer userId) {
return cartMapper.selectCartDetailsByUserId(userId);
}
}
订单生成的核心业务逻辑:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private MedicineMapper medicineMapper;
@Override
@Transactional
public String createOrder(Integer userId, List<CartItemDTO> cartItems, String deliveryAddress) {
// 生成订单号
String orderNo = generateOrderNo();
// 计算总金额并验证库存
BigDecimal totalAmount = BigDecimal.ZERO;
List<OrderItem> orderItems = new ArrayList<>();
for (CartItemDTO item : cartItems) {
Medicine medicine = medicineMapper.selectByPrimaryKey(item.getMedicineId());
if (medicine.getStock() < item.getQuantity()) {
throw new BusinessException(medicine.getName() + "库存不足");
}
BigDecimal itemTotal = medicine.getPrice().multiply(new BigDecimal(item.getQuantity()));
totalAmount = totalAmount.add(itemTotal);
OrderItem orderItem = new OrderItem();
orderItem.setMedicineId(item.getMedicineId());
orderItem.setQuantity(item.getQuantity());
orderItem.setPrice(medicine.getPrice());
orderItem.setItemTotal(itemTotal);
orderItems.add(orderItem);
}
// 创建订单主记录
Orders order = new Orders();
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalAmount(totalAmount);
order.setStatus(OrderStatus.PENDING_PAYMENT);
order.setDeliveryAddress(deliveryAddress);
orderMapper.insert(order);
// 保存订单明细
for (OrderItem item : orderItems) {
item.setOrderId(order.getId());
orderItemMapper.insert(item);
// 扣减库存
medicineMapper.decreaseStock(item.getMedicineId(), item.getQuantity());
}
return orderNo;
}
}
- 后台管理系统
系统提供完善的后台管理功能,支持药品管理、订单处理、用户管理、分类管理等。管理员可以实时监控系统运行状态,处理处方审核等业务。

药品管理Controller实现:
@Controller
@RequestMapping("/admin/medicine")
public class AdminMedicineController {
@Autowired
private MedicineService medicineService;
@RequestMapping("/manage")
public String manageMedicines(
@RequestParam(value = "page", defaultValue = "1") int pageNum,
@RequestParam(value = "status", required = false) Integer status,
Model model) {
int pageSize = 15;
Map<String, Object> params = new HashMap<>();
if (status != null) {
params.put("status", status);
}
PageHelper.startPage(pageNum, pageSize);
List<Medicine> medicines = medicineService.findMedicinesByConditions(params);
PageInfo<Medicine> pageInfo = new PageInfo<>(medicines);
model.addAttribute("medicines", medicines);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("status", status);
return "admin/medicine/manage";
}
@PostMapping("/updateStatus")
@ResponseBody
public ResponseEntity<?> updateMedicineStatus(
@RequestParam Integer medicineId,
@RequestParam Integer status) {
try {
medicineService.updateMedicineStatus(medicineId, status);
return ResponseEntity.ok().build();
} catch (BusinessException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
}
实体模型设计
系统的实体模型设计充分体现了领域驱动设计的思想,核心实体包括用户(User)、药品(Medicine)、订单(Order)、购物车(Cart)等。这些实体通过MyBatis的映射文件与数据库表建立对应关系,实现了对象关系映射的完整解决方案。
MyBatis映射文件示例:
<!-- MedicineMapper.xml -->
<mapper namespace="com.pharmacy.mapper.MedicineMapper">
<resultMap id="BaseResultMap" type="com.pharmacy.entity.Medicine">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="description" property="description" jdbcType="VARCHAR"/>
<result column="price" property="price" jdbcType="DECIMAL"/>
<result column="stock" property="stock" jdbcType="INTEGER"/>
<result column="prescription_flag" property="prescriptionFlag" jdbcType="TINYINT"/>
<result column="manufacturer" property="manufacturer" jdbcType="VARCHAR"/>
<result column="approval_number" property="approvalNumber" jdbcType="VARCHAR"/>
<result column="category_id" property="categoryId" jdbcType="INTEGER"/>
<result column="status" property="status" jdbcType="TINYINT"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
</resultMap>
<select id="selectByConditions" parameterType="map" resultMap="BaseResultMap">
SELECT * FROM medicine
WHERE status = 1
<if test="categoryId != null">
AND category_id = #{categoryId}
</if>
<if test="keyword != null">
AND (name LIKE #{keyword} OR description LIKE #{keyword})
</if>
ORDER BY create_time DESC
</select>
<update id="decreaseStock">
UPDATE medicine
SET stock = stock - #{quantity}, update_time = NOW()
WHERE id = #{medicineId} AND stock >= #{quantity}
</update>
</mapper>
系统优化与功能扩展方向
智能推荐系统:基于用户购买历史和浏览行为,构建药品推荐算法。可以采用协同过滤或基于内容的推荐技术,通过分析药品属性相似度和用户偏好模式,实现个性化推荐。
药品溯源功能:集成区块链技术,建立药品流通溯源体系。每批药品从生产到销售的全流程信息上链存储,消费者可通过扫码验证药品真伪和流通路径。
在线问诊与电子处方:接入第三方互联网医院服务,实现在线问诊、电子处方开具一体化流程。通过API接口与合规的互联网医疗平台对接,完善处方药销售闭环。
库存预警与自动补货:建立智能库存管理系统,设置库存阈值预警,当库存低于安全水平时自动生成补货订单。可以结合销售预测算法,优化库存周转率。
移动端深度优化:开发原生移动应用,利用PWA技术提升移动端用户体验。增加扫码购药、用药提醒、健康档案等特色功能,增强用户粘性。
大数据分析平台:构建数据分析看板,对销售数据、用户行为、药品流行趋势进行多维度分析。为经营决策提供数据支持,实现精细化运营。
系统在技术实现上充分考虑了医药电商的特殊性,通过严格的权限控制、数据验证和业务流程设计,确保了平台的合规性和安全性。SSM框架的稳定性和扩展性为系统的长期演进提供了坚实的技术基础。随着医药电商政策的逐步放开和技术的不断发展,该系统具有良好的市场适应性和扩展潜力。