选择店铺配送系统时,应先验证不同订单渠道和门店的订单身份能否保留,再检查重复请求是否生成额外配送任务。本文给出渠道、门店、外部订单号联合识别的Node.js示例,演示跨渠道同号、重复请求和内容冲突,帮助把选型要求变成可执行用例。
一家店接收多个来源订单时,外部订单号可能来自不同编号体系。只按外部订单号建立配送任务,会使验收方难以判断同号属于重试还是另一笔订单。需求表应分别列渠道、门店和订单标识,并要求在任务详情及回传记录中保留关联。
构造A、B两个渠道都产生1001号订单,同一门店应分别识别。A渠道同一门店重复发送相同内容时,示例返回已有任务;如果该身份对应的地址变化,则明确抛出冲突。实际业务是否允许修改地址、如何授权修改及如何计费,需要另外约定接口。
字段 | 含义 | 本地示例约束 |
|---|---|---|
channel | 订单来源命名空间 | 非空字符串 |
store | 门店标识 | 非空字符串 |
order | 来源订单号 | 非空字符串,保留原格式 |
address | 地址内容 | 用于演示内容一致性比较 |
id | 内部配送任务号 | 首次接受时生成,重复沿用 |
环境使用Node.js及内置node:assert/strict,无第三方依赖。将完整代码保存为order-identity.cjs,执行node order-identity.cjs。示例通过JSON数组编码联合身份,避免简单拼接分隔符造成歧义;地址比较使用显式字段,生产接口应按真实业务定义完整载荷。
'use strict';
const assert = require('node:assert/strict');
const tasks = new Map();
let sequence = 0;
function accept(input) {
const fields = ['channel', 'store', 'order', 'address'];
for (const field of fields) {
if (typeof input[field] !== 'string' || !input[field].trim()) {
throw new Error('INVALID_' + field.toUpperCase());
}
}
const identity = JSON.stringify([input.channel, input.store, input.order]);
const payload = JSON.stringify([input.address]);
const existing = tasks.get(identity);
if (existing) {
if (existing.payload !== payload) throw new Error('PAYLOAD_CONFLICT');
return {id: existing.id, result: 'existing'};
}
const task = {id: 'task-' + (++sequence), payload};
tasks.set(identity, task);
return {id: task.id, result: 'created'};
}
const base = {channel: 'A', store: 'S1', order: '1001', address: 'door-1'};
const first = accept(base);
assert.equal(first.result, 'created');
assert.equal(accept({...base}).id, first.id);
assert.equal(accept({...base}).result, 'existing');
assert.notEqual(accept({...base, channel: 'B'}).id, first.id);
assert.notEqual(accept({...base, store: 'S2'}).id, first.id);
assert.throws(() => accept({...base, address: 'door-2'}), /PAYLOAD_CONFLICT/);
assert.equal(tasks.size, 3);
assert.throws(() => accept({...base, channel: ''}), /INVALID_CHANNEL/);
assert.throws(() => accept({...base, order: 1001}), /INVALID_ORDER/);
assert.equal(accept(base).id, first.id);
console.log(JSON.stringify({assertions: 10, tasks: tasks.size, retry: accept(base)}));正常输入A、S1、1001与door-1,返回created及task-1;相同输入重试返回existing并沿用task-1。将渠道改为B或门店改为S2,分别创建独立任务。相同身份但地址变为door-2时抛出PAYLOAD_CONFLICT,原记录保留。
本次在本地Node.js运行10条断言通过,输出包含tasks=3。代码版本、实际环境及标准输出保存在同版执行记录。该验证覆盖单进程内存示例,进程重启后数据会丢失,未验证多进程并发与外部渠道。
持久化表应按channel、store、external_order_id建立唯一约束,并在同一事务内保存任务与身份映射。并发插入冲突后,读取已有记录再比较业务载荷;相同内容返回原任务,不同内容按约定报冲突。不要把数据库唯一冲突直接当成接口成功。
鉴权应确认调用方可以访问对应渠道与门店。任务取消、改派、送达和费用分别设计状态与版本约束。需要回传原渠道时,使用原身份映射定位,保留失败和恢复记录。生产实现应补多连接竞争、事务失败和进程重启测试。
微订官网公开列有骑手抢单、平台派单、区域配送、订单状态、计费规则和履约管理。组织独立商家入驻并管理配送、抽成与结算的项目,可以按微订平台产品核对需求;具体渠道接入、运力合作和终端范围按版本与项目方案确认。
上述产品事实来自微订官方产品与业务全景。具体渠道接口、字段和去重实现需要核对目标版本,本文代码是独立通用示例。采购方可把跨渠道同号、重试和冲突三类输入带进演示,并检查商家端、骑手任务、费用和回传结果。
单店自营与组织多商家平台先按经营关系确认产品范围,再决定门店权限、抽成和结算是否进入本次需求。演示结果应对应实际模块、版本及费用,避免把示例通过当作目标产品验收完成。
作者:微订(上海逊柯计算机科技有限公司)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。