spec.md 26 KB

功能规格:闪送配送服务

功能标识024-flash-delivery

创建日期:2026-08-31

状态:平台前端与外卖同规则时段运价调整已验证;App 订单列表与详情精简已提交,定向测试与模块构建通过

输入:基于蓝湖“闪送”分组 7 个设计页面及 2026-08-24 用户端/骑手端补充原型,实现帮送、帮取、加急送的完整非支付业务闭环,包括共享地址簿、路线报价、包裹信息、立即/预约配送、可选 PIN 交付、创建订单、骑手主动抢单、取件、送达、用户签收、平台配置与介入。

用户场景与测试

用户故事 1:用户获取报价并发布闪送订单(优先级:P1)

用户选择帮送、帮取或加急送,填写取件与收件地址后获取服务端报价,并发布一笔等待骑手接单的闪送订单。

优先级原因:报价与发布订单是闪送服务成立的基础,没有该能力就无法形成可配送任务。

独立测试:为同一组取件和收件坐标分别选择三种服务,验证系统按服务类型和当前时间匹配运价时段,使用与外卖订单一致的起送与里程规则返回整数新台币报价,并在创建订单时重新计算价格、保存地址与计价快照且进入待接单状态。

验收场景

  1. 假如 当前时间命中所选服务类型的运价时段, 用户请求报价,那么 系统使用该时段的起送距离、起送价格、计价距离和计价金额计算报价。
  2. 假如 路线距离超过起送距离不足 0.5 公里、达到 0.5 公里但不足 1 公里或超过 1 公里, 用户请求报价,那么 系统分别按 0、1 公里或实际超出距离计算里程费用,并将新台币金额四舍五入为整数元。
  3. 假如 地图路线服务正常, 用户请求报价,那么 系统使用路线距离并标记距离来源为路线服务。
  4. 假如 地图路线服务超时或失败, 用户请求报价,那么 系统使用经纬度直线距离降级报价并明确标记距离来源。
  5. 假如 客户端提交伪造金额或距离, 用户创建订单,那么 系统忽略客户端金额与距离并在服务端重新报价。
  6. 假如 同一用户以相同客户端请求号重复创建订单, 请求被重复处理,那么 系统返回同一订单且不产生重复订单。
  7. 假如 用户选择预约配送, 创建订单,那么 系统保存 30 分钟取件时段,预约开始前订单不进入骑手可抢列表。
  8. 假如 路线距离超过 40 公里, 用户报价或创建订单,那么 系统拒绝请求。

用户故事 2:骑手从闪送列表主动抢单并完成配送(优先级:P1)

骑手通过与骑手外卖订单一致的单一分页列表和页签参数查看新任务、待取件、配送中、已完成及已取消任务,主动抢单后依次上传取件和送达图片,完成实际配送。

优先级原因:第一版明确采用骑手主动抢单,不实现自动派单;抢单与配送状态流转是业务闭环的核心。

独立测试:使用 page、size、tab、longitude、latitude 查询骑手闪送列表,验证五个页签的状态映射、本人订单边界、附近任务距离和接单前字段;再由两个骑手并发抢同一订单,验证只有一个骑手成功,成功骑手上传取件和送达图片后订单依次进入已取件和已送达状态。

