县城多门店外卖履约系统怎么设计:共享骑手池与分店对账模型

简介: 县城多门店外卖履约先统一门店档案、订单来源、共享骑手池和结算快照,再以订单归属门店作为分账主键;本文给出MySQL 8.0表结构、派单与分账SQL、正常输出及重复派单异常反例。

县城多门店外卖履约系统,建议先统一门店档案、订单来源、共享骑手池和结算快照,再以“订单归属门店”作为派单与分账主键。共享骑手可以跨店顺路取送,但每个订单的门店归属、商品金额和平台抽成仍按原门店记账;否则跨店拼单会把A店订单记到B店。下面用MySQL 8.0示例给出订单、骑手任务和结算快照模型,并用重复派单与跨店归属错误两个反例说明验收方法。

一、先把三种建模分开:同一主体多门店、多商户平台、多区域分站

县城多门店外卖履约先分清三种建模:同一经营者多门店,门店是结算主体,适合共用骑手池;多商户平台,商户是结算主体,平台按订单抽成;多区域分站,区域是权限与数据边界。三种模型可以叠加,但主键不同。本文示例按“同一主体多门店+共享骑手池”展开,订单表保留store_id和region_code,结算快照以order_no唯一。若平台还接第三方商家自配送,订单来源字段要记录渠道和授权主体;若门店独立库存,则商品表需要store_id维度。演示时用两家门店同商品不同库存、不同店员账号和不同打印归属核对分店隔离,再把跨店顺路单的派单路线与门店账单分开验收。

二、主键与状态:订单归属门店、任务唯一、快照幂等

共享骑手池容易出现两类账务问题:同一订单被重复派给两名骑手,或跨店拼单后按骑手当前门店生成账单。解决思路是把履约状态与账务快照分开:订单表用store_id锁定归属门店;骑手任务表用生成列和唯一键保证同一订单只有一个进行中任务;结算快照表用order_no做主键,保证一笔订单只生成一份可追溯账单。订单状态按CREATED→ACCEPTED→COOKING→PICKED→DELIVERED流转,CREATED或ACCEPTED可转CANCELED;退款作为售后状态单独记录,不覆盖原履约状态。

对象 关键状态 约束目的
外卖订单 CREATED、ACCEPTED、COOKING、PICKED、DELIVERED、CANCELED 记录履约进度,退款不覆盖原状态
骑手任务 ASSIGNED、ACCEPTED、PICKED、DELIVERED、CANCELED 进行中任务唯一,历史任务可保留
结算快照 CALCULATED、REFUND_ADJUSTED、EXCEPTION 账单幂等,异常快照停止入账

三、核心表结构与字段约束

示例依赖MySQL 8.0.16及以上版本与InnoDB。金额统一用“分”的整数,避免浮点误差;费率用DECIMAL;订单号、任务号由业务系统生成。DDL如下。

