## 前言
随着同城即时零售的快速发展,传统线下烟酒门店、酒水经销商普遍面临客流下滑、配送效率低、会员体系缺失、运营数据分散等痛点。搭建一套专属的酒水配送小程序,既能突破线下门店的地理限制拓展线上订单,又能实现库存、订单、配送、会员的一体化数字化管理。
本文从全栈开发视角拆解一套可落地的同城酒水配送小程序的完整技术架构,并分享核心业务模块的代码实现,适用于酒行、酒庄、烟酒供应链等场景的定制开发。
---
## 一、技术栈选型
### 1.1 前端层
- **用户端/配送端**:微信小程序原生框架 + Vant Weapp 组件库,保证加载速度与原生体验
- **商家管理后台**:Vue3 + Element Plus,支持PC端商品、订单、财务全流程管理
### 1.2 后端服务
- 核心框架:Spring Boot 2.7.x + MyBatis-Plus
- 接口规范:RESTful API,统一返回结果封装
### 1.3 存储与中间件
- 关系型数据库:MySQL 8.0,存储商品、订单、用户、财务等核心数据
- 缓存数据库:Redis 6.x,缓存热点商品、库存、Token、分布式锁
- 消息队列:RabbitMQ,处理订单异步通知、配送派单、超时取消等场景
### 1.4 第三方能力
- 支付:微信支付V3接口
- 地图:腾讯地图API,实现定位、距离计算、配送路径规划
- 消息:微信订阅消息,推送订单状态、配送通知
---
## 二、系统整体架构
系统采用经典的分层架构设计,自上而下分为**表现层、网关层、业务服务层、数据访问层、数据层**,同时按端侧划分为用户小程序、配送员小程序、商家后台、平台管理端四大部分。
### 2.1 核心业务流转
用户在小程序选品下单 → 后端校验库存与价格 → 生成订单并调用微信支付 → 支付成功后扣减库存 → 自动派单给附近配送员 → 配送员接单配送 → 用户确认收货 → 订单完成并结算佣金。
### 2.2 架构分层说明
| 层级 | 职责说明 |
| --- | --- |
| 表现层 | 面向C端用户、配送员、商家、管理员的多端交互入口 |
| 网关层 | 接口鉴权、流量控制、请求路由、日志记录 |
| 业务服务层 | 商品、订单、支付、配送、会员、营销等核心业务逻辑 |
| 数据访问层 | 数据库读写、缓存操作、第三方接口调用封装 |
| 数据层 | MySQL持久化存储、Redis缓存、文件存储 |
---
## 三、核心功能模块拆解
1. **商品管理模块**:多分类商品管理、库存实时同步、规格/套餐配置、上下架管控
2. **订单交易模块**:购物车、下单结算、微信支付、订单状态流转、退款售后
3. **配送调度模块**:配送员接单/转单、定位追踪、距离计算、配送费自动核算
4. **会员营销模块**:会员等级、积分体系、优惠券、满减活动、新人礼包
5. **数据统计模块**:营业额、订单量、商品销量、配送效率等多维度报表
---
## 四、核心代码实现
### 4.1 小程序端:商品列表加载与分页查询
```
// pages/goods/list.js
Page({
data: {
categoryList: [],
goodsList: [],
pageNum: 1,
pageSize: 10,
hasMore: true,
loading: false
},
onLoad() {
this.loadCategory();
this.loadGoodsList();
},
// 加载商品分类
loadCategory() {
wx.request({
url: getApp().globalData.baseUrl + '/api/goods/category',
success: (res) => {
if (res.data.code === 200) {
this.setData({ categoryList: res.data.data });
}
}
});
},
// 分页加载商品列表
loadGoodsList() {
if (!this.data.hasMore || this.data.loading) return;
this.setData({ loading: true });
wx.request({
url: getApp().globalData.baseUrl + '/api/goods/page',
data: {
pageNum: this.data.pageNum,
pageSize: this.data.pageSize,
categoryId: this.data.currentCategoryId
},
success: (res) => {
if (res.data.code === 200) {
const newList = res.data.data.records;
this.setData({
goodsList: this.data.pageNum === 1 ? newList : [...this.data.goodsList, ...newList],
hasMore: res.data.data.current < res.data.data.pages,
pageNum: this.data.pageNum + 1
});
}
},
complete: () => {
this.setData({ loading: false });
}
});
},
// 上拉加载更多
onReachBottom() {
this.loadGoodsList();
}
});
```
### 4.2 后端:订单创建核心接口(SpringBoot)
```
@Service
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl implements OrderService {
@Autowired
private GoodsService goodsService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private WxPayService wxPayService;
@Override
public OrderCreateVO createOrder(OrderCreateDTO dto, Long userId) {
// 1. 参数校验
if (CollectionUtils.isEmpty(dto.getGoodsItems())) {
throw new BusinessException("商品不能为空");
}
// 2. 库存校验与价格计算(Redis分布式锁防止超卖)
String lockKey = "lock:stock:" + dto.getStoreId();
RLock lock = redissonClient.getLock(lockKey);
lock.lock(10, TimeUnit.SECONDS);
try {
BigDecimal totalAmount = BigDecimal.ZERO;
List<OrderItem> orderItemList = new ArrayList<>();
for (GoodsItemDTO item : dto.getGoodsItems()) {
Goods goods = goodsService.getById(item.getGoodsId());
if (goods == null || goods.getStatus() != 1) {
throw new BusinessException("商品已下架");
}
if (goods.getStock() < item.getQuantity()) {
throw new BusinessException(goods.getName() + "库存不足");
}
// 扣减库存
goodsService.updateStock(item.getGoodsId(), item.getQuantity());
// 计算小计
BigDecimal subtotal = goods.getPrice().multiply(new BigDecimal(item.getQuantity()));
totalAmount = totalAmount.add(subtotal);
// 构建订单项
OrderItem orderItem = new OrderItem();
orderItem.setGoodsId(goods.getId());
orderItem.setGoodsName(goods.getName());
orderItem.setPrice(goods.getPrice());
orderItem.setQuantity(item.getQuantity());
orderItem.setSubtotal(subtotal);
orderItemList.add(orderItem);
}
// 3. 计算配送费、优惠后实付金额
BigDecimal deliveryFee = calculateDeliveryFee(dto.getAddressId());
BigDecimal discountAmount = calculateDiscount(userId, totalAmount, dto.getCouponId());
BigDecimal payAmount = totalAmount.add(deliveryFee).subtract(discountAmount);
// 4. 生成订单
String orderNo = generateOrderNo();
Order order = new Order();
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalAmount(totalAmount);
order.setDeliveryFee(deliveryFee);
order.setDiscountAmount(discountAmount);
order.setPayAmount(payAmount);
order.setStatus(OrderStatusEnum.UNPAID.getCode());
order.setOrderType(dto.getOrderType());
this.save(order);
// 5. 批量保存订单项
orderItemList.forEach(item -> item.setOrderId(order.getId()));
orderItemService.saveBatch(orderItemList);
// 6. 调用微信支付,返回支付参数
WxPayVO payVO = wxPayService.createJsapiPay(orderNo, payAmount, userId);
// 7. 订单超时取消(延迟队列)
rabbitTemplate.convertAndSend("order.delay.exchange", "order.delay.key", orderNo,
message -> {
message.getMessageProperties().setDelay(30 * 60 * 1000); // 30分钟超时
return message;
});
return OrderCreateVO.builder()
.orderId(order.getId())
.orderNo(orderNo)
.payAmount(payAmount)
.payInfo(payVO)
.build();
} finally {
lock.unlock();
}
}
}
```
### 4.3 微信支付异步回调处理
```
@RestController
@RequestMapping("/api/pay/notify")
public class WxPayNotifyController {
@Autowired
private WxPayService wxPayService;
@Autowired
private OrderService orderService;
@PostMapping("/wx")
public String wxPayNotify(HttpServletRequest request) {
try {
// 1. 解析并验签回调数据
WxPayNotifyVO notifyVO = wxPayService.parseNotify(request);
if ("SUCCESS".equals(notifyVO.getTradeState())) {
String orderNo = notifyVO.getOutTradeNo();
String transactionId = notifyVO.getTransactionId();
// 2. 更新订单状态为已支付
orderService.paySuccess(orderNo, transactionId);
// 3. 异步通知商家、触发配送派单
rabbitTemplate.convertAndSend("order.pay.success.exchange", "", orderNo);
// 返回成功响应
return WxPayResponse.success();
}
} catch (Exception e) {
log.error("微信支付回调异常", e);
}
return WxPayResponse.fail();
}
}
```
---
## 五、关键优化点
1. **库存超卖防控**:采用Redis分布式锁 + 数据库乐观锁双重机制,高并发场景下保证库存准确
2. **配送效率优化**:基于腾讯地图的距离计算接口,自动匹配最近配送员,智能核算配送费
3. **小程序性能优化**:采用分包加载、图片懒加载、接口数据缓存,首屏加载时间控制在1.5s内
4. **订单可靠性保障**:延迟队列处理超时订单,消息队列解耦支付、派单、通知流程
---
## 六、写在最后
这套同城酒水配送系统支持**模板快速上线**与**全原生定制开发**两种模式,可根据商家规模按需适配,完整源码交付,不绑定第三方平台。
目前已在山东多地酒水商家落地运行,支持多门店管理、分销体系、酒水溯源等扩展功能。东营及周边地区可上门对接需求,按需定制功能模块。
>
> 技术交流或定制开发需求,可进一步沟通探讨。
#微信小程序开发 #SpringBoot #同城配送系统 #酒水小程序 #Java后端开发 #小程序架构设计