验收场景

  1. 假如 骑手传入 tab=newTask 和当前位置, 查询闪送列表,那么 系统只返回当前可抢任务,并按与骑手外卖新任务列表一致的附近范围和距离规则处理。
  2. 假如 两名骑手同时抢同一订单, 两个请求并发到达,那么 只有一名骑手成功,另一名收到订单已被接走的业务结果。
  3. 假如 骑手尚未抢到订单, 其尝试确认取件或送达,那么 系统拒绝操作且不泄露完整联系方式。
  4. 假如 已接单骑手未提交取件图片, 其确认取件,那么 系统拒绝状态变更。
  5. 假如 已取件骑手未提交送达图片, 其确认送达,那么 系统拒绝状态变更。
  6. 假如 图片要求已满足, 订单骑手按顺序确认取件和送达,那么 系统保存凭证、操作人和时间并完成对应状态变更。
  7. 假如 订单启用 PIN 交付, 骑手提交错误 PIN,那么 系统拒绝送达且不保存送达图片或改变状态。
  8. 假如 订单启用 PIN 交付, 骑手提交正确 PIN 和送达图片,那么 系统验证 PIN 后进入已送达状态。
  9. 假如 骑手尚未接单, 查看列表或详情,那么 系统按原型返回完整取送文字地址、包裹、时段、路线、金额和是否需要 PIN 等接单判断信息,但不返回联系人、电话、实际 PIN、精确坐标或内部字段。
  10. 假如 骑手切换 toPickupdeliveringcompletedcancelled 页签, 查询列表,那么 系统只返回当前骑手本人且符合页签状态映射的任务。
  11. 假如 骑手查看列表顶部摘要, 当前页签为 newTask那么 系统返回附近任务总数和最高订单金额,不返回尖峰倍率或骑手收入字段。

用户故事 3:用户安全管理共享地址簿(优先级:P1)

用户在闪送与现有收货场景中共用同一个地址簿,可以搜索、新增、修改、查看、删除和置顶自己的地址。

优先级原因:蓝湖设计中的取件地址、收件地址和地址簿均依赖该能力,同时现有地址接口需要消除跨用户访问风险。

独立测试:准备用户 A 与用户 B 的地址,以用户 A 身份执行列表、详情、修改、删除和置顶操作,验证只能访问 A 的地址,所有针对 B 地址的请求均被拒绝。

验收场景

  1. 假如 用户拥有多条地址, 用户按姓名、电话或地址关键词搜索,那么 系统只返回该用户自己的匹配地址。
  2. 假如 用户置顶一条地址, 再次查询地址列表,那么 该地址排在当前用户其他地址之前。
  3. 假如 用户提交其他用户的地址 ID, 其尝试查看、修改、删除或置顶,那么 系统拒绝操作且不返回目标地址内容。
  4. 假如 客户端在新增或修改地址时提交 userId 系统保存地址,那么 系统忽略该字段并以登录用户身份确定归属。

用户故事 4:用户跟踪、取消和签收自己的订单(优先级:P1)

用户查看自己的闪送订单与履约进度,可以在允许阶段取消订单,并在骑手送达后确认签收。

优先级原因:用户需要了解履约进度,并对尚未实际取件的订单保留取消能力。

独立测试:分别创建处于待接单、已接单、已取件和已送达状态的订单,验证用户取消和签收权限符合状态机规则,并验证送达 24 小时后的自动完成。

验收场景

  1. 假如 订单处于待接单或已接单, 订单用户取消,那么 订单进入已取消状态并记录原因。
  2. 假如 订单已取件, 订单用户尝试取消,那么 系统拒绝并要求平台介入。
  3. 假如 骑手已确认送达, 订单用户确认签收,那么 订单进入已完成状态。
  4. 假如 骑手送达后用户 24 小时未确认, 自动完成任务执行,那么 订单进入已完成状态并记录自动操作日志。
  5. 假如 用户访问其他用户的订单, 其查询详情、取消或签收,那么 系统拒绝访问。
  6. 假如 用户查询订单列表, 仅提交 pagesize那么 系统按创建时间倒序返回本人各状态订单的轻量摘要,不要求客户端提交 scenestatusserviceType

用户故事 5:平台管理时段运价并介入异常订单(优先级:P2)

平台管理员为三种闪送服务分别维护多个运价时段,查询全部闪送订单,并在取件后的异常场景中取消或完成订单。

优先级原因:价格必须可运营调整,取件后的订单又必须具备受控的人工处置入口。

独立测试:管理员新增、修改和删除加急送运价时段,验证重叠时段被拒绝、保存后立即生效、新报价使用当前时段及最新版本;随后对已取件订单执行平台取消并检查状态日志。

