Przeglądaj źródła

补齐多店订单两端展示方案及超时边界规格

qmj 6 dni temu
rodzic
commit
fa5e2c39c6

+ 10 - 3
specs/036-multi-store-checkout/contracts/api.md

@@ -1,6 +1,6 @@
 # 多店结算接口契约(实施版)
 
-路径均为 `/system/multiStoreCheckout` 前缀;用户接口使用 `@RequestHeader String token`,POST 使用明确 DTO 与 `@RequestBody`,GET 参数显式声明。App 仅据此接入,不修改 App 源码。错误响应使用现有 `AjaxResult` 及项目 i18n 消息,不返回硬编码单语言字符串。
+路径均为 `/system/multiStoreCheckout` 前缀;用户接口使用 `@RequestHeader String token`,POST 使用明确 DTO 与 `@RequestBody`,GET 参数显式声明。App 仅据此接入,不修改 App 源码。错误响应使用现有 `AjaxResult` 及项目 i18n 消息,不返回硬编码单语言字符串。用户端批次卡与骑手端组任务卡、参考闪送的单工作页签/取送双进度及服务端分页建议见 [两端联合方案](../frontend-display-plan.md),展示细节尚待确认;下方旧拟议 POST 路径若包含业务 ID,实施前须按用户已确认的“有 body 则业务参数统一放 body”要求收口。
 
 ## 用户流程
 
@@ -17,7 +17,7 @@
 
 ## 骑手/平台
 
-- 骑手待抢列表对同骑手配送组只返回一个任务,显示各店及总计;已生效、到预约开放时点才可见。`POST /system/multiStoreCheckout/groups/{groupId}/accept` 原子承接全部有效成员;旧单笔接单 API 对组成员拒绝拆抢。骑手仍逐子单取餐/送达。
+- 骑手待抢列表对同骑手配送组只返回一个任务,显示各店及总计;已生效、到预约开放时点才可见。`POST /system/multiStoreCheckout/groups/accept`,JSON `{groupId,version}`,原子承接全部有效成员;旧单笔接单 API 对组成员拒绝拆抢。骑手仍逐子单取餐/送达。组详情与待抢/已接列表、角标的响应字段待联合展示方案确认后补齐,不把现有逐单列表当作已经支持组合卡。
 - 平台配置 `GET/PUT /system/multiStoreCheckout/config`:开关、围栏米、最多店数、缓冲分钟、可增删改折扣阶梯;保存会校验并更新规则版本,仅影响新报价。平台退款跟进列表显示各商家渠道、实收、退款意图/结果/待人工处理,不提供“手工标记渠道已退款”。
 - 平台配置只读写独立 `order_checkout_config`,不占用 `sys_config`。GET 返回 `enabled/fenceMeters/maxStores/confirmationBufferMinutes/version/tiers`,其中 `tiers` 为门槛数字键到系数的对象;PUT 将 `tiers` 作为 `{minimumStores,ratio}` 数组传入,并回传新版本。缺表或缺行时读取保守关闭,保存拒绝并提示先执行 036 迁移;客户端旧 `version` 不能覆盖新配置。
 - 新任务通知出站与预约旧时点扫描按持久记录幂等重试;组只推一个待抢任务,独立成员各推一个。用户付款通知与订单取餐/送达通知继续独立,不在未全额就绪时发骑手/商家履约新单。
@@ -26,4 +26,11 @@
 
 14:00 创建:14:15 前可发起线上/确认到付;14:14 已实际发起的线上尝试可在 14:20 前完成付款及可信确认;14:16 不可新发起或改到付;14:20 仍未全部就绪则关闭,迟到实收只退款不激活。截止在创建时快照,不因配置变更或重试延长。
 
-普通单仍调用现有 `/createOrder`、LINE/OMG/到付入口并保持原校验与状态;新接口不得仅凭客户端传入的批次号放宽原入口。预约订单不改旧时间语义或添加无人接单自动取消。
+普通单仍调用现有 `/createOrder`、LINE/OMG/到付入口并保持原校验与状态;新接口不得仅凭客户端传入的批次号放宽原入口。预约订单不重定义旧时间语义;2026-10-16 已确认新多店接入 037 现有无人接单规则,按父批次统一生效时间及实际开放时点判断,不以逐子单支付时间开始。
+
+## 2026-10-16 已确认的边界补充(尚待实现)
+
+- 批次详情返回 `activatedAt`,组详情返回 `openedAt`,并由服务端给出真实阶段/允许操作;App 不从付款时间推导无人接单倒计时。按现有阈值自动取消未承接组时,整组从待抢消失,详情保留逐店取消及退款进度,迟到实收不重开。
+- 未生效预约在激活时已到或超过结束则取消,返回原预约已过期的业务结果及真实退款进度,不返回可抢状态、不自动改即时;已生效任务不由此检查取消。
+- 建批后收货地址/坐标固定,地址簿变化不修改订单;首版无多店改址。用户要换地址按现有整批/子单取消权限处理后重新报价,不能只修改某店或绕过已接单禁取消。
+- 配置 PUT 降低最大门店数时,存在超限未结束未承接组则保存失败、原配置和版本不变;提示先处理存量组。已接组不受影响;失败不暗中取消订单或改变费用。

+ 8 - 0
specs/036-multi-store-checkout/data-model.md

@@ -9,14 +9,18 @@
 | `order_checkout_config` | 固定 `id=1`;`enabled`、`fence_meters`、`max_stores`、`confirmation_buffer_minutes`、`tiers_json`、`version` | 平台全局配置专表,固定项用独立列,动态折扣阶梯用 JSON;版本用于报价指纹和后台乐观锁,不接 `sys_config`。 |
 | `order_checkout_batch` | `id`;`parent_dd_id` 唯一;`(user_id,request_key)` 唯一;专用 `checkout_status`、`version`、`create_time`、`operation_deadline_at`、`final_deadline_at`、`confirmation_buffer_minutes` | 服务端批次标识、幂等创建、15 分钟发起截止和创建时缓冲快照;专用状态只表示统一履约资格,不代表退款到账。 |
 | `order_checkout_batch` 规则列 | `anchor_store_id`、`address_id`、`same_rider`、`fence_meters`、`max_store_count`、`rule_version`、`matched_min_stores`、`discount_ratio`、`total_amount` | 创建时冻结本次真实参与集合与计价规则;配置变化不追改。 |
+| `order_checkout_batch` 生效时间(待 T023 实现) | `activated_at` | 最后有效成员合法就绪、批次首次原子生效时写入,不能用某子单实收时间或后续 `update_time` 代替;生效后不因部分取消/重试改写。 |
 | `order_checkout_member` | `id`;`pos_order_id` 唯一;`(batch_id,store_id)` 唯一;`sort_no`、`payment_state`、`pay_type`、`ready_at`、`original_freight`、`discounted_freight`、`food_amount`、`amount`、`coupon_id` | 每店子单金额和付款/到付确认事实。`pay_type` 允许未选择;真实实收只来自渠道记录,不能把到付确认当作到账。 |
 | `order_checkout_payment_attempt` | `id`;`(channel,merchant_order_no)` 唯一;`member_id`、`pay_type`、`state`、`requested_at`、`dispatched_at`、`gateway_transaction_id`、`gateway_paid_at`、`verified_at` | 保存第 15 分钟前服务端发起的证据及其后缓冲内可信结果。请求预留不是实际发起;回调、查询及重试按原交易号对账。 |
 | `order_delivery_group` | `id`;`batch_id` 唯一;`rider_id`、`status`、`version` | 仅同骑手批次创建;组是一个抢单任务,不是合并收款或强制同步取送状态。 |
+| `order_delivery_group` 开放时间(待 T023 实现) | `opened_at` | 首次实际开放给骑手时原子写入并创建通知意图,不能从预约计划时点推算,也不因重试/部分取消改写。无配送组成员使用原 `display_time` 记录首次实际开放。 |
 | `order_checkout_outbox` | `id`;`(event_type,aggregate_id)` 唯一;`status`、`next_retry_at`、`attempts` | 生效/预约开放后的新任务推送,组按组、非组按子单去重;提交后发送、失败可重试、取消后不可再开放。 |
 | `order_checkout_refund_intent` | `id`;`(member_id,reason)` 唯一;`channel`、`amount`、`merchant_order_no`、`gateway_transaction_id`、`status`、`next_retry_at` | 跟踪 LINE/OMG 原路全额退款、未知结果和人工处理;意图创建不等于到账。到付未收不建网关退款意图。 |
 
 不在 `pos_order` 增加多店标志:以 `order_checkout_member.pos_order_id` 的唯一关联作为不可伪造服务端标识;老订单无关联即沿旧流程。容量统计与组列表通过成员表关联 `order_delivery_group`,避免为纯读取再加一列。父单 `order_parent` 沿用现有结构和子单号关联,其 `orderStatus` 不复用为批次生效或实收状态。
 
+2026-10-16 已确认的时间列是目标模型,当前 Entity/Mapper/SQL 尚待 T023 一批实现;本文更新不代表数据库已有这些列。地址与坐标使用建批时复制到父/子订单的快照;`address_id` 只保留原地址关联,不在付款、列表、取送时回读地址簿覆盖快照,旧单笔改址入口也不能改组成员。
+
 ## 2. 状态和不变量
 
 - 批次:`PENDING → ACTIVE` 或 `PENDING → CANCELLED`;`CANCELLED` 永不重开。到最终确认截止仍未全部合法就绪时关批次,截止后收到真实付款也只进入退款/对账,不转 `ACTIVE`。
@@ -26,11 +30,15 @@
 - 组接单:骑手锁 → 组行锁 → 成员子单按 ID 加锁;资格、现有任务容量、组门店上限和全部成员可接状态在锁内校验;全部分配或全部失败。单笔接单入口发现组成员必须拒绝拆抢。
 - 子单创建时写当前业务字段快照,但 `isDisplay` 不等于批次准入;骑手列表、直接接单、商家操作及新单通知均校验批次已 `ACTIVE` 和预约旧时点已开放。普通订单不套批次期限。
 - 组任务只有全部有效成员都履约结束或合法取消后释放。独立取餐、独立送达、独立结算/通知按子单进行,部分取消不重算余单折扣。