CREATE TABLE store (
  id BIGINT UNSIGNED PRIMARY KEY,
  store_name VARCHAR(64) NOT NULL,
  region_code VARCHAR(16) NOT NULL,
  status ENUM('OPEN','CLOSED') NOT NULL DEFAULT 'OPEN',
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

CREATE TABLE delivery_order (
  order_no VARCHAR(32) PRIMARY KEY,
  store_id BIGINT UNSIGNED NOT NULL,
  region_code VARCHAR(16) NOT NULL,
  channel ENUM('MEITUAN','ELEME','SELF') NOT NULL,
  order_status ENUM('CREATED','ACCEPTED','COOKING','PICKED','DELIVERED','CANCELED') NOT NULL,
  goods_amount_cent INT UNSIGNED NOT NULL DEFAULT 0,
  packaging_cent INT UNSIGNED NOT NULL DEFAULT 0,
  delivery_fee_cent INT UNSIGNED NOT NULL DEFAULT 0,
  commission_rate DECIMAL(6,4) NOT NULL DEFAULT 0.1000,
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_order_store FOREIGN KEY (store_id) REFERENCES store(id),
  CONSTRAINT ck_order_amount CHECK (goods_amount_cent >= 0 AND packaging_cent >= 0),
  CONSTRAINT ck_order_rate CHECK (commission_rate >= 0 AND commission_rate <= 0.3000)
) ENGINE=InnoDB;

CREATE TABLE rider_task (
  task_no VARCHAR(32) PRIMARY KEY,
  order_no VARCHAR(32) NOT NULL,
  rider_id BIGINT UNSIGNED NOT NULL,
  task_status ENUM('ASSIGNED','ACCEPTED','PICKED','DELIVERED','CANCELED') NOT NULL,
  task_seq TINYINT UNSIGNED NOT NULL DEFAULT 1,
  assigned_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  active_key VARCHAR(32) GENERATED ALWAYS AS (
    CASE WHEN task_status IN ('ASSIGNED','ACCEPTED','PICKED') THEN order_no ELSE NULL END
  ) STORED,
  UNIQUE KEY uk_active_task (active_key),
  UNIQUE KEY uk_order_seq (order_no, task_seq),
  CONSTRAINT fk_task_order FOREIGN KEY (order_no) REFERENCES delivery_order(order_no),
  CONSTRAINT ck_task_seq CHECK (task_seq >= 1)
) ENGINE=InnoDB;

CREATE TABLE settlement_snapshot (
  order_no VARCHAR(32) PRIMARY KEY,
  store_id BIGINT UNSIGNED NOT NULL,
  rider_id BIGINT UNSIGNED NOT NULL,
  goods_amount_cent INT UNSIGNED NOT NULL,
  delivery_fee_cent INT UNSIGNED NOT NULL,
  commission_cent INT UNSIGNED NOT NULL,
  rider_income_cent INT UNSIGNED NOT NULL,
  merchant_settle_cent INT UNSIGNED NOT NULL,
  snapshot_status ENUM('CALCULATED','REFUND_ADJUSTED','EXCEPTION') NOT NULL DEFAULT 'CALCULATED',
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_snap_order FOREIGN KEY (order_no) REFERENCES delivery_order(order_no),
  CONSTRAINT fk_snap_store FOREIGN KEY (store_id) REFERENCES store(id),
  CONSTRAINT ck_snap_amount CHECK (merchant_settle_cent >= 0)
) ENGINE=InnoDB;

约束说明:delivery_order.store_id非空,保证订单有明确归属门店;rider_task.active_key只在进行中状态生成订单号,配合唯一键拦截重复派单;uk_order_seq保留同一订单历史任务序号;settlement_snapshot.order_no唯一,账单生成可重试但不会重复入账。

四、核心实现:派单与结算快照

派单SQL只允许对已接单或制作中的订单创建进行中任务;结算快照只对已送达任务生成,且订单号唯一。

微订配送调度电脑后台与手机管理页。

微订配送调度电脑后台与手机管理页。

INSERT INTO rider_task(task_no, order_no, rider_id, task_status, task_seq)
SELECT 'T1001', order_no, 9001, 'ASSIGNED', 1
FROM delivery_order
WHERE order_no = '1001'
  AND order_status IN ('ACCEPTED','COOKING')
  AND NOT EXISTS (
    SELECT 1 FROM rider_task
    WHERE order_no = '1001'
      AND task_status IN ('ASSIGNED','ACCEPTED','PICKED')
  );

INSERT INTO settlement_snapshot(
  order_no, store_id, rider_id, goods_amount_cent, delivery_fee_cent,
  commission_cent, rider_income_cent, merchant_settle_cent
)
SELECT o.order_no,
       o.store_id,
       t.rider_id,
       o.goods_amount_cent + o.packaging_cent,
       o.delivery_fee_cent,
       ROUND((o.goods_amount_cent + o.packaging_cent) * o.commission_rate, 0),
       300,
       (o.goods_amount_cent + o.packaging_cent)
         - ROUND((o.goods_amount_cent + o.packaging_cent) * o.commission_rate, 0)
FROM delivery_order o
JOIN rider_task t ON t.order_no = o.order_no AND t.task_status = 'DELIVERED'
WHERE o.order_no = '1001'
  AND NOT EXISTS (SELECT 1 FROM settlement_snapshot s WHERE s.order_no = '1001');

正常输入:门店1为A店,订单1001商品2000分、包装200分、配送费400分、费率0.1000,骑手9001完成任务;门店2为B店,订单1002商品1500分、包装100分、配送费0分、费率0.0800,骑手9002完成任务。按同一快照SQL替换订单号执行后,预期输出如下。

订单 归属门店 计费基数(分) 平台抽成(分) 骑手收入(分) 商家应结(分)
1001 A店(id=1) 2200 220 300 1980
1002 B店(id=2) 1600 128 300 1472

这里配送费单列,商家应结按商品与包装减平台抽成计算;若项目约定配送费由商家承担或平台补贴,需在快照中增加对应字段,保持字段口径与合同一致。跨店顺路拼单只合并骑手路线,不改变订单的store_id,因此两个订单仍然分别形成两个门店账单。

五、异常反例:重复派单与跨店归属错误

反例一,同一订单在已有进行中任务时再次派单。即使task_no不同,唯一键也会拦截。

INSERT INTO rider_task(task_no, order_no, rider_id, task_status, task_seq)
VALUES ('T1001B', '1001', 9002, 'ASSIGNED', 2);

预期输出:ERROR 1062 (23000): Duplicate entry '1001' for key 'uk_active_task'。应用层捕获后返回409并保留原任务,避免重复生成骑手收益。历史已送达任务不受影响,因为active_key只对ASSIGNED、ACCEPTED、PICKED生成值。这类校验适合放在派单入口和任务提交两层:入口先查询进行中任务,数据库唯一键做最终兜底。

反例二,跨店归属错误。假设错误实现把结算快照的门店写成骑手当前门店2,而订单1001实际属于门店1。用下面的检测SQL可发现。

SELECT s.order_no, s.store_id AS snapshot_store, o.store_id AS order_store
FROM settlement_snapshot s
JOIN delivery_order o ON o.order_no = s.order_no
WHERE s.store_id <> o.store_id;

异常输出:order_no=1001,snapshot_store=2,order_store=1。处理方式是把该快照状态置为EXCEPTION,停止对应门店账单生成,按订单门店重算;正常数据应返回0行。跨店拼单场景尤其要保留这项检测,因为骑手可能先到A店取餐、再到B店取餐,但账务上A店订单只属于A店。

六、退款、提现与门店账单验收

退款冲回要挂在原订单快照上,按原订单门店冲减,避免重新匹配门店或费率。提现按门店可结算余额发起,骑手收益单独核算;同一订单的商家账单和骑手收益可以关联,但门店归属只认订单store_id。验收时准备正常单、跨店顺路单、部分退款单和一次提现,逐项核对快照门店、抽成、骑手收入与可提现余额。

验收项 操作 通过标准
正常单 生成订单、派单、送达、生成快照 快照store_id与订单一致,金额可复算
跨店顺路单 两门店订单由同一骑手取送 两个快照分别归属各自门店
部分退款 对订单1001退商品500分 冲回金额按原费率计算并关联原订单
提现 门店1发起提现 可提现余额不包含未结算或EXCEPTION快照

七、复现步骤与业务落地

  1. 准备MySQL 8.0.16及以上版本,创建测试库并执行DDL。

  2. 插入门店1、门店2,插入订单1001、1002及对应已送达骑手任务。

  3. 执行派单SQL和快照SQL,核对订单1001抽成220分、商家应结1980分;订单1002抽成128分、商家应结1472分。

  4. 对订单1001再次插入进行中任务,确认返回唯一键冲突。

  5. 插入一条store_id=2的订单1001快照,执行归属检测SQL,确认返回异常行后删除测试数据。

上述SQL为本地示例设计,未在真实云资源或生产环境执行;输出为按示例参数推算的预期结果。上线前应替换为本地门店、渠道费率、配送费和退款规则,并用正常单、跨店单、退款单和提现单各跑一遍。县城多门店场景先选两三家门店试运行,把门店归属校验放进账单生成前的必检项,再扩门店和骑手池。

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

相关文章
|
8天前
|
弹性计算 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型,零注册零 Key 零成本直接用
总结一下:装这个插件,你不用注册、不用绑卡、不用填一个 Key,就能在 DeepSeek Harness 里用上 DeepSeek V4.1 Flash、Kimi K3 这一批前沿模型,而且是白嫖的、还不限量。三步搞定:下载插件,复制包含 `package.json` 的插件目录路径,在「添加插件」里粘贴路径安装并重启。无论是在阿里云 ECS 上通过命令行部署的 Web 版,还是本地的 Electron 桌面端,都能顺利跑通,快速搭建一套零成本的免费模型使用环境。
603 0
|
1月前
|
人工智能 自然语言处理 API
阿里云Token Plan 订阅方案全新升级:个人版新增12项 Harness 权益,加量不加价,超量尊享88折
本文介绍千问AI平台Token Plan AI大模型订阅服务的全新升级内容:该服务以Credits统一计量,兼容主流AI编程、智能体工具与OpenAI、Anthropic接口协议,覆盖多品牌多模态模型。本次升级个人版新增12项Harness权益,实现加量不加价,超量场景尊享88折优惠,同时设个人版四档套餐、团队版多类席位,配套弹性加油包,为不同规模用户提供高性价比的AI算力订阅方案。
|
1月前
|
缓存 API 开发工具
保姆级上手|千问大模型 API 接入指南,账号开通、密钥申领与代码调用一步通
千问大模型依托百炼平台提供兼容OpenAI标准的API接口,降低了开发者接入国产大模型的门槛。整个接入链路分为账号实名认证开通服务、生成API‑Key、本地环境配置、接口调试、业务迭代优化几个阶段。普通对话、多轮会话、流式输出、图文多模态都有成熟的代码实现,开发者可以直接复用示例代码快速验证业务想法。选型层面,优先qwen‑plus覆盖绝大多数业务;复杂深度推理选择qwen3.8‑max;高并发轻量化任务使用qwen‑turbo。
1320 0
|
2月前
|
人工智能 自然语言处理 搜索推荐
企业级 AI 搜索获客体系建设方案:五层增长模型与全链路落地架构
AI 搜索获客不是营销噱头,而是一个有明确架构、可量化验证、可持续运营的工程体系。它的核心逻辑一句话就能说清:先让 AI 认识你、认可你,再让这份认可变成稳定的客户来源。
|
1月前
|
人工智能 运维 Rust
Codex终端AI编程助手实操全解:部署安装、百炼Coding Plan与Token Plan接入完整教程
现代软件工程迭代节奏持续加快,传统IDE普遍存在体积臃肿、启动缓慢、操作链路繁琐等问题。各类图形界面AI编码插件高度依赖可视化操作环境,无法适配纯终端远程服务器开发、轻量化脚本快速迭代、服务器运维编码等业务场景。市面上大量终端编程工具能力较为单薄,大多仅提供基础代码片段补全,缺少项目全局理解、多步骤任务自治、批量工程重构、安全沙箱防护等高阶能力;同时直接使用海外模型服务,还会遭遇网络链路不稳定、计费不可控、难以适配国内合规开发体系等现实阻碍。
285 0
|
1月前
|
缓存 JSON API
DeepSeek‑V4完整技术解析:Flash与Pro双版性能、计费缓存机制、API实战调用全教程
在大模型工程落地过程当中,超长上下文能力一直是开发者的强需求,但长期面临两大行业痛点:一部分长上下文模型推理速度缓慢,无法支撑线上高并发实时业务;另一部分虽然性能强劲,但是调用成本居高不下,中小企业很难大规模上线。DeepSeek‑V4系列采用差异化双版本产品策略,同时推出`deepseek‑v4‑flash`与`deepseek‑v4‑pro`两款MoE混合专家架构大模型,分别面向轻量化高频业务、复杂深度推理两大赛道,两款模型统一标配**100万Token超长上下文窗口**,把百万级长文本处理能力下放到普通开发者与中小企业,打破长上下文大模型的落地壁垒。
487 0
|
3月前
|
人工智能 自然语言处理 API
最新版阿里云百炼 Night Plan 功能介绍
在AI算力需求持续攀升、成本压力日益凸显的当下,阿里云百炼推出**Night Plan夜间错峰优惠计划**,为个人开发者与小团队提供了一条低成本解锁旗舰大模型能力的高效路径。Night Plan并非独立订阅套餐,而是叠加在百炼现有计费体系(按量付费、Token Plan、Coding Plan)之上的**自动生效折扣机制**,在每日22:00至次日08:00的错峰时段,为Qwen3.7-Max与Qwen3.7-Plus两款旗舰模型提供超低折扣,最高可节省80%调用成本。该计划无需额外订阅、无需手动切换,系统自动识别时段并按折扣价计费,在不牺牲模型质量与响应速度的前提下,大幅降低复杂AI任务的运
375 1
|
2月前
|
人工智能 自然语言处理 安全
阿里云Qoder CN产品简介:AI智能体产品,基于千问大模型等,支持代码智能生成、研发智能问答
本文介绍了阿里云Qoder CN(原灵码)这款面向AI原生时代的全栈智能开发与生产力提效产品。其深度集成通义千问等主流大模型,以代码智能生成、研发智能问答、工程级智能体交互为核心能力,覆盖从个人开发者到企业研发团队的全场景需求。产品矩阵包含Qoder Desktop、QoderWork、QoderWake等多元形态,支持端到端工程级交付、企业级知识增强与数据安全。文章详细梳理了从免费社区版到企业专属版的分层订阅方案,并重点解析了当前一周年庆限时福利。
|
3月前
|
人工智能 算法 安全
Skill 是什么?——给AI装个“能力插件”,就像给手机装App一样简单
本文手把手教你从0到1打造AI“Skill”插件系统,将大模型升级为可扩展的万能工具箱:解耦能力、热插拔新增功能、跨项目复用、团队并行开发。含快递查询实战、超时熔断、输入防呆、并发安全等生产级要点,助你构建高可用AI应用。
|
4月前
|
关系型数据库 MySQL API
1688搜索商品列表API详解:关键词、价格区间与分页参数配置(附Python源码)
本文详解1688搜索商品列表API(alibaba.offer.search):支持关键词、类目ID、价格区间(单位为分!)、分页与排序参数配置,附可直接运行的Python封装代码,含MD5签名、自动翻页、避坑提示及生产级调用建议。(239字)

热门文章

最新文章