更新时间:2026-10-14。本文对应当前仓库中的后端实现,供用户端和骑手端接入;联调前需确认服务端部署版本和 10 月 14 日数据库执行说明。
| 页面/场景 | 前端调整 |
|---|---|
| 用户填写闪送订单 | 按顺序编辑一个 stops 数组:先全部取货站,再全部收货站;物品信息只填写一次。根据 /home 的取货点和收货点数量上限控制可添加数量。 |
| 报价与下单 | 使用 /v2/quote 和 /v2/orders。创建时把本次报价的配置 ID、版本和费用原样回传;创建请求号在重试时保持一致。 |
| 用户/收件人订单列表和详情 | 展示取货、收货两个进度;站点使用 stops[].id,不可把数组下标当成站点 ID。逐站收货码按权限展示。 |
| 骑手履约 | 从详情的 currentTargetStopId 找当前目标;每站上传凭证并刷新详情。逐站送达改用固定路径的新接口,orderId、stopId、PIN 和照片全部放 body。 |
| 待接单改址 | v2 使用新的完整站点报价与保存接口。保存成功后刷新详情,替换本地旧站点 ID 和收货码。 |
| 发起人消息 | 识别两种逐站进度事件,凭 ddId 打开订单详情,再读取最新状态。逐站收件人通知本期不接入。 |
所有下列新 POST 接口使用 token 请求头和 JSON body。只有新接口采用“业务参数统一放 body”的约定;现有 GET、旧取件、旧目标调整、旧订单接口及 LINE Pay 接口的参数格式保持原样。响应仍为项目通用 AjaxResult,业务数据在 data 中;订单详情的 data 直接是订单对象,不再套一层 order。
先调用 GET /system/flashDelivery/home,使用 data.pickupStopLimit、data.deliveryStopLimit 控制添加站点按钮和提交数量。有效范围为 1–10,默认均为 1;对应上限大于 1 即可使用多站点,无需开关。兼容字段 showMultiPickup、showMultiDropoff 分别表示对应上限是否大于 1,showUrgentOption 始终为 true;加急选项直接展示。服务类型、配送等级和可用支付方式也从首页响应读取。
POST /system/flashDelivery/v2/quote 的示例 body:
{
"serviceType": "HELP_SEND",
"deliveryType": "NORMAL",
"vehicleType": 1,
"packageType": "DOCUMENT",
"quantity": 2,
"weightRange": "UP_TO_5_KG",
"specification": "两个文件袋",
"tipAmount": 0,
"deliveryMode": "NOW",
"payType": "4",
"stops": [
{"type":"PICKUP","name":"取件人甲","phone":"0911000001","address":"台北市信义区甲路1号","addressDetail":"1楼","longitude":121.5601,"latitude":25.0301,"remark":"取文件袋甲"},
{"type":"PICKUP","name":"取件人乙","phone":"0911000002","address":"台北市信义区乙路2号","longitude":121.5602,"latitude":25.0302,"remark":"取文件袋乙"},
{"type":"DELIVERY","name":"收件人丙","phone":"0911000003","address":"台北市大安区丙路3号","longitude":121.5603,"latitude":25.0303,"remark":"交给本人"},
{"type":"DELIVERY","name":"收件人丁","phone":"0911000004","address":"台北市大安区丁路4号","longitude":121.5604,"latitude":25.0304,"remark":"交前台"}
]
}
至少一个 PICKUP 和一个 DELIVERY,取货站必须排在所有收货站之前,路线顺序就是数组顺序;同一地址或坐标不能重复。每站分别填写姓名、电话、完整地址和经纬度,可选门牌、交接方式、最长 200 字备注。v2 站点不要提交旧结构中的逐站物品字段;packageType、正整数 quantity、可选 weightRange 和 specification 只在订单级出现一次。SCHEDULED 订单还需提交 scheduledPickupStartAt、scheduledPickupEndAt,NOW 订单无需提交这两个字段。
创建订单使用 POST /system/flashDelivery/v2/orders。body 包含报价时的业务字段和完整 stops,再增加:
{
"clientRequestId": "客户端生成并持久保存的本次下单请求号",
"pricingId": 123,
"pricingVersion": 1,
"quotedBaseDeliveryFee": 80,
"quotedDistanceFee": 10,
"quotedUrgentFee": 0,
"quotedAmount": 90,
"pinRequired": true,
"senderImageUrls": [],
"userNote": "请注意文件袋"
}
上述价格数字只展示字段形状,实际值必须取本次报价 data 的 pricingId、pricingVersion、baseDeliveryFee、distanceFee、urgentFee、amount,不可使用示例数字。clientRequestId 最长 64 字符;同一次创建的网络重试使用相同值,新订单使用新值。pinRequired 省略时默认为 true,开启后每个收货站有独立四位收货码。报价在创建前变化时,接口会返回错误并在 data 附最新报价;展示新金额让用户重新确认后再提交。
GET /system/flashDelivery/orders?role=sender|receiver&page=1&size=10;receiver 包括每一个已匹配到系统普通用户的收货站。收件人列表卡片展示自己的收货地址。GET /system/flashDelivery/orders/{id};按订单号打开消息:GET /system/flashDelivery/orders/byOrderNo?orderNo=...。GET /system/flashDelivery/rider/orders、GET /system/flashDelivery/rider/orders/{id},沿用原有 tab、分页和可选坐标参数。详情 data.stops 按路线顺序返回。请求站点字段叫 type,响应字段叫 stopType;响应的 id 才是后续履约所需的 stopId,stopOrder 从 0 开始。每站有 status、remark、pickedUpAt/deliveredAt 和 imageUrls。列表与详情提供 pickupStopCount、pickedUpStopCount、deliveryStopCount、deliveredStopCount。部分取货时整单仍为 ACCEPTED;全部取完为 PICKED_UP;部分送达仍为 PICKED_UP;全部送达为 DELIVERED;确认收货或平台/系统完成后为 COMPLETED。页面不要只靠整单 status 推算逐站进度。
v2 的订单级 deliveryPinCode 为空,收货码在各个 DELIVERY 站的 stops[].deliveryPinCode。发起人可查看全部收货码;已在系统内匹配的收件人只能查看自己站的收货码及联系人、精确地址和凭证;骑手看不到任何实际收货码。未匹配系统用户的收货站仍可下单,但此人不会进入“我收的”列表,也不会收到 App 推送;发起人需自行告知该站收货码。逐站收件人通知本期暂缓。
用户端取消按钮以 canUserCancel 为准;任一取货站已取货后不可自助取消。确认收货入口只在整单 DELIVERED 后提供;系统仍会检查全部收货站是否真的已送达。骑手收入账单只在订单进入 COMPLETED 时生成一次。
骑手从详情 currentTargetStopId 定位当前站点;默认依次指向最早未完成的取货站,全部取完后依次指向最早未送达的收货站。操作成功后重新请求详情,不继续使用旧的目标 ID、状态或版本。
| 操作 | 当前接口 | 提交内容 |
|---|---|---|
| 逐站取货 | POST /system/flashDelivery/rider/orders/{id}/stops/{stopId}/pickup |
现有接口,body 为 {"imageUrls":["/profile/pickup.jpg"]};如同时传 stopId,必须与路径一致。 |
| 选择目标站 | POST /system/flashDelivery/rider/orders/{id}/stops/{stopId}/target |
现有接口,body 含 orderVersion、clientRequestId,改变默认目标时还需 reason 和 consentDeclared:true。 |
| 逐站送达 | POST /system/flashDelivery/rider/orders/stops/deliver |
新接口,body 含 orderId、stopId、imageUrls,启用 PIN 时再传该站 pinCode。 |
取货和送达凭证每站至少 1 张、最多 9 张。新送达接口中 orderId、stopId 均为正整数;只有一个收货站的 v2 订单也必须传 stopId。骑手在送达现场向收件人核对其本站收货码,不能使用别站或订单级收货码。新骑手端可统一根据详情中的站点 ID 使用逐站送达接口;旧 /rider/orders/{id}/deliver 只供旧客户端处理旧订单,v2 订单调用它会被拒绝。
送达非当前目标站会被拒绝。改变顺序时,先取得发起人同意,再使用目标调整接口登记原因和 consentDeclared:true;该字段是骑手声明,当前没有发起人 App 内审批流程。调整请求的 clientRequestId 在同一次操作重试时保持不变。某站已成功取货或送达的重试不会重复保存照片和进度;末站送达后主状态已变化时也是如此。
仅待接单、未分配骑手的 v2 订单可编辑。先从详情读取 orderVersion 和完整站点,编辑后提交所有取货与收货站;只提交被修改的一站会丢失其余站点,因此服务端要求完整数组。
POST /system/flashDelivery/v2/orders/address/quote
token: <登录 token>
Content-Type: application/json
{"orderId":10,"orderVersion":0,"stops":[{"type":"PICKUP","name":"...","phone":"...","address":"...","longitude":121.56,"latitude":25.03},{"type":"DELIVERY","name":"...","phone":"...","address":"...","longitude":121.57,"latitude":25.04}]}
确认保存调用 POST /system/flashDelivery/v2/orders/address,body 保留相同的 orderId、orderVersion、完整 stops,再回传报价 data 中的 distanceMeters→quotedDistanceMeters、baseDeliveryFee→quotedBaseDeliveryFee、distanceFee→quotedDistanceFee、urgentFee→quotedUrgentFee、amount→quotedAmount。只改站点,物品、配送方式、小费和原运价快照继续沿用订单保存值。报价或版本变化时重新获取并让用户确认。保存成功后以返回详情更新全部 stops[].id 和各站收货码;旧站点 ID 已失效。旧改址入口会拒绝 v2 订单,旧订单仍沿用原入口。
每个取货/收货站首次成功且事务提交后,服务端向订单发起人推送并写入消息中心。两种 eventType:FLASH_PICKUP_STOP_COMPLETED、FLASH_DELIVERY_STOP_COMPLETED。消息 payload 示例:
{
"ddId": "订单号",
"state": "PICKED_UP",
"type": -1,
"pushType": 3,
"eventType": "FLASH_PICKUP_STOP_COMPLETED",
"stopId": 13,
"stopType": "PICKUP",
"stopOrder": 0,
"completedStopCount": 2,
"totalStopCount": 2
}
state 是通知发生时真实的整单状态,不应写死为示例值;stopOrder 为路线数组的 0 基下标,通知文案的站号为 1 基。收到事件后按 ddId 请求 /orders/byOrderNo 并刷新详情;不要从消息体推断联系人、地址或 PIN。相同站点的重试不重复通知,最后一站也不叠发旧整单阶段通知。逐站收件人通知留待后续需求。
stopId。PICKED_UP,不能提前确认完成或记账。现有单点、支付及其他旧接口以 原闪送 App API 文档 为准。数据库结构和不同环境的执行方式见 10 月 14 日 SQL 说明;本次问题修复没有额外字段变更;2026-10-14 测试库已按旧版增量路径完成结构与字典更新,其他环境仍需按 SQL 说明执行。