+- 已确认接入 037:无人接单基准为 `max(activated_at, opened_at, 预约开始)`(即时忽略预约);部分子单先付款不启动计时,部分取消不重置。超时与接组在统一锁/事务规则下互斥,未承接组取消剩余有效成员并关联现有渠道退款事实;无组成员使用父批次生效与本人实际开放时间按独立订单判断。
+- 尚未生效预约批次在激活时已到/超过原结束时间则转 `CANCELLED` 并退款,不自动改即时;恢复扫描补处理。已经 `ACTIVE` 的任务不因预约结束由此路径取消,继续依履约及 037 无人接单规则处理。
 
 ## 3. 平台配置和金额
 
 独立 `order_checkout_config` 单行保存全局开关、围栏距离米(默认 1000)、最多店数(默认 5)、缓冲分钟(默认 5)及 JSON 动态折扣阶梯(初始 `{2:0.9,3:0.8}`),配置保存时校验:围栏/最多店数/缓冲为正整数,门槛为不小于 2 的唯一整数,系数 `0 < ratio <= 1` 且最多四位小数,与批次快照 `DECIMAL(7,4)` 一致。开关/围栏/门店上限/阶梯缺失或非法时保守关闭新合并报价;缓冲异常回退 5 分钟,不变为无限。配置版本在同一行 CAS 增加并纳入报价指纹;创建时重算与报价版本不一致则要求重报。配置表缺行时读取显示关闭态、保存时提示执行 036 手动迁移,不能偷偷初始化为启用。
 
+2026-10-16 已确认:降低 `max_stores` 前检查未结束、未承接组的有效成员数,存在超出新值者拒绝保存且不增加配置版本,包含尚未生效的已建组;已接组继续履约。检查与建批的配置读取/版本重验以及组取消/承接必须具有一致并发保护,不能检查后又按旧配置建出超限未接组。
+
 首店门店坐标为圆心、对每个后续门店作球面直线距离,米精度比较 `distance <= fence_meters`;不以道路/用户地址距离代替。圈外店不进入本批次父/子单或金额;创建成员集合必须与确认报价一致,否则拒绝。
 
 每店原运费按现有有效规则权威计算;同骑手批次取最高满足门槛档位,对每店分别执行 `original_freight × ratio` 后 `HALF_UP` 到整数 TWD。子单 `amount = food_amount - valid_promotion_and_coupon_reduction + discounted_freight`,父单总额为子单实付之和。用户到付代收该子单 `amount`,给商家 `amount - discounted_freight`,商家给骑手折后运费;不存在跨商家补差。取消余单金额不重算。

+ 110 - 0
specs/036-multi-store-checkout/frontend-display-plan.md

@@ -0,0 +1,110 @@
+# 多店下单:用户端与骑手端列表、详情联合方案
+
+日期:2026-10-16。状态:方案草案,供本轮讨论;页面与列表接口尚未实现。本文件补充 036 的列表展示,不替代既有支付、退款、容量和逐子单履约规则。用户最新要求两端一起规划;以下新增卡片及筛选细节是建议,尚未视为用户确认。
+
+同日项目审查的四项建议已获用户确认,见 spec.md FR-042~045:多店接入 037、未生效预约过期、建批后地址冻结和下调上限保护。它们已纳入本轮实施要求,不能与本文件尚未实现的页面状态混为一谈。
+
+## 1. 两端共用的关系
+
+一次结算对应 `batchId`,每家店对应独立 `orderId`,选择同骑手时另有 `groupId`。用户查看结算批次,骑手承接配送组;两端通过成员子单关联,不能用同一用户、同一地址或时间接近来猜测关联。普通订单和历史订单无 036 成员关联时继续按原单笔方式展示。
+
+| 内容 | 用户端 | 骑手端 |
+|---|---|---|
+| 普通单 | 一单一张原订单卡 | 一单一张原任务卡 |
+| 036 多店 | 一个批次一张多店卡,卡内逐店展示 | 同骑手一个配送组一张任务卡,卡内逐店展示 |
+| 列表位置 | 在原订单列表按下单时间与普通单、闪送混排,来源仍是外卖 | 在原美食待抢、待取餐、配送中等列表与普通外卖任务混排 |
+| 主入口 | 批次详情和继续结算;逐店可查看子单详情 | 组详情和整组接单;逐店执行原取餐、送达等操作 |
+| 容量 | 不适用 | 组整体占一个任务;子单数量、卡片个数和页签角标不能替代容量计数 |
+
+圈外店不属于该批次或配送组,不出现在这张卡片内。不选择同骑手的成员不能因同批结算被包装成一个可整组承接的骑手任务。
+
+### 借鉴闪送多点取送
+
+已核对闪送现有骑手列表服务、列表 DTO、用户统一列表及 [v2 前端交接文档](../../docs/flash-delivery-v2-frontend-handoff.md)。闪送采用一笔订单一张卡、一个主流程页签,同时返回逐站摘要和取送双进度:尚未取完仍在待取件,即使已有站点送达;全部取完后进入配送中。多店采用相同展示原则,撤回本草案最初“同组同时出现在待取餐和配送中”的建议,避免同一任务跨工作页签重复出现。
+
+两端可复用卡头、取送进度和可展开明细的交互;多店明细使用成员子单,而非把各店强行转换成闪送 `stops`。闪送是一笔订单、多站履约;多店有独立商家、商品、付款、取消、退款和逐单账单。多店卡必须额外保留这些逐店事实,不复用闪送的整单收款或统一结算逻辑。当前工作区未提供 App 页面源码,本次核对的是后端实际返回及交付契约,不代表已验证真实 App 视觉效果。
+
+## 2. 用户端
+
+### 卡片与详情
+
+多店卡头显示“多店订单 · N 家店”、下单时间及批次当前阶段;卡内逐店显示店名、商品摘要、该店实付、付款方式、支付确认及履约状态。摘要同时列出创建时订单总额、线上已实收、已退/退款中及到付约定待收,不能把到付确认标成已经扣款。原总额及各店折后金额保持创建快照,取消和退款另列分项,不向剩余成员补差,也不把不同资金方向混成一个付款成功金额。
+
+未生效时显示“已确认 X/N 家”、支付发起截止、必要的核实中状态和“继续结算”。点击进入批次收银进度页,用户可以定位未就绪的店。截止后的缓冲期显示“付款结果核实中”,不再提供新发起、重试、换方式或到付确认;批次取消后显示各店真实退款进度。
+
+未生效预约核实齐付款时若已到或超过原预约结束,显示预约已过期、订单已取消及真实退款进度,不进入进行中、不自动转即时。建批后地址及坐标为快照,只读展示;修改地址簿不改变这批订单,页面不提供逐店改址。
+
+生效后仍保持一张多店卡,增加“已取餐 X/N 家 · 已送达 Y/N 单”的双进度,卡内分别显示“待接单、待取餐、配送中、已送达、已取消、退款中”等真实状态。点击卡头进入批次总览,点击店铺行进入该子单详情。取消或退款按现有 036 边界提供按钮,不能用一个汇总状态替所有子单执行操作。
+
+### 页签建议
+
+“全部”每批只出现一张卡。主流程页签按整批当前阶段归类,退款/售后作为补充筛选;部分退款不能把仍在配送的其他成员从进行中列表隐藏。
+
+| 页签 | 036 批次规则 |
+|---|---|
+| 待付款 | `PENDING` 批次,包括未选方式、部分付款、到付待确认、线上结果核实中;已付成员仍显示在同卡内 |
+| 进行中 | `ACTIVE` 且至少一个成员尚未履约结束或异常处理结束;卡内展示全部成员进度 |
+| 已完成 | 所有有效成员已结束且至少一单已送达;若另有取消成员,明确显示“部分取消”,不宣称每店都送达 |
+| 已取消 | 未生效整批取消,或生效后全部成员均已合法取消 |
+| 退款/售后 | 任一成员存在退款或售后记录;可同时出现在进行中等主流程页签,卡内明确标出涉及哪家店 |
+
+批次统一生效状态、履约汇总和退款结果是三个维度。禁止仅凭 `payStatus=1`、到付默认状态、某一家已付款或某一家进入售后推导整批已生效/已结束。
+
+## 3. 骑手端
+
+### 待抢任务
+
+批次已 `ACTIVE` 且达到预约原开放时点后,同骑手配送组才出现一次。卡头显示“多店配送 · N 店取餐 · 同一收货地址”;显示各取餐店名称、位置、即时/预约信息、共同送达位置,以及有效成员折后配送费合计。该金额沿原账单口径展示,不将其直接标为扣除佣金/税后的净收入。
+
+无人接单按 037 现有阈值处理,基准取统一生效、首次实际开放和预约开始的最晚值;某子单先付款不提前开始,部分取消不重置。超时未接组整组从待抢消失,相关详情显示逐店取消/退款结果;接组已成功则不会再被该超时路径取消,App 以服务端返回为准。
+
+需代收的到付金额单独展示,并逐店注明付款方式。线上已付餐费不能加入待代收现金;给各商家的到付款按各子单金额减该店折后运费展示。客户联系方式等信息继续遵守现有接单前后访问边界,不因组摘要额外公开。
+
+一个按钮“接此组订单”在服务端原子分配全部可承接成员,成功后返回最新组和成员;竞争失败则刷新。旧单笔接单入口拒绝拆抢组成员。部分成员在接单前合法取消时重新返回有效成员、费用及版本;不能把已取消成员继续交给骑手。
+
+距离建议:显示各取餐店到骑手的直线距离,用最近有效取餐店的距离作为待抢排序及原距离门槛的参考。该建议尚待确认;首店围栏仍按用户选择的首店计算,与骑手距离是不同条件。页面不把门店编号或该排序显示为强制取餐路线,不新增自动路线优化。
+
+### 已接任务及混合进度
+
+接单后保留组卡和同一组标识,沿闪送方式同时显示“已取餐 X/N 家 · 已送达 Y/N 单”。N 按当前有效成员计,另外显示原成员总数和已取消数,避免取消一店后进度变化被误解为已取餐。送达进度按子单数计,不按去重后的收货地址数计;同一个收货地址仍逐子单确认送达。进入组详情可看到各店商品、出餐状态、电话、导航、付款方式、现金金额和本店操作按钮。每个已满足条件的子单可独立取餐、送达;骑手自由决定先去哪家。某店已送达时仍可去其他店取餐,没有“全部取齐”门禁,也没有全组取餐、全组送达或全组结算按钮。
+
+| 现有骑手页签 | 组卡出现规则 |
+|---|---|
+| 待抢 `newTask` | 符合开放条件且无人承接的组显示一次 |
+| 待取餐 `toPickup` | 已接组且仍有有效成员尚未取餐,组只在此工作页签显示,允许部分成员已送达;双进度和店铺行展示真实进度 |
+| 配送中 `delivering` | 全部有效成员均已取餐,且仍有未送达/未处理完的履约成员,组只在此工作页签显示 |
+| 已完成 | 所有有效成员履约或异常处理已结束,且至少一单已送达后显示组历史 |
+| 已取消/售后 | 展示涉及的成员及实际处理状态;仍有待处理履约成员的组继续留在对应工作页签 |
+
+同一组只归属一个主流程工作页签,角标按任务组计一次,不按店数或站点数计。示例:三家店已取 2/3、已送达 1/3,仍在待取餐;已取 3/3、已送达 1/3 后进入配送中;全部有效成员送达/结束才进入组历史。A 已送达、B 待取时,组仍在待取餐并占一个任务。分组归类只是展示摘要,不能据此关闭已取子单的送达按钮、要求按店序取餐,或阻止已送一单后继续取另一单。
+
+成员取消后保留该行取消历史、从待操作目标及对应待收现金中移除;剩余成员按原快照继续。已取餐异常未处理完不能仅因售后标记而从工作列表隐藏或释放容量。实际收入和退款不通过列表汇总字段回写。
+
+## 4. 后端和 App 的共同契约
+
+列表必须在服务端按批次/配送组聚合后再分页和计数。不能先对子单分页、再由 App 合并,否则会跨页拆组、重复卡片、角标不一致。普通订单、用户多店批次、骑手配送组使用带类型的唯一展示键,避免不同表 ID 相同导致覆盖;父单号、组 ID 和子单号各保留其职责。
+
+建议返回的只读字段(名称供契约细化,尚未实现):
+
+| 对象 | 字段信息 |
+|---|---|
+| 用户列表项 | 卡片类型、`batchId`、创建时间、批次阶段、履约摘要、退款摘要、成员总数/就绪数、两个截止、金额分项、逐店成员摘要、允许操作 |
+| 骑手任务项 | 任务类型、`groupId`、组版本、有效成员数/已取/已送数、折后配送费合计、到付待代收、各店距离与状态、允许操作 |
+| 成员摘要 | `orderId`、业务单号、店铺展示信息、付款方式、实际支付/到付确认、取送与取消状态、相关金额;按角色限制身份及联系信息 |
+
+列表、详情、角标、通知跳转和接单响应使用同一批次/组关联。组只发一个待抢通知,点击进入组详情;逐单后续取送通知仍按已确认规则处理。接单/取消等操作后返回或刷新最新组,App 不在本地假定其他子单同步成功。
+
+沿用现有单笔订单接口和卡片的兼容规则,新的组合结构要明确 App 接入版本/能力,再确定列表入口,不能让旧 App 将组合卡误当普通单。新增有 JSON body 的业务接口把业务 ID 和操作参数统一放 body;GET 的简单查询/路径参数沿项目现有规则。组接单拟用 `POST /system/multiStoreCheckout/groups/accept`,body 为 `{groupId, version}`,版本仅用于发现卡片过期,服务端仍须在事务锁内重验成员与容量。
+
+## 5. 实施与验收
+
+先确认本方案,再将字段、分页游标、错误及旧 App 兼容写入接口契约,随后实现 T014–T018。App 源码由前端人员接入,本仓库交付前端文档;本次规划不执行 SQL,也不标记页面或接口已完成。
+
+- 普通单、多店批次、闪送混排及同时间/跨页情况,无重复、无漏单、无拆批。
+- 用户部分线上付款、全到付确认、缓冲、取消后退款、某店退款另店配送均能持续找到原批次。
+- 骑手同组待抢只出现一次;两骑手竞争和旧单笔拆抢均不会部分分配。
+- A 已取/B 待取,A 已送/B 待取,部分取消等状态下,一组只在一个主流程工作页签,双进度不被汇总状态覆盖,角标和容量按组计一次。
+- 任意取餐顺序、已取成员先送达可操作,现金不包含线上已付餐费,单店操作不联动修改其他店状态。
+- 未生效/未到预约开放时点不推不抢;越权读取批次/组/成员拒绝,旧 App 与普通单行为有定向回归。
+
+本轮展示建议已按用户提出的闪送参考修订为:用户一批一张卡;骑手一组一张卡、一个主流程工作页签、取餐/送达双进度;用户主阶段与退款筛选可以交叉;骑手待抢距离参考最近有效取餐店。新增展示选择仍为讨论方案,不改变此前已确认的付款、取消、容量与自由取送规则。

