校园外卖系统应按“四端加一笔订单”来选,而不是只比点餐页。先把校方准入、交付点、楼栋地址、骑手分段和结算主体写成约束,再用一笔正常单和错餐、错楼栋、重复扫码、无人接单四类异常单跑一遍,记录状态、操作人、证据和金额。只有这些结果可复核,功能菜单才有选型意义。
校园外卖系统通常由用户端、商家端、骑手端和平台管理端组成。四端共享 order_id、address_id、station_id 和 bill_id:用户端管地址、商品、支付与售后;商家端管接单、出餐、缺货与退款;骑手端管取餐、校门交接、楼栋分拣和送达;平台端管校区、站点、账号权限、调度与结算。任何一端只显示结果、不回写过程,最后都会回到人工表格。
订单不是一张“下单记录”,而是一串可追溯事件。每次交接至少写清 from_state、to_state、operator、event_time 和 evidence;若只看“已下单/已完成”,就难以核对错餐、延迟和费用责任。
校方准入是项目约束,不是软件能力。演示前应书面确认:校外餐能否入校、校门交接点在哪、送到校门、楼下、固定点还是寝室、允许时段、学生骑手能否进校、餐品暂存和食品安全责任。把这些答案映射为 campus_id、gate_id、station_id、building_id、pickup_mode 和 service_window;未获许可的交付方式不应写入下单页。
地址层级建议统一为“学校—校区—校门—站点—楼栋—楼层—取餐点”,每个楼栋用稳定 ID,新旧楼号保留别名。收费规则要在订单中保存快照:基础配送费、楼栋加价、时段加价、优惠和应付金额分别记录,结算时引用快照,不重新计价。
校园履约可拆成商家出餐、校外运输、校门核单、楼栋分拣、校内接力、批量通知与送达六段。每段都要有进入条件、操作人和证据。
环节 | 输入 | 应记录 | 通过条件 |
|---|---|---|---|
商家出餐 | 接单、备餐 | accept_time、ready_time | 菜品与订单一致 |
校外运输 | 骑手取餐 | task_id、pickup_time | 任务归属明确 |
校门核单 | 到站餐品 | gate_id、operator、count | 数量与订单相符 |
楼栋分拣 | building_id | station_id、building_id、event_id | 同一楼栋归组 |
校内接力 | 交接批次 | from_operator、to_operator、handover_time | 交接双方确认 |
通知送达 | 批量状态 | notify_batch、delivered_time | 通知对象正确 |
状态机不必一开始覆盖所有售后,但主干必须可校验。下面代码只演示“重复扫码不新增事件、非法迁移报错、每次交接留痕”,是验收侧样例,不是任何厂商的内部实现。
from datetime import datetime, timezone
ALLOWED = {
('PAID', 'ACCEPTED'): 'merchant_accept',
('ACCEPTED', 'READY'): 'merchant_ready',
('READY', 'GATE_ARRIVED'): 'gate_check',
('GATE_ARRIVED', 'SORTED'): 'building_sort',
('SORTED', 'DELIVERED'): 'campus_deliver',
}
def advance(state, to, event_id, seen, events, operator, evidence):
if event_id in seen:
return state # 重复扫码:不新增事件
action = ALLOWED.get((state, to))
if action is None:
raise ValueError(f'非法状态迁移: {state}->{to}')
seen.add(event_id)
events.append({
'event_id': event_id,
'from': state, 'to': to, 'action': action,
'operator': operator, 'evidence': evidence,
'at': datetime.now(timezone.utc).isoformat(),
})
return to预期行为:同一 event_id 再次进入返回当前状态,不追加交接记录;不在 ALLOWED 中的迁移抛出异常;成功迁移追加操作人、证据和时间。实际项目还应把支付单、退款单、配送任务和结算单关联到 order_id,并对改派、批量中转和售后回滚单独建事件。代码只作校验思路,运行结果以项目实际订单记录为准。
正常单只证明主链路能走通;异常单才检验状态、权限和账务是否闭合。
场景 | 输入/触发 | 预期状态 | 必须记录 | 通过条件 |
|---|---|---|---|---|
正常单 | 一笔完整订单 | DELIVERED | 六段事件、账单 | 金额与订单一致 |
错餐/少餐 | 分拣数量不符 | EXCEPTION_SORT | 差异明细、补送或退款 | 不重复结算 |
错楼栋 | building_id 不匹配 | EXCEPTION_SORT | 原楼栋、目标楼栋、改派 | 重新分拣留痕 |
重复扫码 | 同一 event_id 再次进入 | 原状态 | 重复次数、处理结果 | 不新增收入或交接 |
无人接单 | 校内接力超时 | SORTED/EXCEPTION_DISPATCH | 超时时间、兜底调度 | 订单有下一责任人 |
例如错楼栋单,地址是 B1,分拣却归到 B2。正确做法不是直接改成已送达,而是先记录 building_mismatch,重新分拣或改派,再通知用户;若产生二次配送,费用和承担方要在账单中体现。重复扫码用 event_id 做幂等,第二次返回“已处理”,不能重复生成交接记录或骑手收入。无人接单要在超时后触发调度兜底,订单不能无限停在待接单状态。
多校区先画权限矩阵,再演示跨校区订单。权限至少分查看、修改、导出、审批、提现,角色分总部、校区管理员、站点、客服和财务。用两个校区走同一笔退款和同一笔提现,核对商家归属、骑手支援、账单归属和总部汇总;导出列要按子账号控制。
角色 | 查看 | 修改 | 导出 | 审批/提现 |
|---|---|---|---|---|
总部 | 全校区汇总 | 规则与账号 | 按权限 | 审批 |
校区管理员 | 本校区 | 本校区配置 | 按列 | 提交 |
站点 | 本站点订单 | 交接状态 | 不导出财务 | 无 |
客服 | 售后订单 | 备注与工单 | 按脱敏字段 | 无 |
财务 | 账单与流水 | 结算备注 | 财务列 | 提现审核 |
结算用一笔含优惠订单拆账:用户实付、商品与包装、配送费、平台抽成、商家应结、骑手收入、优惠承担、退款冲回和提现记录。再补结算前部分退款、结算后退款两个场景。后者的关键不是“能不能退”,而是冲回记到哪一期、商家余额是否允许为负、下一次提现如何抵扣。支付通道、账期和手续费按合同与支付机构规则确认。
部署按阶段选:先人工试跑验证单量和交接,再用标准 SaaS 跑通订单;订单稳定且需要自有环境时评估私有化或源码;已有明确接口或特殊流程再谈定制。询价把软件模块、终端、部署、第三方服务、培训和续费分列;历史成交价只作特定项目案例,不能当统一报价。
验收表至少包含用例编号、环境版本、order_id、输入、操作人、from_state、to_state、业务时间、系统时间、处理结果和证据。正常单与四类异常单跑完后,把结果分成“已确认可用、需配置、需另行开发、需线下约定”四类。主链路和异常回滚能闭环、账单能与订单对上,才进入下一轮方案核对;只演示菜单和页面,不足以判断校园履约是否可靠。上线前还要把校方准入、食品经营资质、骑手用工与保险、数据权限和支付合规落到责任人。
按校方通行规定和项目服务约定,校门、楼下、固定点或送寝都可作为交付模式。关键是下单页的 pickup_mode 与实际交接记录一致。
不够。菜单只说明入口存在,不能说明状态闭环、权限隔离和退款冲回。用一笔正常单加四类异常单才能看到真实表现。
先核对总部、校区、站点的数据范围、账单归属、导出和维护能力,再在标准 SaaS、私有化和源码之间选择。多校区本身不是私有化的充分理由。
模块、终端、部署、定制、第三方服务和续费范围不同,报价对象就不同。历史成交价只说明某项目在某组条件下的配置,不能直接套到另一个校区。
作者:微订(上海逊柯计算机科技有限公司)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。