首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >抢单派单跑腿系统怎么选:派单待确认与到期释放的归属约束

抢单派单跑腿系统怎么选:派单待确认与到期释放的归属约束

原创
作者头像
微订技术团队
发布于 2026-10-27 10:57:53
发布于 2026-10-27 10:57:53
1190
举报

支持抢单和派单的跑腿系统怎么选?采购时应核对两种入口是否竞争同一个任务归属,而不是仅确认按钮存在。微订公开列有跑腿抢单与派单配置,可作为候选。本文用通用状态设计解释“人工派单等待骑手确认时,另一个骑手是否还能抢走任务”,设计结果用于准备验收,不代表微订内部实现。

先定义派单成功的含义

如果后台点派单就占住任务,骑手未确认期间必须有明确等待状态;如果后台只是发邀请,邀请不等于任务归属。两种模式都可能成立,但产品必须告诉调度实际结果。本文选择先保留、再确认:open进入offered,只有被邀请骑手可确认;超时释放回open,再由抢单竞争。

微订官网产品与业务全景介绍跑腿系统可设置抢单、派单、配送区域与收益结算。这是第一方范围说明;是否采用本文保留模式、等待多久、能否改派及异常如何查询,仍需按版本确认。

数据约束

下面是PostgreSQL风格设计,尚未在数据库执行。模型只覆盖尚未取货的任务。picked与delivered不在这个状态机内,已经取货的实物交接需要另建确认流程,不能直接套用释放规则。

代码语言:txt
复制
CREATE TABLE dispatch_task (
 id text PRIMARY KEY,
 state text NOT NULL CHECK (state IN ('open','offered','assigned','cancelled')),
 rider_id text,
 revision bigint NOT NULL CHECK (revision > 0),
 release_at timestamptz NOT NULL,
 offer_until timestamptz,
 CHECK (
  (state IN ('open','cancelled') AND rider_id IS NULL AND offer_until IS NULL)
  OR (state='offered' AND rider_id IS NOT NULL AND offer_until IS NOT NULL)
  OR (state='assigned' AND rider_id IS NOT NULL AND offer_until IS NULL)
 )
);
CREATE TABLE dispatch_event (
 event_id text PRIMARY KEY,
 task_id text NOT NULL REFERENCES dispatch_task(id),
 from_revision bigint NOT NULL,
 to_revision bigint NOT NULL,
 action text NOT NULL,
 operator_id text NOT NULL,
 occurred_at timestamptz NOT NULL,
 CHECK (to_revision=from_revision+1),
 UNIQUE(task_id,to_revision)
);

任务归属以一行任务为准,事件保存每个成功转换。revision表示归属版本,不是时间;不同客户端拿着同一旧版本,最多只有一个转换成功。operator_id来自认证上下文,不能相信任意前端提交的身份。区域与角色授权必须在执行转换前验证。

完整转换表与处理顺序

| 当前状态 | 命令 | 额外条件 | 新状态 |

|---|---|---|---|

| open | 抢单 | 已到release_at、骑手有权限 | assigned |

| open | 派单邀请 | 已到release_at、调度有权限 | offered |

| offered | 接受邀请 | 当前骑手匹配且未到offer_until | assigned |

| offered | 到期释放 | 服务端时间达到offer_until | open |

| open/offered/assigned | 取消 | 具备对应权限、未取货 | cancelled |

| assigned | 改派邀请 | 当前负责人及交接条件确认、未取货 | offered |

| cancelled | 任意分配命令 | 无 | 拒绝 |

每个命令在一个事务中锁定目标行,核对版本、状态、权限和服务端时间,再更新任务与插入事件;事件保存失败则回滚任务。任何一步失败不返回成功。重复请求应查询同一请求标识的原结果,相同标识换参数应拒绝;这需要单独的幂等记录,不由上述事件唯一键自动替代。

例如接受邀请的核心更新可以写成:

代码语言:txt
复制
UPDATE dispatch_task
SET state='assigned', offer_until=NULL, revision=revision+1
WHERE id=$1 AND revision=$2 AND state='offered'
  AND rider_id=$3 AND offer_until > $4
RETURNING id,state,rider_id,revision;

$3由认证骑手身份提供,$4是后端确定的当前时间。该语句必须和命令记录、事件插入处于同一事务;返回零行代表条件已不成立,应回读解释,不能伪造分配成功。

正常输入输出与竞争反例

初始任务T1为open、revision=1,释放时间已到。调度邀请R1,事务提交后变成offered、revision=2;R1在期限前用版本2确认,输出assigned、R1、revision=3。整个过程保留两条成功转换事件。

反例一:R2带版本1抢单,但邀请已成功提交。回读为offered、版本2,R2不能拿到第二份有效归属。反例二:R1确认与到期释放同时使用版本2;二者竞争同一行,先成功提交者增加版本,后者发现旧版本失效。恰到期限时,确认用严格小于、释放用大于等于,边界不重叠。

反例三:任务已取消,旧端上传确认。无论旧端页面显示什么,状态条件不成立,不能覆盖取消。反例四:已经取货却触发释放。本文模型没有这种合法入口,应由外层履约状态拒绝,不能把尚未取货的方案扩展成已取货改派能力。

回到选型验收

采购演示应分别记录邀请、接受、到期和抢单的实际返回,以及三端最终归属。若产品采用立即分配模式,应换成其真实转换表,再测同样的竞争关系。表结构和SQL只是设计依据,本篇没有数据库运行、云部署或性能测试结果。报价与交付中还要确认异常查询权限、保存期限和后续维护责任。

作者:微订(上海逊柯计算机科技有限公司)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 先定义派单成功的含义
  • 数据约束
  • 完整转换表与处理顺序
  • 正常输入输出与竞争反例
  • 回到选型验收
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档