+ 29 - 12
specs/036-multi-store-checkout/plan.md

@@ -6,6 +6,10 @@
 
 **阶段**: 用户已要求按 spec-kit 继续实施;已补 data-model、contracts 和 tasks。业务实现中,未完成验收。
 
+2026-10-16 用户要求用户端、骑手端的多店列表一起规划,并参考闪送多点列表。新增 [两端列表与详情联合方案](frontend-display-plan.md):借鉴一张卡、一个主流程工作页签、取送双进度,卡内仍保留逐店付款与履约;覆盖角标/容量、通知跳转和服务端分页边界。撤回草案中同组跨两个工作页签同时展示的建议;新增展示细节尚待讨论,不视为已实现或此前已确认。
+
+2026-10-16 用户已确认项目审查的四项建议,见本文末「项目审查」和 spec.md FR-042~045;纳入本轮实施与验收。其中 037 已实现独立订单无人接单取消,本轮接入 036;此前“无人接单取消后续处理”的说明由本次决定覆盖。业务代码尚未因此完成。
+
 ## 1 核心建议
 
 保留“一次结算父单、每店独立子单、各店独立收款”。父单管本次确认参与集合的准入、生效、超时和取消;配送组管同骑手履约,不能把整份购物车等同于本次结算。用户已澄清:同骑手A/B父批次不包含圈外C,也不等待C付款;普通不合并结算不创建组。
@@ -14,7 +18,7 @@
 
 用户已确认首版纳入**即时平台外送、预约平台外送、到付**;夜市自配送、自取沿用原流程。预约支持在线付款或到付。同一用户、同一地址仍是合并前提;新多店批次不支持线下转账、原单店转账不变已确认(Q13)。堂食暂不纳入仍为方案建议。
 
-2026-10-12用户最新决定:**预约时间处理改造后续单独进行**。不撤销预约多店支持;本輪仅按当前有效规则做兼容和批次准入,不重定义时间语义、不新增最迟接单或预约无人接单自动取消。Q12和FR-014移至后续独立事项,详见3.1;不能据此默认旧预约链路已闭环。
+2026-10-12用户决定预约时间处理改造后续单独进行;2026-10-16 补充确认本轮接入 037 既有无人接单超时规则,并检查尚未生效预约是否已过期。不撤销预约多店支持,不重定义原预约语义或新增倒推最迟接单算法,详见3.1及 FR-042~043;不能把确认当作旧链路或新代码已验证。
 
 用户指出各商家可独立设置支付方式,撤回“同批统一付款方式/渠道”的建议。改为按每家店提供可用方式、用户逐店选择、子单独立保存payType;父批次只汇总,不覆盖子单。LINE/OMG/到付混用及统一生效已确认;新批次过滤转账,不改原单店流程(Q13)。预约时间改造延期见Q12。
 
@@ -69,28 +73,28 @@
 2. **统一提交**:以token确定用户,以真实门店确定商品/归属;校验用户确认的参与集合及资格,用报价版本/幂等号防重。本地事务只写本次成员父子单、收费规则快照和配送组,不另建圈外店单;夹带C或成员不一致明确拒绝,不静默删店,不留下部分可支付单。
 3. **逐单收银确认**:用户按子单进入各店收银台选择方式。线上独立凭证/交易且可信付款成功才就绪;到付由服务端校验用户确认、无渠道扣款且不记实收。未选/失败/未知仍待确认,进度可恢复,不由前端决定就绪。
 4. **批次生效**:各线上子单须在15分钟内由服务端记录并实际发起支付,且在最终确认截止前取得可信付款成功事实;到付须在15分钟内合法确认。全部真实成员合法就绪、未取消且未过最终确认截止时原子生效一次。不等满缓冲,不按创建或默认到付状态开放;即时提交后开放、预约沿原规则。
-5. **整批取消**:未生效用户主动取消立即关闭;用户截止停止新操作,但合法在途支付按缓冲核实,不立即取消未知结果。最终确认截止仍未就绪原子关闭,已实收逐笔落全额退款意图,未实收到付/未选只取消,未知/迟到付款继续对账。确认已无法满足全部就绪时可提前关闭;已生效不再按结算超时取消,预约无人接单另属延期规则。
+5. **整批取消**:未生效用户主动取消立即关闭;用户截止停止新操作,但合法在途支付按缓冲核实,不立即取消未知结果。最终确认截止仍未就绪原子关闭,已实收逐笔落全额退款意图,未实收到付/未选只取消,未知/迟到付款继续对账。确认已无法满足全部就绪时可提前关闭;已生效不再按结算超时取消,无人接单接入037按FR-042处理。
 6. **配送履约**:合并组只出现一次待抢任务;骑手接组后子单共享骑手,其后各店接单/出餐、骑手取餐/送达、账单及通知沿普通子单流程独立处理。取餐顺序由骑手自行决定,不按用户选店顺序强制,不要求组内全部取齐后才能送达某一已取子单,不新增整组送达/结算入口。非合并子单各自进入原抢单流程。
 
 沿用当前普通外送要求:**批次生效且到达预约开放时间后开放抢单,骑手接组成功后商家才接单/出餐**,不是先等各店出餐再让骑手看到,否则会与现有骑手先接单规则互相等待。即时单无预约时间等待;独立取餐/送达与组汇总按已确认Q11处理。用户明确多店目的为配送费优惠,除已确认批次支付/接组/收费规则外,不额外设计新的履约流程;本次独立履约不撤回已有批次就绪/超时取消决定。
 