验收场景

  1. 假如 管理员新增或修改某一服务类型的运价时段, 新请求在该时段内报价,那么 新报价立即使用新配置且已创建订单价格不变。
  2. 假如 时间范围重叠、起止时间非法、距离或金额不是正数、金额不是整数或服务类型非法, 管理员提交配置,那么 系统拒绝保存。
  3. 假如 普通用户或骑手调用平台配置或介入接口, 权限校验执行,那么 系统拒绝操作。
  4. 假如 订单已取件但发生异常, 有权限的管理员取消订单,那么 系统允许取消并记录管理员、原因和时间。
  5. 假如 订单已送达但用户无法确认, 有权限的管理员确认完成,那么 系统完成订单并记录平台操作日志。

用户故事 6:平台在管理后台配置价格并处理闪送订单(优先级:P2)

平台管理员从“闪送管理”菜单进入价格配置或订单管理页面,无需直接调用接口即可维护三种服务价格、筛选订单、查看完整履约资料并执行受权限控制的平台介入。

优先级原因:后端接口已具备,但缺少平台可操作入口会导致计价只能通过接口工具维护,异常订单也无法进入日常运营流程。

独立测试:以拥有完整闪送权限的管理员登录后台,分别完成三种服务价格读取与修改、订单组合筛选、详情查看、异常取消和已送达订单完成;再以缺少对应权限的账号验证菜单与操作按钮不可用。

验收场景

  1. 假如 管理员进入价格配置页面, 页面加载,那么 系统按帮送、帮取和加急送展示全部运价时段、起送规则、计价规则及配置版本。
  2. 假如 管理员新增、修改或删除合法时段, 操作成功,那么 页面刷新服务端配置;非法值、重叠时段或并发冲突必须保留编辑内容并展示错误。
  3. 假如 管理员进入订单页面, 按状态、服务类型、订单号、用户 ID 或骑手 ID 查询,那么 表格按服务端分页结果展示并可重置条件。
  4. 假如 管理员查看订单详情, 详情加载,那么 页面分区展示订单概况、取送地址、费用明细、预约与 PIN、骑手、图片凭证和状态日志。
  5. 假如 订单处于非终态, 具有取消权限的管理员填写原因并二次确认,那么 页面调用平台取消接口并刷新列表与详情。
  6. 假如 订单处于已送达状态, 具有完成权限的管理员二次确认,那么 页面调用平台完成接口并刷新订单状态。

边界情况

  • 取件地址和收件地址相同或坐标相同,不允许创建订单。
  • 地址缺少联系人、联系电话、完整地址或有效经纬度时,不允许用于报价和创建订单。
  • 经纬度超出合法范围时拒绝请求,不调用地图服务。
  • 对应服务类型在当前时间没有匹配的运价时段时,不允许报价或创建订单,并返回“当前时段暂无可用运价”。
  • 地图路线结果缺少有效距离时按路线失败处理并降级为直线距离。
  • 创建订单时当前配置与先前报价时不同,以创建时服务端重新计算结果为准。
  • 待接单列表仅返回待接单订单;已取消或已被抢走的订单不得继续出现在新查询结果中。
  • 待抢订单列表按原型显示完整取送文字地址,但隐藏联系人、电话、实际 PIN、精确坐标和内部字段;抢单成功后订单骑手才能读取履约所需的完整联系方式与坐标。
  • 骑手第一版不能自行放弃已抢订单,需要平台介入处理。
  • 已完成和已取消为终态,不允许再次变更。
  • 自动完成任务与用户确认、平台完成并发时,只允许一个状态变更成功且不得重复写入完成副作用。
  • 价格接口暂时无数据时,价格页面必须显示空状态,不得使用前端默认价格冒充服务端配置。
  • 订单详情加载失败时不得保留上一笔订单资料;取消或完成失败时不得提前修改本地状态。
  • 图片凭证为空时显示明确空状态;图片加载失败不得阻塞其他订单资料展示。

需求

