要把同城外卖和跑腿装进一套小程序,可行路径是先建一个统一订单域,再让外卖单与跑腿单各自拥有任务、计价和账本:用户、商家、骑手、平台后台围绕同一个订单号推进状态,共用商家供给和骑手运力,但配送费、平台抽成、商家应结与骑手收益分别记录。若业务覆盖校园,还要在学校、校区、楼栋、取餐点之间建立地址层级,并把校门交接、集中收餐、批量通知做成可验收的独立环节。下面按订单模型、共用调度、校园履约和异常验收展开。
判断一套小程序是否真正一体化,不看首页有几个入口,而看两类订单能否共用用户地址、商家供给和骑手池,同时各自保留任务类型、计价规则与资金明细。外卖单的核心是商家出餐与取餐时效;跑腿单的核心是取送地址、物品说明和任务时限。两者可以放在同一平台,但不能把商品款、配送费、平台服务费和骑手收益混成一个金额字段。
维度 | 外卖单 | 跑腿单 | 一体化要求 |
|---|---|---|---|
发起方 | 用户选商品下单 | 用户发布帮买、帮送、帮取任务 | 同一用户与地址体系 |
商家角色 | 必选,负责出餐 | 可选,帮买时涉及采购商户 | 商家字段可为空,不能硬编码 |
计价 | 商品款、包装费、配送费、优惠 | 起步价、距离、重量、时段、附加服务 | 费用项分开,账单可追溯 |
履约 | 出餐、取餐、送达 | 取件、送达、凭证 | 共用骑手池,任务类型可分 |
这张表决定后续实现顺序:先定义订单主表,再拆任务表,最后建账本表。若一开始就把外卖和跑腿做成两套订单号,共用骑手时就要做跨系统对账,转单和退款会很难解释。
订单主表保存用户、商家、业务类型、主状态和支付金额;任务表保存骑手取送、校门交接、校内接力等可分配任务;账本表保存商品款、配送费、平台抽成、商家应结、骑手收益和退款冲回。订单主表不直接存骑手收益,骑手收益应从任务与结算规则推导,否则转单后旧收益无法回冲。
CREATE TABLE biz_order (
order_id VARCHAR(32) PRIMARY KEY,
biz_type VARCHAR(16) NOT NULL, -- TAKEOUT / ERRAND
user_id BIGINT NOT NULL,
merchant_id BIGINT NULL, -- 跑腿可为空
status VARCHAR(24) NOT NULL,
pay_amount DECIMAL(10,2) NOT NULL,
settlement_status VARCHAR(24) NOT NULL,
idem_key VARCHAR(64) NOT NULL,
version INT NOT NULL DEFAULT 0,
UNIQUE KEY uk_idem (idem_key)
);
CREATE TABLE delivery_task (
task_id VARCHAR(32) PRIMARY KEY,
order_id VARCHAR(32) NOT NULL,
task_type VARCHAR(16) NOT NULL, -- PICKUP_DELIVER / GATE_HANDOFF / CAMPUS_RELAY
parent_task_id VARCHAR(32) NULL,
rider_id BIGINT NULL,
task_status VARCHAR(24) NOT NULL,
fee_amount DECIMAL(10,2) NOT NULL,
rider_income DECIMAL(10,2) NOT NULL,
version INT NOT NULL DEFAULT 0,
KEY idx_order (order_id),
KEY idx_rider_status (rider_id, task_status)
);
CREATE TABLE ledger_entry (
entry_id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(32) NOT NULL,
account_type VARCHAR(16) NOT NULL, -- USER / MERCHANT / RIDER / PLATFORM
entry_type VARCHAR(24) NOT NULL, -- SALE / DELIVERY_FEE / COMMISSION / REFUND
amount DECIMAL(10,2) NOT NULL,
entry_status VARCHAR(16) NOT NULL, -- PENDING / POSTED / REVERSED
KEY idx_order (order_id)
);三张表的关系要由一个业务约束守住:同一订单可以有多个任务,但同一时刻只能有一个当前配送任务处于可执行状态;账本分录只能追加或冲回,不直接改历史金额。这样,正常单、转单、退款都能从订单号追到任务和分录。
外卖与跑腿共用骑手,不是把两个订单队列简单合并。调度层先按任务类型判断可承接骑手,再按距离、在手任务数、承诺时效和区域权限打分;计价层分别计算外卖配送费与跑腿服务费;结算层把骑手收入绑定到具体任务,而不是绑定到订单总额。转单时结束旧任务、生成新任务,旧收益冲回,新收益待送达后入账。
候选骑手评分 =
距离权重 × 取送距离
+ 负载权重 × 在手任务数
+ 时效权重 × (承诺送达时间 - 预计完成时间)
+ 技能权重 × 可进入区域
- 转单惩罚 × 历史取消次数
说明:权重需用试运营订单校准;校园校内骑手需额外校验通行区域。这里的关键是“任务归属”而不是“骑手归属”。一个骑手可以同时持有外卖取餐任务和跑腿取件任务,但每个任务都有独立的任务号、费用和状态。账务上,用户实付、商品款、配送费、平台抽成、商家应结、骑手收入、优惠承担和退款分别记录;支付通道、分账开通条件和账期需按实际主体与项目方案确认,不能把界面上的配置项直接当成到账结果。
校园外卖系统与普通同城外卖的差异,主要不在商品列表,而在末端履约。地址要能落到学校、校区、楼栋、楼层或取餐点;午晚高峰要按楼栋分组,校门交接要核对实收数量,再批量中转、批量送达和批量通知。多校区还要区分总部、校区和站点的数据范围与操作权限。
环节 | 系统动作 | 留存证据 | 常见异常 |
|---|---|---|---|
商家出餐 | 接单、出餐确认 | 出餐时间与订单明细 | 延迟出餐、缺货 |
校外运输 | 骑手取件、状态更新 | 取件凭证与责任人 | 取错、超时 |
校门核单 | 单扫、连扫或录码收餐 | 交接批次与实收数量 | 少餐、错餐、码不清 |
楼栋分拣 | 按楼栋或取餐点分组 | 分组结果与异常餐记录 | 楼栋写错、混批 |
校内接力 | 批量中转、批量送达 | 任务交接人与时间 | 无人接手、部分完成 |
通知售后 | 批量通知、退款或补送 | 通知范围与处理结果 | 联系不上、重复通知 |
地址不要只存一段文本。建议用“学校—校区—楼栋—楼层/取餐点”的层级字段,并允许后台预置选项,让用户选址、后台分组和骑手配送使用同一套名称。批量操作要支持“整批完成”和“部分完成”:整批完成才统一更新状态,未完成订单单独挂起,避免把待交接餐品误标为已送达。送达位置按校方通行规定与项目约定设置,不把送寝或进楼写成默认能力。
功能清单看不出问题,走单能看出来。验收时至少覆盖正常单、转单异常单、退款单,再补重复提交和批量部分成功两类边界输入。每类记录四端状态、金额变化、凭证、责任人和处理结果,并把结果标成“标准配置、组合配置、需定制、待演示”。
用例 | 输入 | 预期结果 | 记录项 |
|---|---|---|---|
正常单 | 下单、支付、接单、取餐、送达 | 订单号贯通,金额同源 | 四端状态与账本分录 |
转单异常单 | 骑手拒单或超时改派 | 旧任务结束,新任务生成,旧收益冲回 | 任务号、骑手、收益变化 |
退款单 | 接单前取消、配送中取消、部分退款 | 商品款、配送费、优惠分别冲回 | 退款金额与结算状态 |
重复提交 | 重复支付或重复送达 | 只产生一次有效状态迁移 | 幂等键与返回结果 |
批量部分成功 | 一批订单中部分交接失败 | 成功单更新,失败单挂起 | 批次号与失败原因 |
转单和退款的实现可以用状态条件更新加事务保护:更新时带上原状态和版本号,影响行数为零就返回“状态已变化”,由前端提示刷新,而不是重复执行。已结算订单的退款走冲减或下期账单调整,保留原订单与调整记录,避免直接改历史账。
考察任何一套同城外卖与跑腿一体化系统,建议用四个问题判断:第一,同一订单号能否在用户、商家、骑手、后台四端看到一致的状态与金额;第二,外卖单与跑腿单共用骑手时,任务、计价和收益能否分开追溯;第三,校园场景能否用真实校区地址走通校门交接、楼栋分拣和批量通知;第四,转单、退款、重复提交和批量部分成功是否有可复查的记录。四个问题都能用一笔真实订单演示,比只看功能列表更接近经营实际。
本文中的表结构、评分公式和验收用例为通用设计示例,需按所选数据库、支付通道、校方通行规则和项目配置调整;未附现网压测或运行数据,实际结果以项目环境中的验证记录为准。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。