-预约批次共用15分钟发起/到付确认及快照缓冲,线上既有尝试可在缓冲完成和核实,不等预约当天付款;全部就绪后沿旧时点开放。本轮已批准普通平台配送和新多店预约后续扫描、重启补扫、幂等开放和通知重试,不新增预约语义/最迟接单/自动取消。创建先设置type/delryTime再判旧显示条件,普通预约不套多店期限,夜市自配送/自取不纳入扫描。
+预约批次共用15分钟发起/到付确认及快照缓冲,线上既有尝试可在缓冲完成和核实,不等预约当天付款;全部就绪后沿旧时点开放。本轮已批准普通平台配送和新多店预约后续扫描、重启补扫、幂等开放和通知重试,不新增预约语义或倒推最迟接单算法;037现有规则接入按FR-042。创建先设置type/delryTime再判旧显示条件,普通预约不套多店期限,夜市自配送/自取不纳入扫描。
 
 2026-10-13已确认合并资格:即时单与预约单不能同组;预约单的日期、开始和结束时间必须完全一致才能同组,仅时段重叠、不同日期同钟点均不允许。预结算明确方式/时段不兼容,创建按服务端规范化的真实配送方式/日期/起止时间重验并拒绝不一致成员,不静默改时间、转即时或自动拆组。由于同组由同一骑手承接,不仅凭“都是预约”或时段交集放行。此决定不取消同一时段预约多店支持,也不提前启动下方预约时间改造。
 
 ### 3.1 预约时间处理:后续独立事项
 
-**记录日期:2026-10-12;2026-10-13更新范围。新预约语义/最迟接单及无人接单自动取消:未开始,仍延期;旧时点基本开放扫描、重启恢复、幂等及通知重试已经批准纳入本轮。** 以下新算法建议不代表已批准或实现,基本扫描见7.1。
+**记录日期:2026-10-12;2026-10-16更新范围。** 新预约语义与倒推最迟接单算法仍延期;旧时点基本开放扫描、重启恢复、幂等通知及 037 既有无人接单规则的多店接入已批准纳入本轮,激活前预约过期检查按 FR-043。本节下列历史建议中的“最迟接单/自动截止”只指新的倒推算法,不再排除 FR-042 的既有规则接入,不能视为代码已实现。
 
 1. 用户选择的18:00–18:30拟定义为期望送达时段,不是18:00才开始配送;需要统一前后端文案、时间字段及旧数据兼容,不能直接把历史delryTime重新解释。
 2. 本轮基本扫描复用原有效时间判断及sys_appointorder_handletime,不改变原时点语义;源码无配置默认60分钟,部署值未核实。18:00开始且提前60分钟时17:00开放仅为示例;新多店另须批次生效,普通预约不要求批次状态。新的开放算法后续评估。
 3. 最迟接单拟由预约结束减履约预留时长倒推,预留包含备餐、多店取餐、配送及缓冲,不只用地图行驶时间。首版是否使用保守配置、如何随门店数调整,后续确认。
 4. 到达最迟接单仍未承接的配送组/独立订单拟停止抢单并取消,线上已收原路退款、未实收到付不产生退款。生效后不连带取消已接/已取餐任务;已接超时转异常跟进,不直接自动取消。新多店不支持转账,原单店转账若涉及预约取消需在后续专项另评估,不增加到本轮。
 5. 下单时校验可履约时间和各店备餐/取餐营业时段、预约太近不开放选择等时间算法留待后续;本轮同组预约日期/起止必须完全一致已确认,不再作为延期待确认项。不同独立订单/批次的预约时间与付款衔接后续按范围另评,不擅自要求所有购物车候选统一时段;原单店转账核款与预约衔接如有需要后续另定。
-6. 用户本次已批准旧时点下持久开放扫描、重启补扫、通知幂等/重试及开放与取消/接单竞争,移入7.1及本轮验收,不再延期;新最迟接单/自动取消扫描仍后续。列表与直接接口校验时间资格,不靠App倒计时、不复用TestTask。
-7. UserOrderController在setDelryTime前调用handleIsDisplay,可能把预约当立即单;实施本轮扫描时保证平台配送预约先设置type/delryTime再判旧开放条件,不以错误显示状态掩盖扫描缺失。不重解释历史时段或批量回写历史已开放单;超过预约结束的最迟接单/自动截止改造继续延期。
+6. 用户本次已批准旧时点下持久开放扫描、重启补扫、通知幂等/重试及开放与取消/接单竞争,移入7.1及本轮验收,不再延期;新的倒推最迟接单扫描仍后续,037现有规则接入不延期。列表与直接接口校验时间资格,不靠App倒计时、不复用TestTask。
+7. UserOrderController在setDelryTime前调用handleIsDisplay,可能把预约当立即单;实施本轮扫描时保证平台配送预约先设置type/delryTime再判旧开放条件,不以错误显示状态掩盖扫描缺失。不重解释历史时段或批量回写历史已开放单;倒推最迟接单算法延期,未生效预约过期按FR-043、既有无人接单规则按FR-042。
 
-后续仍从本节确认新预约语义、最迟接单及自动取消;旧时点基本扫描按本次已确认范围在7.1落实。当前只更新方案,不写业务代码、执行SQL、创建或切换分支,不声称扫描或新预约功能已完成。
+后续仍从本节确认新预约语义与倒推最迟接单算法;旧时点基本扫描按本次已确认范围在7.1落实。当前只更新方案,不写业务代码、执行SQL、创建或切换分支,不声称扫描或新预约功能已完成。
 
 ## 4 开放履约字段和并发控制
 
@@ -213,7 +217,7 @@
 
 整批取消。每个已付款子单退**完整实付金额,包含该单实付配送费**;未付款取消,结果未知先补查。退款实际调用使用该子单对应商家凭证/交易,不能只改 payStatus。
 
-统一15分钟是支付发起/到付确认期限,不是催到付提前交现金;默认5分钟可配置缓冲仅允许合法既有线上尝试继续完成付款和核实,不给到付追加确认机会。全到付未确认不无限保留;在途未知不能按未付款抢先取消,最终截止未就绪关闭,真实线上实收原路退,未收款到付不因payStatus=1造退款。已全部合法就绪生效后不再按结算期限取消;预约无人接单截止仍属Q12延期事项。
+统一15分钟是支付发起/到付确认期限,不是催到付提前交现金;默认5分钟可配置缓冲仅允许合法既有线上尝试继续完成付款和核实,不给到付追加确认机会。全到付未确认不无限保留;在途未知不能按未付款抢先取消,最终截止未就绪关闭,真实线上实收原路退,未收款到付不因payStatus=1造退款。已全部合法就绪生效后不再按结算期限取消;无人接单按FR-042接入037,不能用结算期限替代。
 
 支付请求在发起截止前由服务端记录并实际发起,仅代表既有交易可在缓冲继续完成,不代表已经付款或可以开放履约;须在最终确认截止前核实对应真实收款。第15分钟后禁止新的支付发起/重试/方式切换/到付确认,合法既有渠道页面可能在该时点后完成付款,这是用户已接受的口径放宽。最终截止仍不就绪或用户已主动取消则关闭;本地关闭不能保证渠道不再扣款,迟到实收持续对账退款,不重新激活。
 
@@ -283,7 +287,7 @@
 | 审查项 | 实施落点 | 约束与验收 |
 |---|---|---|
 | 4 通知 | LinePayFactService、LinePayOrderNotificationService、OmgPaymentNotifyService、DeliveryOrderNotificationService及新批次到付确认 | 支付事实先保存,全部合法就绪后持久通知事件;预约等旧时点,提交后发送,组/独立单去重及失败重试。用户付款结果与履约通知分开,后续单笔通知仍独立;FR-036/SC-024 |
-| 5 预约开放 | UserOrderController预约初始化、DateUtil旧时间判断、PosOrder查询/更新及新增有效扫描入口 | 普通平台配送/新多店预约旧时点补扫、重启恢复、开放/通知幂等及并发;先设预约字段,新批次额外已生效,普通不套批次期限。禁复用TestTask,不新增最迟接单/自动取消,不回写历史已开放;FR-037/SC-025 |
+| 5 预约开放 | UserOrderController预约初始化、DateUtil旧时间判断、PosOrder查询/更新及新增有效扫描入口 | 普通平台配送/新多店预约旧时点补扫、重启恢复、开放/通知幂等及并发;先设预约字段,新批次额外已生效,普通不套批次期限。禁复用TestTask,不新增倒推最迟接单算法,不回写历史已开放;FR-037/SC-025及FR-042/SC-030 |
 | 6 用户列表 | UserOrderController.orderList/applyTabFilter、UnifiedOrderQueryService、UnifiedOrderTab及批次详情 | 未选/部分付款/已付待生效/缓冲核实可见并恢复合法结算,真实已付与到付分开,不遗漏新批次Apple Pay;只改新批次分类,App只交文档;FR-038/SC-026 |
 | 7 权威算价 | 新多店预结算/创建、OrderPromotionHelper及真实商品/规格/促销/原运费能力 | 不信客户端amount/freight/foodAmount及food价格,服务端查真实价格/归属/数量,计算优惠与折后实付;报价差异拒绝/重报不只警告,金额单位明确,支付/退款/到付/账单同快照;FR-039/SC-027 |
 | 8 优惠券 | 新批次整批/合法子单取消、PromotionUserCouponServiceImpl及Coupon Mapper条件更新 | 只返取消成员券、原有效期不延长、过期不续期;原券/原子单绑定幂等及并发核销,迟到旧取消不释放新单券,返券不等于退款到账;FR-040/SC-028 |
@@ -309,16 +313,16 @@
 | Q9 | 权威算价/快照与兼容 | 已确认创建服务端全量校验及真实商品/规格价格、优惠、原/折后运费和实付计算后固化快照;付款不复查普通菜单/营业变化,仍校验归属/状态/期限/方式/凭证。新批次取消券返还、原有效期和幂等已确认,不新增库存预占;普通单原规则不改,普通预约仅按Q12补扫 |
 | Q10 | 支付工具与最终退款规则是否匹配? | 先沿用现有已支持LINE/OMG信用卡/Apple Pay工具,不新增分期等支付工具。用户普通取消现在只需未接全退,不再以“已接取消保留运费”强制要求部分退款或新增禁用;异常售后若确定部分退款再核对渠道能力。OMG正式退款仍已确认纳入 |
 | Q11 | 骑手什么时候看到配送组,取餐顺序与履约如何定? | 已确认沿原外送:生效且达到预约开放时间后可抢单,接组后各店独立接单/出餐;独立取餐、独立送达,取餐顺序骑手自行决定。单笔结算/通知沿普通订单,不要求全组取齐,不新增整组送达/结算。组状态只汇总混合子单进度,最后有效成员结束才释放1任务;撤回全取齐后整组送达建议 |
