校園外賣系統和社會化外賣最大的不同,在於場景高度集中、時間高度重疊、規則相對固定。如果直接套用通用外賣模型,往往在高峯期會出現訂單擁堵、配送混亂的問題。因此,在設計校園外賣系統小程序時,從下單到配送的業務邏輯必須更“剋制”、更清晰。
下面我們從業務流程 → 數據模型 → 關鍵代碼實現三個層面,拆解校園外賣系統的核心實現思路。
一、整體業務流程拆解
一個標準的校園外賣系統小程序,下單到完成配送,大致分為 6 個階段:
- 用户選餐並提交訂單
- 系統校驗下單條件(時間、庫存、配送範圍)
- 商家接單並出餐
- 系統進入“待配送”狀態
- 配送人員接單並完成配送
- 訂單完成,進入結算與統計
在校園場景下,訂單狀態流轉的穩定性,比複雜的營銷玩法更重要。
二、核心數據模型設計
1. 訂單表(order)
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
shop_id BIGINT NOT NULL,
total_amount DECIMAL(10,2),
status VARCHAR(20),
delivery_type VARCHAR(20),
created_at DATETIME,
updated_at DATETIME
);
常見訂單狀態設計:
CREATED // 已下單
PAID // 已支付
ACCEPTED // 商家已接單
PREPARING // 商家制作中
WAIT_DELIVERY // 待配送
DELIVERING // 配送中
COMPLETED // 已完成
CANCELLED // 已取消
2. 訂單商品表(order_item) CREATE TABLE order_items ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, goods_id BIGINT, goods_name VARCHAR(100), price DECIMAL(10,2), quantity INT );
三、小程序端:下單核心代碼示例
1. 提交訂單(小程序)
// submitOrder.js
submitOrder() {
const orderData = {
shopId: this.data.shopId,
goodsList: this.data.cartList,
deliveryType: 'CAMPUS_DELIVERY'
}
wx.request({
url: '/api/order/create',
method: 'POST',
data: orderData,
success: res => {
if (res.data.code === 0) {
wx.navigateTo({
url: `/pages/pay/index?orderId=${res.data.orderId}`
})
}
}
})
}
這裏要注意兩點:
不在小程序端計算最終金額(防止篡改)
所有價格以後台計算為準
四、後端:創建訂單的核心邏輯
public Long createOrder(CreateOrderDTO dto, Long userId) {
// 1. 校驗商家狀態
Shop shop = shopService.getById(dto.getShopId());
if (!shop.isOpen()) {
throw new BizException("商家未營業");
}
// 2. 計算訂單金額
BigDecimal totalAmount = BigDecimal.ZERO;
for (OrderGoodsDTO goods : dto.getGoodsList()) {
totalAmount = totalAmount.add(
goods.getPrice().multiply(
BigDecimal.valueOf(goods.getQuantity())
)
);
}
// 3. 創建訂單
Order order = new Order();
order.setUserId(userId);
order.setShopId(dto.getShopId());
order.setTotalAmount(totalAmount);
order.setStatus("CREATED");
orderMapper.insert(order);
return order.getId();
}
在校園外賣系統中,下單接口一定要輕、快、可併發,複雜邏輯儘量拆到異步處理。
五、訂單狀態流轉設計(核心)
校園外賣的穩定性,90% 取決於訂單狀態控制。
public void updateOrderStatus(Long orderId, String targetStatus) {
Order order = orderMapper.selectById(orderId);
if (!OrderStatus.canTransfer(order.getStatus(), targetStatus)) {
throw new BizException("非法狀態流轉");
}
order.setStatus(targetStatus);
orderMapper.updateById(order);
}
狀態流轉校驗示意:
CREATED -> PAID
PAID -> ACCEPTED
ACCEPTED -> PREPARING
PREPARING -> WAIT_DELIVERY
WAIT_DELIVERY -> DELIVERING
DELIVERING -> COMPLETED
這樣可以有效避免:
- 重複接單
- 跳狀態
- 高峯期併發導致的數據錯亂
六、配送邏輯:校園場景的關鍵點
校園配送通常有兩種模式:
- 商家自配送
- 校園騎手統一配送
配送接單示例
public void acceptDelivery(Long orderId, Long riderId) {
Order order = orderMapper.selectById(orderId);
if (!"WAIT_DELIVERY".equals(order.getStatus())) {
throw new BizException("當前訂單不可配送");
}
order.setStatus("DELIVERING");
order.setRiderId(riderId);
orderMapper.updateById(order);
}
在校園場景中,強制一單一騎手、限定配送範圍,反而能提高整體效率。
七、高峯期的關鍵優化思路
在午餐、晚餐高峯期,校園外賣系統通常會:
限制同一用户短時間內重複下單
控制商家最大接單量
延遲非關鍵接口(如統計、消息推送)
例如簡單的限流:
if (redis.incr("shop:order:count:" + shopId) > MAX_ORDER_LIMIT) {
throw new BizException("當前下單人數較多,請稍後再試");
}
八、總結
校園外賣系統小程序的技術難點,不在於“功能多”,而在於業務鏈路是否足夠清晰、狀態是否可控、系統是否扛得住高峯。 從下單、接單、出餐到配送,每一步都要圍繞“校園場景”去做取捨,而不是照搬通用外賣邏輯。