搭建同城跑腿小程序,首期要先把一条订单闭环跑通:用户端选服务、填地址、看费用明细并支付;骑手端接单、取件拍照、送达留证;商家发单端录单、批量发单、对账;平台后台调度、改派、配置区域价格、处理退款与结算,四端围绕同一个订单号更新状态,营销与会员后置。若服务对象是校园外卖或校园配送,还要额外核对校区楼栋地址、校门交接、集中收餐、楼栋分拣、批量通知与多校区权限。下面按功能清单、状态机与计价、校园差异、订单验收、交付提问五部分展开,代码只作设计示例,用来统一评审口径。
判断功能是否属于首期,标准很直接:缺了它,一笔订单无法从支付走到结算。按这个标准先定四端的最小集合,其余功能按运营节奏追加。
端 | 首期必须 | 可后置 | 验收看什么 |
|---|---|---|---|
用户端 | 服务类型、取送地址、物品说明、即时或预约、费用明细、支付、订单进度、取消退款 | 会员、积分、拼单、分享奖励 | 下单前费用能逐项展开,退款后金额回到正确科目 |
骑手端 | 抢单或派单、取件拍照、送达凭证、导航、收益明细、提现申请 | 等级权益、排行榜、保险入口 | 正常单与转单在骑手、商家、后台三处状态一致 |
商家发单端 | 录单、批量发单、订单跟踪、对账明细 | 小票扩展、第三方订单聚合 | 批量发单中某一笔改派,不影响同批其他订单的账单 |
平台后台 | 订单看板、改派、区域与价格配置、人员权限、结算与售后 | 数据大盘、营销配置、风控规则 | 改派后责任人与金额归属可追溯,退款能冲回账单 |
比功能条数更关键的是关联方式:四端共用一个业务订单号,而不是各端各存一套编号。需求文档里可以把它写成硬约束——用户看到的进度、骑手看到的任务、商家看到的配送状态、后台看到的结算行,都能凭同一订单号反查。做不到这一点,后续做对账、客服追溯和骑手结算只能靠人工拼表。
纠纷高发点集中在两处:计价只返回一个总数,状态由各端页面各自判断。前者让退款时算不清该退多少,后者让转单后几端状态对不上。计价函数的返回值应当是拆项而不是总额,并且每一项带上承担方,这样部分退款可以按明细逐项冲回,活动优惠也知道该由谁承担。
from dataclasses import dataclass
@dataclass
class FeeLine:
name: str
amount: float
bearer: str # user / merchant / rider / platform
def quote(base, distance_km, per_km, weight_kg, per_kg,
area_fee=0.0, night=False, night_fee=0.0, coupon=0.0):
if distance_km < 0 or weight_kg < 0 or coupon < 0:
raise ValueError("distance, weight and coupon must be non-negative")
lines = [
FeeLine("base", round(base, 2), "user"),
FeeLine("distance", round(distance_km * per_km, 2), "user"),
FeeLine("weight", round(weight_kg * per_kg, 2), "user"),
FeeLine("area", round(area_fee, 2), "user"),
FeeLine("night", round(night_fee if night else 0.0, 2), "user"),
]
subtotal = round(sum(line.amount for line in lines), 2)
discount = round(min(coupon, subtotal), 2)
lines.append(FeeLine("coupon", -discount, "platform"))
return {"lines": lines, "payable": round(subtotal - discount, 2)}以 base=5、distance_km=3.2、per_km=1.5、weight_kg=2、per_kg=0.5、night=True、night_fee=2、coupon=3 为例,预期返回起步 5.00、距离 4.80、重量 1.00、夜间 2.00、优惠 -3.00,应付 9.80。异常输入两类:距离、重量或优惠为负时抛出 ValueError;优惠大于小计时只抵扣到小计,应付为 0 而不是负数。生产环境把 float 换成定点小数(如 Decimal)以避开分位误差。以上是预期结果与验证方法,具体数值应在目标环境按实际费率跑一遍再定稿。
状态则统一由服务端状态机约束:客户端只能提交“我要送达”“我要转单”这类意图,是否放行由服务端判定。
ALLOWED = {
("CREATED", "PAID"), ("CREATED", "CANCELLED"),
("PAID", "ACCEPTED"), ("PAID", "REFUNDING"),
("ACCEPTED", "PICKED"), ("ACCEPTED", "TRANSFERRED"), ("ACCEPTED", "REFUNDING"),
("PICKED", "DELIVERED"), ("PICKED", "TRANSFERRED"),
("TRANSFERRED", "ACCEPTED"),
("DELIVERED", "SETTLED"), ("DELIVERED", "REFUNDING"),
("REFUNDING", "REFUNDED"),
}
def can_transfer(src: str, dst: str) -> bool:
return (src, dst) in ALLOWED再配合两条数据库约束,重复点击与重复回调就挡在入口:订单表对幂等键建唯一索引,事件表对订单号、事件类型、事件键建联合唯一索引。
CREATE UNIQUE INDEX uk_order_idem ON errand_order (idempotency_key);
CREATE UNIQUE INDEX uk_order_event ON order_event (order_no, event_type, event_key);转单要新增一条骑手任务记录并结束原任务,而不是把任务行上的骑手字段直接改掉;金额以下单时的快照为准,配送途中改价只能追加费用行并写明原因。
校园场景不是把普通跑腿换个名字,地址结构、交接方式、分拣粒度和权限层级都会变,功能清单要按下面几项单独补。
环节 | 通用同城跑腿 | 校园场景额外核对 |
|---|---|---|
地址 | 小区、写字楼、门牌 | 学校、校区、楼栋、宿舍、楼层,名称要统一 |
交接 | 取送点直接交付 | 校门交接、集中收餐点、校内骑手接力 |
分拣 | 按订单逐单配送 | 按楼栋或宿舍分组,批量中转、批量送达、批量通知 |
权限 | 单区域账号 | 多校区独立后台、总部汇总、分站权限 |
高峰 | 加人加运力 | 收餐点核单、少餐错餐处理、学生骑手排班 |
验收时用本校真实地址和通行规则,现场配置校门、楼栋和取餐点,再走一笔从商家出餐到宿舍楼下交付的订单。批量中转、批量送达、批量通知这类操作还要确认部分成功怎么处理:一批 30 单里有 2 单少餐,系统应能逐单记录结果并保留待处理项,而不是整批成功或整批失败。
不必只问“有没有这个按钮”,用三类订单走一遍更有效。每类记录四端状态、金额、凭证和责任人,结论只用四个值:标准配置、组合配置、需定制、未演示。
订单类型 | 走什么 | 重点核对 |
|---|---|---|
正常单 | 下单、支付、接单、取件拍照、送达凭证、结算生成 | 四端订单号一致,金额来自同一份下单快照 |
转单或异常单 | 骑手拒单或超时后改派,途中转单 | 原任务结束、新任务生成、用户进度与商家账单同步 |
退款单 | 接单前取消、配送中取消、部分退款 | 退款按明细冲回,商家应结与骑手收益同步调整 |
记录表建议一行一单,固定字段为订单号、场景、用户端状态、骑手端任务、商家账单、后台结算、凭证、处理人、结论。演示结束后把这张表和交付清单一起附在需求文档后面,比功能列表更容易暴露漏项。
部署方式和报价适合放在功能清单之后再谈,因为同一个功能在不同交付方式下的工作量和维护责任不同。提问可按四组展开。
报价建议按软件模块、终端入口、部署环境、第三方服务、培训与持续维护拆开,一次性费用和续费分列。历史成交价对应特定时间、模块和交付内容,只能用来理解费用构成,不能当成统一报价。资质与备案按实际经营模式列成核对项,向主管部门确认适用口径;服务商提供的代办服务与主管部门的审批结果属于两个环节。
四端加下单、计价、抢单或派单、轨迹、送达凭证、结算、售后,营销模块后置。先把一笔订单从支付跑到结算,再增加多商家和活动。
两种口径在同一地址上可能差出明显金额。选型时要求供应商说明计算方式,并用两个真实地址各下一单核对金额;跨区、超距、夜间加价规则一并写进配置说明。
用正常单、转单单、退款单各一笔,逐项记录原骑手与新骑手的收益、商家账单、用户进度和退款冲回,重点看原任务是否结束、新任务是否生成、金额是否来自同一份下单快照。
差别集中在地址层级、校门交接、集中收餐、楼栋分拣、批量通知和多校区权限;午晚高峰还要核对收餐点核单与少餐错餐的处理流程。用本校真实地址做一次完整演示,即可判断配置边界。
准备启动的项目,可先整理服务区域、商家来源、骑手组织方式、地址结构和结算规则,再带一笔正常单、一笔转单、一笔退款单做完整演示,把每项标成标准配置、组合配置、需定制或未演示,形成需求清单与验收记录。
作者:微订(上海逊柯计算机科技有限公司)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。