-| Q12 | 延期新预约算法与本轮基本扫描 | 即时/预约不同组,预约日期/起止完全一致,合法同段多店保留。本轮已批准普通平台配送/新多店外卖预约旧时点持久扫描、重启补扫、开放幂等及通知重试;新批次额外须生效,普通单不套新期限。新语义/最迟接单/无人接单取消仍后续,不再把基本扫描延期 |
+| Q12 | 延期新预约算法与本轮基本扫描 | 即时/预约不同组,预约日期/起止完全一致,合法同段多店保留。本轮已批准普通平台配送/新多店外卖预约旧时点持久扫描、重启补扫、开放幂等及通知重试;新批次额外须生效,普通单不套新期限。新语义/倒推最迟接单仍后续,037现有规则的多店接入已于2026-10-16确认,基本扫描不延期 |
 | Q13 | 线下转账范围 | 已确认新多店批次不支持转账,原单店/历史订单及商家设置保持不变;各店按LINE/OMG/到付就绪集合选择。仅转账门店提交前明确提示不可参与,可另走原单店;不静默删店/自动拆单/擅自转到付,不新增核款/转账人工退款 |
 
-原业务规则及本次第4~9项均已确认,不重复询问:全部合法就绪后幂等通知、普通平台配送/新多店预约按旧时点补扫、用户列表/继续结算、服务端权威算价、新批次取消券返还、详情/进度/操作归属。仅新预约语义/最迟接单/自动取消继续延期,普通其他异常沿原有效流程。下一步细化data-model/contracts及并发/测试映射供用户审阅,完整技术方案批准前不写执行tasks或业务代码,不把确认当作实现验证。
+原业务规则及本次第4~9项均已确认,不重复询问:全部合法就绪后幂等通知、普通平台配送/新多店预约按旧时点补扫、用户列表/继续结算、服务端权威算价、新批次取消券返还、详情/进度/操作归属。仅新预约语义与倒推最迟接单继续延期,037接入按本次确认实施,其他异常沿原有效流程。下一步细化data-model/contracts及并发/测试映射供用户审阅,完整技术方案批准前不写执行tasks或业务代码,不把确认当作实现验证。
 
 ## 9 实现与验收顺序(范围确认后细化)
 
 1. 确认范围/分组/费用/容量/取消规则;补齐 data-model 和 contracts,由用户审阅。
 2. 完成首店围栏/参与集合报价及确认提交、支付方式过滤、参与店全量预检、权威算价、幂等父子单和服务端新批次标识/状态;验证圈外C不建单/不等待付款、夹带拒绝、转账边界、事务回滚、快照及越权。创建后菜单/普通营业变化不自动取消/重算;保留支付必要校验,回归现有非多店创建/付款/优惠促销/发票/通知等原行为。
-3. 完成收银/支付、15分钟发起/可配置缓冲/实际交易核实及生效;接入现有回调/查询/到付的批次通知闸门、持久幂等通知及普通平台配送/新批次预约旧时点扫描。验证部分付款无履约通知、14:14发起14:17完成合法、14:16新操作拒绝、预约按时开放/重启补扫/失败重试/取消竞争及普通兼容;新语义/最迟接单/自动取消不纳入。
+3. 完成收银/支付、15分钟发起/可配置缓冲/实际交易核实及生效;接入现有回调/查询/到付的批次通知闸门、持久幂等通知及普通平台配送/新批次预约旧时点扫描。验证部分付款无履约通知、14:14发起14:17完成合法、14:16新操作拒绝、预约按时开放/重启补扫/失败重试/取消竞争及普通兼容;新语义/倒推最迟接单不纳入;037接入和激活前预约过期检查按FR-042~043。
 4. 完成未生效整批取消/超时、生效未接单店取消全退、已接用户拒绝及已接未取商家无法供餐取消,接入LINE/OMG退款并补新批次取消成员优惠券释放/返还。验证实收/未知/迟到事实、接组/取餐竞争、重复取消幂等返券、保留原有效期、已过期不续期、旧取消不释放新单用券、其他成员不受影响;测试环境真实退款限制按6节,不新增用户审核。
 5. 完成整组抢单、原字典任务统计按组去重及组任务释放、每组门店上限校验、沿普通订单独立出餐/取餐/送达/结算/通知、折后运费与混合付款现金/账单对齐、售后任务收口及关联信息权限;验证两骑手抢同组、拆抢、跨类型/组并发、任意取餐顺序、部分已送部分待取的混合进度、单笔幂等、组任务释放、到付交付及不重复收款。不实现已撤回子单上限或全组取齐/统一送达/整组结算流程。
 6. 完成用户原列表/统一列表中新批次分类和继续结算、批次/关联详情归属、平台配置、必要PC及App接入文档,再统一业务回归/模块构建。验证未选/已付待生效/缓冲核实/Apple Pay本批子单、其他用户父/子/组ID越权及商家/骑手授权边界,App不改源码;正式退款/真实支付联调另行批准。
@@ -365,3 +369,16 @@ OMG 实现按项目纪律将每个接口的代码、测试源码、规格与 SQL
 - 2026-10-13:用户接受第2项建议,明确放宽为15分钟内发起线上支付/确认到付,服务端已记录并实际发起的线上尝试可在默认5分钟可配置缓冲内完成用户认证、付款及服务端确认;第15分钟后禁新发起/重试/切换/到付确认。同步正文、Q6和验收,撤回严格第15分钟前完成付款及仅后台响应缓冲口径;实收才就绪、最终未就绪取消退款、取消后不重开及非多店兼容不变。仅更新036文档,未改代码/SQL/App、未执行测试、未切换分支或提交推送。
 - 2026-10-13:用户确认审查第4~9项,纳入全部就绪后幂等履约通知、普通平台配送/多店预约旧时点扫描与重启补扫、用户列表/继续结算、服务端权威算价、新批次取消券返还(原有效期/幂等)及详情/进度/操作归属。新增FR-036~041、SC-024~029及7.1映射,基本扫描不再延期;新预约语义/最迟接单/无人接单取消仍后续,其他普通规则不套新批次限制。仅更新036文档,未改代码/SQL/App、未执行测试、未创建/切换分支或提交推送。
 - 未写业务代码、DDL,未运行 Maven、未修改 App,未创建/切换分支、未提交/推送。
+
+## 2026-10-16 项目审查:四项边界已获确认
+
+用户已确认以下四项建议,纳入本轮实施与验收;对应 spec.md FR-042~045、SC-030~033。此前确认的支付、取消、运费和自由取送规则不重开讨论,确认不等于代码已实现。
+
+| 优先级 | 缺口与场景 | 已确认处理 |
+|---|---|---|
+| 高 | 037 当前只实现独立外送单无人接单取消,多店不会自动继承。 | 本轮接入现有阈值;计时基准取批次生效、首次实际开放和预约开始三者最晚,不能从子单先付款开始。未承接组原子取消剩余有效成员,逐交易退款;部分取消不重置,接组与取消互斥。无配送组的独立配送成员沿独立处理,仍以父批次统一生效作为基准。 |
+| 高 | 预约时段在付款/缓冲期间过完,例如 14:00 建批、预约 14:05–14:15、14:18 才核实齐付款。 | 尚未生效批次激活时已到或超过预约结束则整批取消、退真实实收,不自动转即时;恢复扫描补处理,未知/迟到款继续核实退款。原付款两个截止不延长,不新增预约提前量算法;已生效任务不因本检查被取消。 |
+| 中 | 子单改址会破坏同地址配送及收费快照。 | 建批后冻结地址与坐标快照,修改地址簿不改订单;首版不新增多店改址。未生效要改址先整批取消再报价,生效后沿已确认取消权限,不放开已接用户取消;旧单笔改址不能绕过。 |
+| 中 | 最大店数 5 降 3 会使已建五店待接组无法承接。 | 保留实时接组重验;存在有效成员数超出新上限的未结束、未承接组时,拒绝该次下调,含尚未生效的已建组。检查与建批/配置版本并发一致;已接组继续履约,不改收费快照。 |
+
+另列为实施验收、不再另设业务审批:共享的付款/换方式/取消/商家/骑手/预约扫描入口都识别新批次关联,避免旧入口提前履约或拆组;新批次退款编排复用 LINE/OMG 现有退款执行与交易幂等事实,不生成两套可独立执行的重复退款;App 新组合卡的能力兼容、列表分页和角标统一验证,未完成前不开放用户入口。其他已取餐异常仍按已确认的普通有效流程处理,但必须验证该流程能保留组任务直至实际履约/交接结束,不能只改售后状态后释放任务。

+ 23 - 12
specs/036-multi-store-checkout/spec.md

@@ -4,7 +4,9 @@
 
 **Feature Branch**: `codex/036-multi-store-checkout`,从 `test-202609v2` 创建;平台管理 PC 端仓库使用同名分支。
 
-**Status**: Draft,供用户逐轮讨论;业务代码未开始。
+**Status**: 实现中;已提交配置与询价基础,创建批次、支付、退款、骑手配送及两端列表尚未完成验收。新增展示细节继续讨论。
+
+2026-10-16 两端列表/详情展示补充建议见 [frontend-display-plan.md](frontend-display-plan.md)。同日用户确认项目审查的四项建议,作为本轮实施与验收要求:接入 037 多店无人接单取消、激活前预约过期检查、建批后地址冻结、下调上限时保护未接组,见 FR-042~045。新增规则确认不等于代码已实现。
 
 **Input**: 用户提供《多店下单与骑手合并需求变更 (2).docx》,确认各店独立收款、在线批次全部子单付款完成后才开放履约,并要求纳入 OMG 正式退款、预约配送和到付;夜市自配送、自取沿用原流程。先给方案、确认细节后实现,可持续调整。
 
@@ -15,7 +17,7 @@
 - 一次多店结算按店生成独立子订单,款项分别付给对应商家,不改为平台代收。
 - 新批次创建时各子单待收银确认,不预先认定付款方式;线上须服务端确认支付成功,到付须用户选择并由服务端校验确认。全部成员就绪前,商家/骑手不能提前履约。
 - 首版纳入即时配送、预约配送和到付;夜市自配送、自取沿用原流程,不加入本次多店批次规则。
