这个鲜牛奶订购系统是我去年为本地一家乳制品企业开发的线上销售平台。作为一个典型的JavaWeb应用,它解决了传统鲜奶订购中存在的管理混乱、订单处理效率低下等问题。系统采用前后端分离架构,前端使用Vue.js构建用户界面,后端基于Spring Boot框架开发,数据库选用MySQL 5.7。
在实际开发过程中,我发现鲜奶订购有几个特殊需求:一是需要处理每日配送的周期性订单,二是要考虑产品的保质期管理,三是需要支持灵活的配送地址设置。这些特性使得这个项目比普通电商系统更具挑战性。
选择Spring Boot+Vue的组合主要基于以下考虑:
java复制// 典型的Spring Boot启动类配置
@SpringBootApplication
@MapperScan("com.xiannai.mapper")
public class XiannaiApplication {
public static void main(String[] args) {
SpringApplication.run(XiannaiApplication.class, args);
}
}
系统采用经典的三层架构:
提示:在商品详情页我们加入了Redis缓存,将查询性能提升了3倍
鲜奶订购的特殊性在于客户通常需要设置周期性配送(如每周一、三、五)。我们设计了专门的订单调度模块:
java复制// 订单调度服务核心逻辑
@Service
public class OrderScheduleService {
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
public void generateDailyOrders() {
// 查询所有周期性订单
List<Subscription> subscriptions = subscriptionMapper.selectActiveSubscriptions();
// 生成当日订单
subscriptions.forEach(sub -> {
if(shouldDeliverToday(sub.getDeliveryDays())) {
Order order = createOrderFromSubscription(sub);
orderMapper.insert(order);
}
});
}
}
考虑到鲜奶的短保质期特性,系统实现了先进先出(FIFO)的库存管理策略:
sql复制-- 临期商品预警查询
SELECT * FROM xiannai_stock
WHERE expiry_date < DATE_ADD(NOW(), INTERVAL 2 DAY)
AND quantity > 0;
主要表包括:
sql复制CREATE TABLE `xiannai_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_uuid` varchar(32) NOT NULL COMMENT '订单编号',
`user_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`quantity` int(11) NOT NULL COMMENT '订购数量',
`delivery_date` date NOT NULL COMMENT '配送日期',
`delivery_time` varchar(20) NOT NULL COMMENT '配送时段',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0-待支付 1-已支付 2-配送中 3-已完成',
`is_recurring` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否周期性订单',
`recurring_pattern` varchar(50) DEFAULT NULL COMMENT '周期模式:1,3,5表示周一三五',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_order_uuid` (`order_uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
为提高查询性能,我们在以下字段建立了索引:
购物车需要考虑鲜奶的特殊性:
前端实现代码片段:
javascript复制// Vue组件中的购物车逻辑
methods: {
addToCart() {
if(this.selectedDates.length === 0) {
this.$message.error('请至少选择一个配送日期');
return;
}
this.selectedDates.forEach(date => {
const cartItem = {
productId: this.product.id,
date: date,
quantity: this.quantity
};
this.$store.dispatch('cart/addItem', cartItem);
});
}
}
支付流程做了以下特殊处理:
支付状态机设计:
java复制public enum OrderStatus {
PENDING_PAYMENT, // 待支付
PAID, // 已支付
DELIVERING, // 配送中
COMPLETED, // 已完成
CANCELLED, // 已取消
REFUNDED // 已退款
}
我们使用Docker Compose部署整套系统:
yaml复制version: '3'
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: xiannai123
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:alpine
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
数据库层面:
应用层面:
前端层面:
日期处理问题:
库存并发问题:
java复制@Transactional
public boolean reduceStock(Long productId, int quantity) {
// 使用悲观锁锁定商品记录
Product product = productMapper.selectForUpdate(productId);
if(product.getStock() >= quantity) {
product.setStock(product.getStock() - quantity);
productMapper.updateById(product);
return true;
}
return false;
}
调试技巧:
开发效率提升:
测试建议:
目前系统已经稳定运行半年,后续计划增加:
对于想扩展功能的开发者,我建议:
这个项目从设计到上线共耗时3个月,期间遇到了不少挑战,但也积累了宝贵的实战经验。最大的体会是:对于生鲜类电商系统,业务逻辑的准确性比炫酷的功能更重要。特别是在库存和订单管理上,必须做到百分之百可靠。