功能需求

  • FR-001:系统必须提供帮送、帮取和加急送三种服务类型。
  • FR-002:帮取只承担取件配送,不包含代购、垫付或商品金额。
  • FR-003:三种服务必须使用同一订单履约状态机;加急送仅在排序和计价上体现优先级。
  • FR-004:系统必须按服务类型维护多个运价时段,每个时段保存开始时间、结束时间、起送距离、起送价格、计价距离、计价金额、配置版本与修改记录;配置保存即生效,不设置启停状态。
  • FR-005:报价必须先按服务类型和当前时间匹配唯一运价时段;同一服务类型的时间段不得重叠,没有匹配时段时必须拒绝报价和创建订单。
  • FR-006:计价必须与现有外卖订单一致:起送距离内只收起送价格;超出不足 0.5 公里不加价,超出 0.5 公里但不足 1 公里按 1 公里计,超出至少 1 公里按实际超出距离计;里程费用四舍五入到整数元后与起送价格相加,所有 TWD 金额均为整数且不再按百位或千位特殊取整。
  • FR-007:系统必须优先使用地图路线距离,地图失败时使用经纬度直线距离并向客户端返回距离来源。
  • FR-008:地图密钥必须从服务端配置读取,不得返回客户端或写入业务日志。
  • FR-009:创建订单时必须由服务端重新计算距离和价格,并保存地址、路线、金额和计价配置快照。
  • FR-010:系统必须使用客户端请求号保证同一用户的订单创建幂等。
  • FR-011:闪送订单不得复用餐饮订单或打车订单数据模型。
  • FR-012:订单必须保存包裹类别和机车可载重量档,重量档为 SMALL(不超过 5kg)、MEDIUM(不超过 12kg)或 LARGE(不超过 20kg);不保存精确重量或件数。
  • FR-013:订单必须支持用户备注,但备注不参与计价。
  • FR-014:骑手必须通过统一闪送订单列表的 newTask 页签主动抢单,第一阶段不实现自动派单。
  • FR-015:骑手闪送列表必须复用骑手外卖订单列表的查询参数名称和分页习惯:pagesizetablongitudelatitude;不得再拆分为 availablemine 或叠加 scenestatusserviceType 筛选。
  • FR-016:骑手抢单必须使用原子条件更新,确保同一订单最多由一名骑手抢到。
  • FR-017:订单状态必须包括待接单、已接单、已取件、已送达、已完成和已取消。
  • FR-018:只有抢到订单的骑手能够确认取件和送达。
  • FR-019:确认取件必须至少提供一张取件图片;确认送达必须至少提供一张送达图片。
  • FR-020:系统必须保存取件和送达图片 URL、凭证类型、操作骑手和操作时间。
  • FR-021:用户只能在待接单或已接单状态取消自己的订单。
  • FR-022:订单已取件后,用户和骑手均不能自行取消,只有有权限的平台管理员能够介入取消。
  • FR-023:骑手确认送达后,用户可以确认签收并完成订单。
  • FR-024:送达后 24 小时未确认的订单必须自动完成,并留下可审计日志。
  • FR-025:平台管理员能够查询全部闪送订单及日志,并在允许状态执行取消或完成操作。
  • FR-026:每次有效状态变更必须记录变更前状态、变更后状态、操作人类型、操作人 ID、原因和时间。
  • FR-027:所有状态变更必须校验当前状态、业务归属和操作角色,并防止并发覆盖。
  • FR-028:用户只能查询、取消和签收自己的闪送订单。
  • FR-029:骑手在抢单前可查看完整取送文字地址及履约判断所需的订单摘要,但不得获得联系人、电话、实际 PIN、精确坐标或内部字段;抢单成功后才能查看完整联系方式和坐标。
  • FR-030:闪送必须与现有收货场景共用 info_address 地址数据。
  • FR-031:统一地址接口必须要求登录身份,并对详情、修改、删除和置顶执行地址所有权校验。
  • FR-032:地址列表必须支持按当前用户的姓名、电话和地址关键词搜索,并支持置顶排序。
  • FR-033:地址保存接口必须忽略客户端提供的用户 ID,以当前登录用户确定地址归属。
  • FR-034:所有用户端和骑手端接口必须直接读取请求头 token;不得接受客户端提交的用户或骑手身份。
  • FR-035:所有平台接口必须使用后台权限校验,并为配置查询、配置修改、订单查询和订单介入设置明确权限。
  • FR-036:所有请求必须使用明确 DTO 或显式查询参数,Controller 不得使用 Map 接收请求。
  • FR-037:所有业务校验错误必须通过项目国际化消息机制返回,不得硬编码单一语言错误。
  • FR-038:系统必须复用现有上传能力;闪送接口仅接收上传完成后的图片 URL。
  • FR-039:本功能的数据库变更只能记录在 updatesql/sql.md,不得直接执行。
  • FR-040:订单必须支持 NOWSCHEDULED 两种配送方式;预约时段固定为 30 分钟且不得晚于创建时间后三天。
  • FR-041:预约订单在预约开始时间前不得出现在可抢列表,也不得被骑手通过订单 ID 提前抢取。
  • FR-042:用户可选择是否启用 4 位数字交付 PIN;启用后骑手必须同时提交正确 PIN 和至少一张送达图片。
  • FR-043:PIN 只对订单用户和有权限的平台管理员可见,不得返回给待接单或已接单骑手,也不得写入业务日志。
  • FR-044:创建订单可提交 1 至 9 张可选寄件图片;凭证类型扩展为 SENDERPICKUPDELIVERY 并记录操作人类型。
  • FR-045:用户订单列表必须只接收 pagesize,按创建时间倒序返回本人全部状态的轻量摘要;骑手订单列表必须按 tab 在服务端映射底层状态并完成分页,禁止先分页后由客户端过滤。
  • FR-046:用户列表、骑手列表和角色详情必须分别使用专用响应视图。App 详情响应的 data 必须直接是订单详情,不得再套 orderimageslogs;照片使用 senderImageUrlspickupImageUrlsdeliveryImageUrls 等明确字段,原始状态日志只允许平台审计详情返回。
  • FR-047:骑手接单后,用户可读取骑手昵称、头像和评分等公开摘要;实时位置只在配送进行状态向订单用户返回。
  • FR-048:路线距离不得超过 40 公里;超过限制时报价和创建均拒绝。
  • FR-049:平台管理前端必须提供“闪送管理”父菜单,并提供“价格配置”和“闪送订单”两个子页面。
  • FR-050:平台前端必须通过现有六个 flash:* 权限分别控制页面访问、价格修改、订单查看、取消和完成操作,不得仅依赖按钮隐藏代替后端鉴权。
  • FR-051:价格配置页面必须按服务类型展示全部时段,并支持新增、修改和删除;表单字段为 startTimeendTimestartingDistancestartingFaredistancefreight,同时展示只读配置版本与更新时间。
  • FR-052:价格表单必须校验时间范围有效、同服务时间段不重叠、距离为正数、起送价格和计价金额为正整数;配置保存即生效,删除后立即不可用于报价,操作成功后必须重新读取服务端列表。
  • FR-053:订单页面必须按服务端分页,并支持状态、服务类型、订单号、用户 ID 和骑手 ID 组合筛选及一键重置。
  • FR-054:平台订单详情必须展示订单概况、取送地址、路线与费用、预约与 PIN、骑手 ID 与履约时间、三类图片凭证及状态日志;不得要求管理员从列表字段拼接详情。
  • FR-055:平台取消必须要求非空原因和二次确认;平台完成必须二次确认。操作成功后刷新服务端数据,操作失败时保留当前页面并显示后端错误。
  • FR-056:平台前端新增的全部用户可见文本必须通过 Vue i18n 提供简体中文、繁体中文、英文和越南文,不得硬编码单一语言文本。
  • FR-057:平台前端必须沿用现有 Vue 2、Element UI、若依请求封装、动态菜单和 v-hasPermi 体系,不新增重复的状态管理或 UI 框架。
  • FR-058:骑手列表 tab 只接受 newTasktoPickupdeliveringcompletedcancelled,分别映射待接单、已接单、已取件、已送达/已完成和已取消;闪送不提供外卖退款页签。
  • FR-059:骑手 newTask 列表必须返回取件点距离、路线距离、预计时长、订单金额、包裹类别、重量档、配送方式、预约时段、完整取送文字地址和是否需要 PIN,并返回附近任务总数与最高订单金额;不得返回已移除的尖峰倍率或尚未实现的骑手收入。
  • FR-060:用户创建订单、用户详情、骑手详情和骑手接单成功响应必须使用直接且稳定的 App 订单详情结构;权限差异只影响敏感字段是否返回,不得改变 data 的顶层形状,也不得要求 App 通过 data.order 是否存在判断响应类型。