-- 新预约时间语义、最迟接单及无人接单自动取消仍留后续。2026-10-13用户确认本轮补充普通平台配送外卖和新多店外卖预约单的后续开放扫描,沿原有效开放时点,支持重启补扫、幂等开放与通知重试;新批次额外要求已生效,普通预约不套用多店期限。夜市自配送、自取不纳入。后续边界见plan.md「预约时间处理:后续独立事项」。
+- 新预约时间语义与倒推最迟接单算法仍留后续;2026-10-16 已确认本轮接入 037 现有无人接单超时规则,不再将这项接入延期。普通平台配送外卖和新多店预约沿原有效开放时点持久扫描,支持重启补扫、幂等开放与通知重试;新批次额外要求已生效,普通预约不套用多店期限。夜市自配送、自取不纳入。
 - 各商家可独立设置支付方式,多店不要求共同渠道;本功能仅开放各店已可用的LINE Pay、OMG和到付,不擅自改变商家设置。
 - 同批可按店混用LINE Pay、OMG和到付,逐笔收银时选择;即使最终全部到付,也须逐单完成到付确认,不能创建即生效或因旧payStatus=1默认就绪。
 - 全部新批次共用创建起15分钟支付发起/到付确认期限,支付下一店、重试/回页面不延长;支付完成与服务端确认缓冲默认5分钟、平台可配置,创建时固化时长和最终确认截止。第15分钟停止新的支付发起、重试、切换方式及到付确认;截止前服务端已记录并实际发起的线上支付尝试,允许在缓冲期继续完成用户认证、渠道付款和服务端确认。此口径经用户确认,取代严格要求第15分钟前完成付款的旧口径;并非第15分钟后仍可发起新交易。全部真实成员经服务端确认合法就绪立即生效,无需等满缓冲;最终确认截止仍未就绪整批取消,真实实收全退含运费、未收款到付只取消。已取消后迟到实收退款、不重开。
@@ -23,7 +25,7 @@
 - 同骑手资格以用户选择的第一家店为圆心,按门店坐标计算首店到后续各店的直线距离,不按道路路线距离;范围默认1公里、在平台合并配置中可调整,不能在代码写死1公里。圈外店不进入本次合并结算父单/配送组,不创建其子单、不等待其支付、不计入合并折扣或本批次金额;A/B合并不受圈外C付款影响。
 - 即时单与预约单不能进入同一合并配送组;预约单仅预约日期、开始时间和结束时间完全一致时才能同组,不因同用户/地址/围栏而放宽,仅时段重叠也不能合并。不同日期的同一钟点亦不合并;仍支持符合原有效规则的同一预约时段多店,预约时间处理改造仍按既定范围延期。
 - 新多店批次创建时完整校验门店、商品、配送资格及金额,成功后固化商品/价格/折后运费快照;付款不因普通改价、上下架或停止接新单/营业时间变化重新算价、自动取消批次,仍可在15分钟内发起支付/确认到付,既有线上交易可在缓冲内完成。付款继续检查归属、订单/批次未取消未过期、方式及凭证可用;快照不是库存保证,实际不能出餐按此前确认的子单规则处理,不新增库存预占体系。
-- 新批次准入/期限、权威算价快照及取消返券仅用于服务端明确标识的新多店批次,不全局改变普通单/历史单的付款、取消、优惠促销及发票规则。本次明确批准普通平台配送预约按原时点补充后续开放扫描,不引入新预约语义、批次15分钟限制或无人接单取消。夜市自配送、自取及其他旧流程不变,新标识缺失不能误判为未生效批次,共享入口不能全局移除原校验。
+- 新批次准入/期限、权威算价快照及取消返券仅用于服务端明确标识的新多店批次,不全局改变普通单/历史单的付款、取消、优惠促销及发票规则。本次明确批准普通平台配送预约按原时点补充后续开放扫描,不引入新预约语义或批次15分钟限制,普通单保持037现有无人接单规则。夜市自配送、自取及其他旧流程不变,新标识缺失不能误判为未生效批次,共享入口不能全局移除原校验。
 - 圈外店处理建议:预结算明确列出未纳入店及原因,用户确认本次参与集合后再提交;C保留购物车供另行结算,不自动另建订单、不静默丢掉购物车商品。购物车保留方案属于接入建议,App由前端人员实现。
 - 骑手接单数量沿用现有外卖/闪送/总接单数字典:普通独立外卖单算1单,合并配送组整体算1单,不新增骑手实际子单总量上限、相关字典或配置项。同父单的独立配送订单不能合计为1单;闪送原计数与加急独占不变。此前双层容量/子单上限方案已撤回。
 - 接组须在同一骑手锁内检查账号资格、现有任务上限和组内门店上限,再原子分配;部分完成/取消不按子单释放任务名额,组内全部有效子单履约结束才释放组任务。已取餐异常未处理结束时不得仅因进入售后而提前释放组任务。
@@ -137,9 +139,9 @@
 1. 即时/预约、线上/到付均共用创建起15分钟支付发起/到付确认期限,不延长至预约日期;截止前已记录并实际发起的线上尝试可在默认5分钟可配置缓冲内完成及核实,缓冲不开放新的支付发起、重试、方式切换或到付确认。全部就绪生效后等待原预约开放,不再因结算倒计时取消。
 2. 到付子单须用户逐店选择且服务端合法确认,不在创建时默认就绪。所有到付确认完成才统一生效,不在第一条创建或首次确认时提前推送。
 3. 接单、商家处理、列表和通知共同检查批次生效及预约开放条件;仅改 isDisplay 不能防止直接接口提前接单。
-4. 本轮按用户本次确认补充旧时点下普通平台配送/新多店预约后续开放扫描、重启补扫、开放幂等及通知重试;新批次额外检查已生效,普通预约不套用新期限,通知不得提前或重复。基本扫描不再延期,不复用废弃TestTask;新预约语义、最迟接单及无人接单自动取消仍单独留后续。
+4. 本轮补充旧时点下普通平台配送/新多店预约后续开放扫描、重启补扫、开放幂等及通知重试;新批次额外检查已生效,普通预约不套用新期限,通知不得提前或重复。不复用废弃TestTask;新预约语义与倒推最迟接单算法延期,037 现有无人接单规则的多店接入按 FR-042 实现。
 5. 到付取消不产生未实收款项的在线退款;实际线下收款、取餐和售后仍按现行到付流程处理,不把旧 payStatus=1 当作渠道实收证据。
-6. 已生效预约单无人接单的截止和自动取消延期单独处理;本轮不复用“未付齐付款超时”冒充预约到期处理,不声称已有此功能。
+6. 已生效预约批次按 FR-042 接入 037 无人接单取消,未生效预约批次激活前按 FR-043 检查预约是否已过期;两者均不复用“未付齐付款超时”冒充,且不擅自实现新的预约最迟接单算法。
 7. 三店均参与、A选LINE/B选OMG/C选到付时,C须在15分钟内明确合法确认,A/B须在15分钟内由服务端记录并实际发起支付尝试,且在最终截止前完成真实付款核实;最后成员就绪才生效。C仅创建不算就绪,缓冲不放宽C确认期限;超时取消只退真实线上实收。
 
 ### US5 平台规则与付清后售后(P2)
@@ -176,14 +178,14 @@
 - **FR-009** 支持 LINE Pay 与 OMG;OMG 正式退款必须实现且显式区分环境,未经批准不得用正式交易验证。
 - **FR-010** 用户主动取消在未接单阶段按真实交易全额退款含运费,已接单不走用户取消退款;不以旧稿“商品款退、运费保留”默认要求部分退款扩展。异常售后如需部分退款须另确认,任何退款累计不得超实收、部分退款不得标成全额退款。
 - **FR-011** 非适用单店/历史订单及夜市自配送、自取保持原流程;新多店到付和预约属于本功能,标识明确区分适用范围。唯一相关补齐为本次批准的普通平台配送预约按旧时点补扫,不套新批次期限。
-- **FR-012** 按项目规范补注释、四语言、SQL 登记、测试和 App 接入文档;本轮仅讨论规格,不直接实现。
+- **FR-012** 按项目规范补注释、四语言、SQL 登记、测试和 App 接入文档;按实施任务交付,规格确认不代表代码已实现。
 - **FR-013** 创建、选择方式、子单就绪、真实实收、批次生效和预约开放分别表达;到付确认参加结算期限但不算线上实收,未收款取消不产生虚构退款。旧单店到付创建约定不直接应用新批次。
-- **FR-014(后续独立事项)** 新预约送达时段语义、重算开放/最迟接单及无人接单自动取消仍后续独立处理。本轮已确认补充旧开放时点下普通平台配送/新多店外卖预约的持久扫描、重启恢复、幂等开放与通知重试,见FR-037;不能继续将基本扫描列为延期,不复用废弃TestTask。
+- **FR-014(后续独立事项)** 新预约送达时段语义与倒推开放/最迟接单算法留后续;本轮基本开放扫描按 FR-037、多店接入 037 已有无人接单规则按 FR-042,不再延期。激活前预约失效检查按 FR-043,不改原预约语义,不复用废弃 TestTask。
 - **FR-015** 每店独立查询、选择、校验并保存支付方式;批次不要求共同渠道,允许LINE/OMG/到付按店混用,受当前平台/商家/凭证闸门共同约束。只在新批次上下文过滤转账,不改现有单店支付方式查询和商家设置。
 - **FR-016** 新多店预结算、创建及后续换方式拒绝payType=6,原单店和历史转账仍走原流程;本轮不新增核款时限、待核款提醒、人工转账退款或补偿入口。仅转账门店提交前明确拒绝其参与本批,不擅自转到付/自动拆单/静默移除,也不关闭平台全局转账开关。
 - **FR-017** 外卖任务按进行中的配送组去重加未分组独立订单计数,跨类型总任务为外卖任务加闪送任务;合并组整体算1单,不新增实际子单总量限制。不得按父批次去重或仅排除售后状态来释放已取餐、仍待履约/处置的组任务。
 - **FR-018** 复用现有外卖/闪送/总任务字典及合并组最大门店配置。接组只检查外卖任务+1、总任务+1及组门店数;普通外卖增加1任务,闪送保持原计数和加急独占。撤下新子单上限字典、字段、页面管理及相关校验,不把门店上限当作骑手子单总量上限。
-- **FR-019** 现有任务字典缺失/非法/读取异常回退1;合并配置缺失/非法时保守关闭合并报价。预结算/创建检查每组门店上限,接单在骑手锁内使用实时任务容量和门店上限再校验。配置降低不能强制取消骑手已接任务;待接组超出调整后的门店上限时须有明确不可接原因及平台跟进,不改收费快照。
+- **FR-019** 现有任务字典缺失/非法/读取异常回退1;合并配置缺失/非法时保守关闭合并报价。预结算/创建检查每组门店上限,接单在骑手锁内使用实时任务容量和门店上限再校验。配置降低不能强制取消骑手已接任务;存在超出拟设上限的未结束、未承接组时,按 FR-045 拒绝该次下调,不改收费快照。
 - **FR-020** 每店折后实付运费同时作为商家给骑手的配送毛收入基数和现有骑手账单计算基数,不再按原运费向商家索取、不新增折扣补差。线上已收款子单由商家按现行方式给骑手折后运费;到付子单骑手给商家该单总额减折后运费,向用户代收该单总额。佣金和税沿用原规则,不能额外支付重复配送收入;原单店转账结算不在本功能中改写。
 - **FR-021** 混合付款配送组分别列出各店给商家金额、商家给骑手运费、到付待收总额;只合计真实到付有效子单的待收金额,不将线上单加入代收。取消后的金额及已发生线下款项另跟踪,不仅靠组总额展示。
 - **FR-022** 合并报价明确首店锚点、参与店及排除原因,提交校验用户已确认成员且各参与店位于首店圈内。付款进度、批次总额、折扣店数、生效和取消仅作用于该父单成员,圈外C另行结算,不自动创建或等待C付款。
@@ -202,12 +204,17 @@
 - **FR-035** 平台合并配置页面维护支付完成与服务端确认缓冲时长,单位分钟,默认5,保存只接受正整数;缺失/非法/读取异常按5分钟安全回退,不能回退为无限等待。创建快照后不因改配置改变旧批次最终截止。发起资格以服务端持久记录的原支付尝试、实际发起事实及时间为准,不能用前端点击/回跳或事后补写时间证明期限内发起;收款须核实渠道真实交易、金额、币种、商家及签名/查询事实。LINE认证/确认/扣款按实际分阶段流程处理,认证成功不算实收;不再要求证明用户认证/扣款均在第15分钟前完成,不以本地记账时间冒充渠道付款时间。
 
 - **FR-036** 新批次付款事实先落库,逐单成功/到付确认不直接发履约新单通知;全部合法就绪后生效并持久记录开放事件。满足预约条件且提交后发送,合并组按组、独立单按子单幂等,失败可重试,取消终态不复活。用户支付结果通知保持真实事实,后续取餐/送达逐子单沿原流程。
-- **FR-037** 补充普通平台配送外卖及新多店预约的持久开放扫描,沿原时间判断/sys_appointorder_handletime,不新增最迟接单或自动取消。创建先设预约信息再判显示;扫描校验原开放时点、未取消未分配和原付款/履约资格,新批次额外已生效,普通单不检查批次期限。重启数据库补扫,开放状态与通知意图原子幂等并支持重试;直接接单不可绕过。自取/夜市自配送不纳入,不批量改写历史已开放单。
+- **FR-037** 补充普通平台配送外卖及新多店预约的持久开放扫描,沿原时间判断/sys_appointorder_handletime,不新增倒推最迟接单算法;现有无人接单规则的多店接入另按 FR-042。创建先设预约信息再判显示;扫描校验原开放时点、未取消未分配和原付款/履约资格,新批次额外已生效,普通单不检查批次期限。重启数据库补扫,开放状态与通知意图原子幂等并支持重试;直接接单不可绕过。自取/夜市自配送不纳入,不批量改写历史已开放单。
 - **FR-038** 用户原订单列表与统一列表识别新批次:未选、部分付款、全部未就绪或缓冲核实中保留可见进度/继续结算信息,不因payType空值漏单或payStatus=1误标可履约。真实已付与到付确认分开,生效后逐子单普通进度不被覆盖;覆盖本批LINE、OMG信用卡/Apple Pay及到付,旧非多店分类不全局改写,App只交付接入文档。
 - **FR-039** 新多店预结算/创建服务端读取真实门店商品/规格价格、数量与优惠规则,计算餐费、原/折后运费及实付并固化。拒绝跨店商品/规格、非法数量和报价/金额不一致,不能直接保存客户端amount/freight/foodAmount或仅警告放行。明确金额单位与渠道转换,逐店HALF_UP及支付/退款/到付/账单同快照不变,原普通算价不改。
 - **FR-040** 新批次整批或合法子单取消释放/返还对应取消成员占用/核销的券,不返仍履约成员的券。保留原有效期,仍有效恢复可用、过期不续期;原券/原子单绑定及状态参加并发幂等,重复取消/退款/扫描不重复返券,旧取消不得释放已由新单使用的券。创建同一券不能并发重复使用,返券不是渠道退款成功;普通非多店券规则不改。
 - **FR-041** 新批次详情、付款进度、关联订单、支付/取消按token确定用户并校验父/子/组归属及关联,不能仅凭传入ID返回信息或操作;现有getParentOrderDetail涉及新批次不得原样复用无用户过滤查询。商家仅访问授权子单,骑手沿现有待抢/本人承接权限,不放宽其他商家或用户敏感信息。未授权无款项/状态/退款/返券副作用。
 
+- **FR-042(2026-10-16 已确认)** 本轮将新多店接入 037 无人接单超时规则,沿用 `pos_order_auto_cancel` 分钟阈值及原预约开始口径。计时基准取批次统一生效、首次实际开放和预约开始(即时忽略)三者最晚值;单子单先付款不启动计时,部分取消、刷新、重试不重置。未承接配送组超时原子取消全部剩余有效成员,与整组接单互斥;已承接组不自动取消。逐交易退真实实收、到付未收不造退款,旧独立订单保持 037 原规则。没有配送组的独立配送成员沿独立订单方式处理,但生效基准仍不得早于父批次统一生效。
+- **FR-043(2026-10-16 已确认)** 尚未生效的预约批次在激活时若当前时间已到或超过预约结束,拒绝激活并整批取消,真实实收按原交易退款、未知/迟到款继续核查退款;不自动转即时单。恢复扫描补处理这种失效批次。原 15 分钟发起/到付确认及缓冲快照不延长,不新增更严格的预约提前量算法。已生效批次不因预约结束直接取消,仍按履约及 FR-042 处理。
+- **FR-044(2026-10-16 已确认)** 建批后冻结本批所有子单的同一收货地址及坐标快照,后续修改地址簿不影响订单。首版不新增多店改址功能,不能通过普通单笔接口改其中一家地址。未生效要改址先整批取消再重新报价下单;生效后按现有已确认取消权限处理,不放开已接单用户取消。
+- **FR-045(2026-10-16 已确认)** 平台降低最大合并门店数时,若存在有效成员数超出新上限的未结束、未承接配送组(包括尚未生效的已建组),拒绝本次配置保存,提示先处理存量组;无冲突才保存。检查须与建批、配置版本及组状态变化一致,不能并发漏过。已承接组不阻止此配置调整,也不被取消;实时接组重验和费用快照规则保留。
+
 ## Key Entities
 
 - 结算批次:复用OrderParent;成员、创建起15分钟用户操作截止、确认缓冲时长快照/最终确认截止、逐单已就绪/实收及待核实进度、预约信息、收费快照及生效/取消状态。新批次均有用户截止,不设全到付例外;缓冲到期不是已生效预约任务取消时间。
@@ -231,9 +238,9 @@
 - **SC-002** 重试同一提交、付款回调和接单请求不产生重复批次、重复支付核销或分裂骑手归属。
 - **SC-003** 批次收费等于子单收费合计;总运费等于各店独立打折并舍入后的运费之和,不再按总额打折分摊尾差,所有退款累计不超过实收。
 - **SC-004** 服务重启后到期取消和退款可以恢复,失败可追踪且不影响其他子单退款。
-- **SC-005** 普通及非适用历史订单回归覆盖创建、原营业/价格/促销/优惠券/发票、LINE/OMG/到付/转账、取消及履约/通知;新标识为空不被新批次期限/就绪条件拦截或取消,自取/自配送不变。普通平台配送预约仅按SC-025补齐旧时点后续开放,不引入新时间语义或自动取消。
+- **SC-005** 普通及非适用历史订单回归覆盖创建、原营业/价格/促销/优惠券/发票、LINE/OMG/到付/转账、取消及履约/通知;新标识为空不被新批次期限/就绪条件拦截或取消,自取/自配送不变。普通平台配送预约补齐原开放并保持037现有规则,036新增接入只作用于新批次,不重定义预约语义。
 - **SC-006** OMG 正式退款发布前完成批准的小额交易联调;模拟测试通过不能代替真实联调通过。
-- **SC-007** 即时到付、预约到付及预约线上验证批次生效与旧预约开放时点兼容,未实收到付不造退款。本轮包括基本开放扫描/重启恢复,详见SC-025;新预约语义、最迟接单与无人接单自动取消仍留后续,不宣称本轮完成。
+- **SC-007** 即时到付、预约到付及预约线上验证批次生效与旧预约开放时点兼容,未实收到付不造退款。本轮包括基本开放扫描/重启恢复,详见SC-025;新预约语义与倒推最迟接单仍留后续;既有037接入按SC-030实施和验证,不能提前宣称完成。
 - **SC-008** 验证三店/五店合并组均只算1任务、独立单各算1任务、外卖闪送总任务及加急独占,普通单/组/闪送并发不超过原字典任务上限。上限1时两组仅一组成功,上限2且其他条件满足时两个五店组可接,不另按子单合计拒绝;部分完成/取消不提前释放组任务,已取售后继续占用,字典异常回退1任务而非1家店。
 - **SC-009** 餐费100/折后运费32的到付子单应收用户132、给商家100、配送毛收入32;三单均到付合计396/300/96,混合付款只累计到付单待收。用户收费、现金交付、账单运费基数均取同一快照,不能重复收取线上已付款或重复支付配送收入。
 - **SC-010** 新批次对仅转账门店明确提示,对伪造payType=6的创建/换方式请求拒绝;提交前全店检查,不留下部分已创建可支付子单。原单店转账下单、商家核款、现有查询及历史订单回归不受影响,不改变商家配置。
@@ -252,11 +259,15 @@
 - **SC-023** 14:00创建、默认发起/到付确认截止14:15及最终确认截止14:20;14:14由服务端记录并实际发起、14:17真实付款并核实且其余成员合法就绪可生效。14:16新发起/重试/切换方式/确认到付拒绝;仅前端声称14:14已发起、伪造时间、只有请求或认证成功均不能当作实收就绪。最终截止仍未知则取消并持续核查迟到实收退款。验证缓冲配置5改8只影响新批次、非法回退5、回调/查询/扫描竞争、重复核销、LINE分阶段及非多店无新增期限。
 
 - **SC-024** A已付/B未付或未选不推履约新单且不可抢,全部合法就绪即时开放一次、预约未到不推。重复回调/查询/到付不重复事件,事务回滚不发送;失败可重试、取消后不复活,单笔送达通知不等其他单。