关键实体

  • 闪送订单:用户发布的取件配送任务,持有地址、路线、价格、服务类型、履约状态和关键时间快照。
  • 计价配置:某一服务类型在一个时间范围内立即生效的起送距离、起送价格、计价距离、计价金额及版本信息。
  • 配送凭证:用户下单时的可选寄件图片,以及骑手取件或送达时提交的必填图片记录。
  • 订单状态日志:记录订单每次有效状态变化的操作审计信息。
  • 共享地址:属于单一用户、可供闪送和现有收货业务共同使用的联系人与地点信息。

成功标准

  • SC-001:三种服务的当前时段匹配、起送距离、0.5 公里边界、实际超出距离、整数新台币取整和加急配置报价测试全部通过。
  • SC-002:地图路线成功和失败降级场景均能在一次请求内返回可用报价,并准确标记距离来源。
  • SC-003:至少 20 个并发抢单请求针对同一订单时,数据库中恰好只有一名骑手成功绑定。
  • SC-004:跨用户地址和订单的详情、修改、删除、置顶、取消及签收测试拦截率达到 100%。
  • SC-005:缺少取件或送达图片的状态变更请求拦截率达到 100%。
  • SC-006:所有允许和禁止的状态流转均有自动化测试覆盖,终态订单不能再次改变状态。
  • SC-007:送达超过 24 小时的订单能够自动完成,且并发确认不会产生重复状态日志或重复副作用。
  • SC-008:修改计价配置后,新订单使用新版本,历史订单保存的价格与配置快照保持不变。
  • SC-009:所有新增用户可见业务错误均能通过项目支持的语言资源解析,不出现硬编码单一语言结果。
  • SC-010:拥有对应权限的管理员能够只通过平台页面完成三种服务价格维护和订单查询、详情、取消及完成操作,核心流程无需 Postman 或数据库操作。
  • SC-011:价格和订单页面的接口路径、请求方法、查询参数及权限字符串契约测试全部通过,四个前端语言文件的 flashDelivery key 集合完全一致。
  • SC-012:平台前端生产构建通过,新增页面在 1280px 及以上后台常用宽度无横向页面溢出,表格窄屏时仅在表格区域滚动。

假设

  • 继续使用现有用户、骑手、token、骑手位置、图片上传和站内消息/推送基础设施。
  • 地图路线服务的具体供应商与密钥沿用项目现有配置能力;计划阶段确定现有配置键和 HTTP 调用位置。
  • 币种为新台币,接口使用稳定币种代码 TWD
  • 第一阶段不根据有效骑手数量阻止下单,也不实现自动匹配、自动派单或定向派单。
  • 蓝湖页面中的附近骑手数量与预计接单时间第一阶段不作为动态业务承诺。
  • 骑手第一阶段不能自行放弃已抢订单,由平台管理员介入处理异常订单。

非目标

  • 不接入支付网关、付款、退款、取消费、退回费、结算或骑手收入分账。
  • 不实现代购、垫付款、商品金额、精确重量、件数或禁寄品电子确认;禁运品、货值和尺寸限制由前端展示规则说明,后端只校验本期明确的重量档和最大路线距离。
  • 不实现自动派单、抢单推送筛选、骑手在线状态计算或接单时间预测。
  • 不修改餐饮订单 pos_order 或打车订单 taxi_order 的业务语义。
  • 不在本功能中实现用户端、骑手端或商家端页面;本轮前端增量仅实现平台管理端。