-- **SC-025** 旧配置提前60分钟、预约18:00–18:30时17:00前不开放、17:00后原普通合法平台配送预约可开放;新批次未生效仍不开放,随后生效才开放。停机跨时点后补扫,重复扫描不重复开放/生成通知,取消/接单竞争不复活;普通单不套批次15分钟条件,自取/自配送不纳入,新语义/最迟接单/自动取消不视为已实现。
+- **SC-025** 旧配置提前60分钟、预约18:00–18:30时17:00前不开放、17:00后原普通合法平台配送预约可开放;新批次未生效仍不开放,随后生效才开放。停机跨时点后补扫,重复扫描不重复开放/生成通知,取消/接单竞争不复活;普通单不套批次15分钟条件,自取/自配送不纳入;新预约语义/倒推最迟接单不纳入本轮,037接入按SC-030验证。
 - **SC-026** 新批次未选、A已付/B未付、混合到付、Apple Pay未付及缓冲核实中可查进度并恢复合法结算;批次未就绪时已付子单不能误标可履约,到付不标实收,生效后逐单普通进度不被组覆盖;旧非多店分类回归不变。
 - **SC-027** 篡改amount/freight/foodAmount、跨店商品/规格、非法数量不能改变收费;提交报价差异拒绝/重报价而非仅警告。服务端快照与渠道/退款/到付/账单一致,创建后改价仍按旧快照,原单店算价不改。
 - **SC-028** 未生效整批取消返对应券、生效取消C只返C券;重复取消/退款/扫描只返一次,仍有效可用、过期不续期。并发创建同一券不能重复核销,旧取消回调不释放新单所用券;返券不伪造退款成功,普通单券规则不改。
 - **SC-029** 用户A传B父单号/子单ID/组ID或伪造关联/标识,不能看B详情/进度或支付/取消,失败无状态/款项/返券副作用;本人合法查询正常,商家/骑手仅现有授权范围,不因关联组暴露其他敏感数据。
+- **SC-030** A 先付款而 B 未就绪时不启动无人接单计时;整批生效并实际开放后按 037 阈值检查。预约取生效/开放/预约开始的最晚值,部分取消不续时;超时取消与抢组竞争仅一方成功,超时只退各笔实收,不重复退款/返券。普通独立单 037 回归不变。
+- **SC-031** 14:00 建批、预约 14:05–14:15、14:18 才核实齐付款时不得激活或开放,已收款退款;等于预约结束也拒绝,未知款后续核查。预约仍有效的批次正常激活;已生效的履约任务不因时段结束被此检查取消,重启扫描补处理且不复活。
+- **SC-032** 修改/删除地址簿记录不改变已建批地址及坐标;直接请求旧单笔改址入口不能改变任何成员。未生效取消后新报价可使用新地址,已承接组仍拒绝用户取消;逐店同地址及收费快照一致。
+- **SC-033** 存在未接五店组时将最大店数 5 降为 3 保存失败且版本/原配置不变;冲突组处理完后保存成功,已接五店组继续履约。并发建组/取消/接组/配置保存不留下超过新上限而被卡住的未接组,取消成员后的有效店数正确参与检查。
 
 ## 待讨论事项
 

+ 16 - 0
specs/036-multi-store-checkout/tasks.md

@@ -36,6 +36,22 @@
 - [ ] T018 批次详情/进度/继续结算接口、平台退款跟进 PC 页四语言;配置页已在 T002 完成;App 只写 `frontend-app-integration.md`。
 - [ ] T019 定向测试、受影响模块构建及回归普通 LINE/OMG/到付/转账、自取、夜市自配送、预约、促销券/发票;检查 SQL、编码、换行和差异范围,记录正式 OMG 退款未联调限制。
 
+## 2026-10-16 两端列表联合规划(展示细节待确认)
+
+已编写 [frontend-display-plan.md](frontend-display-plan.md) 供讨论,不代表下列实现任务已完成。
+
+- [ ] T020 将用户批次卡与骑手组任务卡、单一工作页签和取送双进度(参考闪送多点)、角标/容量、金额分项和通知跳转收口到 contracts 与 App 文档;先确认展示选择及旧 App 接入策略。
+- [ ] T021 在 T014–T018 中实现服务端按批次/组聚合后分页及计数,验证普通单混排、跨页不拆组、骑手 A 已取/B 待取和部分取消时单页签归类、双进度及组计数;不得依赖 App 对分页子单临时合并。
+- [x] T022 用户已确认项目审查四项建议,更新 spec/plan/data-model/contracts 及对应验收;该项只代表规格收口,业务实现见 T023–T026。
+- [ ] T023 接入 037 多店无人接单取消:统一生效/首次开放时间持久化及 SQL、按组计时/取消与接组互斥、逐交易退款/返券和原独立单回归;部分取消不重置,预约用最晚基准,见 FR-042/SC-030。
+- [ ] T024 激活与恢复扫描检查未生效预约批次已到/超过结束时间,整批取消及真实退款/迟到补偿,不转即时、不取消已生效任务,见 FR-043/SC-031。
+- [ ] T025 建批保存同一收货地址与坐标快照,后续不随地址簿改变;新旧入口拒绝改动已建批单个地址,取消重下仍按既定权限,见 FR-044/SC-032。
+- [ ] T026 配置下调最大店数时保护超限未接组,含未生效组;与建批/取消/接组并发一致,无冲突才保存且不影响已接组和费用快照,见 FR-045/SC-033。
+
 ## 依赖与交付闸门
 
 T001→T002→T003→T005;T004 在 T005 前。T005→T006–T010→T011–T013→T014–T016→T017–T019。未完成持久状态、支付事实、取消/退款和接组防护前不得把配置开关视为可上线;测试数据库迁移由开发者手动执行。最终状态仅按真实验证报告,不把文档或局部代码称作整功能完成。
+
+展示增量依赖:T020 先收口展示与兼容契约,T021 随 T014–T018 实现,结果纳入 T019 验证。新增任务编号不表示可以跳过前面的批次、支付和接组防护。
+
+审查增量依赖:T023 随 T005–T015 的生效/开放/退款和接组边界实施,T024–T025 随 T005/T008–T009,T026 随 T002/T005/T015;四项结果均纳入 T019 统一验收,普通 037 行为保持回归覆盖。

+ 4 - 0
specs/037-order-no-rider-auto-cancel/plan.md

@@ -29,3 +29,7 @@ OMG 正式退款使用支付尝试保存的环境快照和商户 CreditCheckCode
 - `mvn -q -pl ruoyi-admin -am -DskipTests package` 通过。
 - `mvn -q -pl ruoyi-admin -am test` 执行 1057 个测试,只有 `FlashDeliveryV2Test` 的 7 个断言/错误未通过;该文件对应的闪送服务在本任务开始前已有未提交修改,本任务不改动其代码。
 - SQL 仅登记在 `updatesql/sql.md`,没有执行数据库迁移;测试环境 OMG 无真实信用卡退款接口,正式退款仍待正式凭证和网关联调验收。
+
+## 2026-10-16 多店接入范围确认
+
+用户已确认在 036 T023 中接入 037 现有无人接单阈值:以父批次统一生效、组首次实际开放和预约开始的最晚值计时,部分取消不续时,未承接组原子取消剩余有效成员并逐交易退款,与整组接单互斥。无组独立配送成员沿独立方式但不早于父批次生效计时。当前本节仅同步规格,扩展源码/时间字段/SQL 和回归待 036 T023 完成;上面的独立订单验证记录不覆盖此扩展,不改变普通单既有行为。

+ 1 - 1
specs/037-order-no-rider-auto-cancel/spec.md

@@ -42,7 +42,7 @@
 
 **不回填历史**:`effective_at IS NULL` 的存量单不参与本功能,从上线起干净生效(避免任务首跑批量取消历史滞留单;旧滞留单人工处理)。
 
-**多店批次后续接入**:`specs/036-multi-store-checkout` 当前仍是草案。其新批次须以全部有效子单就绪后父批次原子生效的状态及父批次生效时间为准;单个子单先付款不启动整组无人接单倒计时。037 先覆盖现有独立外送单,多店组接入时复核整组接单与取消条件。
+**多店批次接入(2026-10-16 已确认、尚待实现)**:本轮在 036 FR-042/SC-030、T023 中接入现有阈值;全部有效成员就绪后以父批次统一生效、首次实际开放和预约开始三者最晚值计时,单子单先付款不启动倒计时,部分取消不续时。未承接配送组超时原子取消剩余有效成员,与接组互斥、逐交易退真实实收;无组的独立配送成员沿独立方式但不早于批次统一生效计时。现有 037 独立订单实现和验证不代表这段扩展已完成,普通单规则保持回归覆盖。
 
 ### ② 匹配条件(镜像骑手接单 CAS,保证「骑手本可以接但没人接」)
 

+ 2 - 1
specs/037-order-no-rider-auto-cancel/tasks.md

@@ -1,6 +1,6 @@
 # Tasks: 外卖无人接单自动取消与退款
 
-**状态**:已提交;数据库部署与联调待执行。所有 SQL 仅写入 `updatesql/sql.md`,不直接执行。
+**状态**:独立订单实现已提交;数据库部署与联调待执行。2026-10-16 确认的多店扩展见 T007,尚未实现或验证。所有 SQL 仅写入 `updatesql/sql.md`,不直接执行。
 
 - [x] T001 `effective_at` 字段与映射;到付创建、LINE/OMG 实收、线下收款首次生效写点;对应测试源码与 SQL。
 - [x] T002 修复未支付外送单在线支付切换到到付,原子更新并处理并发/迟到付款;对应测试源码和规格更新。
@@ -8,3 +8,4 @@
 - [x] T004 无人接单扫描、预约计时、CAS 取消、LINE 退款/转账待办、日志与通知;对应测试源码、字典和调度 SQL。
 - [x] T005 OMG 正式环境信用卡交易状态查询与自动退款、幂等退款意图、环境隔离和模拟网关测试;测试环境保持待处理,不宣称真实退款成功。
 - [x] T006 统一静态检查、JDK 21 定向测试、模块构建与回归;检查暂存清单并提交中文提交信息。完整回归的闪送失败项与部署联调限制见 `plan.md`。
+- [ ] T007(2026-10-16 已确认)多店扩展在 036 T023 实现和验证:批次生效/实际开放时间、预约最晚基准、未接组原子超时取消及退款、接组竞争、部分取消不续时;既有独立订单 T001–T006 的已提交状态不代表本项完成。