# Data Model: 闪送订单状态变更消息推送 **Date**: 2026-09-17 | **Spec**: [spec.md](spec.md) 本特性不新增表;2026-09-18 的新单通知追加 `flash_delivery_order.is_display`,作为骑手可见性与预约开放通知资格的同一门闩。 ## 消费的既有实体 ### FlashDeliveryOrder(闪送订单,既有) 推送触发与接收人判定只读以下字段: | 字段 | 类型 | 用途 | |------|------|------| | `orderNo` | String | 推送正文 `,NO:` 后缀与 payload `ddId`(FR-007) | | `userId` | Long | 寄件用户 → ACCEPTED/PICKED_UP/DELIVERED 推送对象 | | `riderId` | Long | 接单骑手 → CANCELLED 推送对象;null 表示未接单,跳过推送 | | `status` | String | 仅用于触发点判定(由状态流转代码自身保证,推送不重复判状态) | | `isDisplay` | Boolean | `is_display`:立即单为 true;预约单创建为 false,进入有效窗口后以条件更新原子切换为 true | | `deliveryMode` / `scheduledPickupStartAt` / `scheduledPickupEndAt` | String / Date | 预约单开放时间窗判定 | | `pickupLongitude` / `pickupLatitude` / `vehicleType` / `deliveryType` | 坐标 / Integer / String | 新单候选骑手的距离、车型及普通/加急互斥筛选 | ### InfoUser(用户,既有) | 字段 | 用途 | |------|------| | `cid` | 设备推送标识;为空时云端推送跳过、消息记录仍生成 | | 语言设置 | 经 `PayPush.*HandleLocal` → `LocaleUtils.getUserLocale` 决定文案语言 | ### push_message(消息记录表,既有,不修改) `PayPush` 通道内 `PushEventService.PublisherEvent(userId, title, content, body)` 落库,即 spec FR-008 的"消息中心记录"。通知服务不直接操作该表。 ## 触发事件矩阵(状态流转 → 推送) | 状态流转 | 触发方法(FlashDeliveryApplicationService) | 通知调用 | 接收人 | content key | |----------|--------------------------------------------|---------|--------|-------------| | WAITING_ACCEPTANCE → ACCEPTED | `accept`(锁内条件更新成功后) | `notifyAccepted(order)` | userId | ...receiving.order | | ACCEPTED → PICKED_UP | `pickup` → `transitionWithProof` | `notifyPickedUp(order)` | userId | ...qspsz.order | | PICKED_UP → DELIVERED | `deliver` → `transitionWithProof` | `notifyDelivered(order)` | userId | ...qsysd.order | | → CANCELLED(用户取消) | `userCancel` | `notifyCancelled(order)`(riderId 非空时) | riderId | order.cancelled | | → CANCELLED(平台取消) | `adminCancel` | `notifyCancelled(order)`(riderId 非空时) | riderId | order.cancelled | | 立即单创建(初始 WAITING_ACCEPTANCE、isDisplay=true) | `create` 提交后 | `notifyAvailable(order)` | 符合条件的在线骑手 | new.flash.order | | 预约单进入窗口(isDisplay false → true) | `FlashDeliveryAvailabilityTask` | `notifyAvailable(order)`(仅条件更新成功时) | 符合条件的在线骑手 | new.flash.order | **明确不触发**(FR-010):预约单创建、加小费(`tipAdd`)、DELIVERED → COMPLETED(`complete` / 自动完成 task)、WAITING_ACCEPTANCE 过期自动取消(`cancelExpiredScheduledOrder`)。 ## 原子开放约束 预约任务只选择 WAITING_ACCEPTANCE、无人接单、SCHEDULED、`is_display=false` 且当前时间位于半开区间 `[start, end)` 的订单。更新语句重复全部条件,并执行 `is_display=true`;影响行数为 1 才获得推送资格。这样列表可见性和通知资格在同一次数据库写入生效,多实例竞争也不会重复推送。 ## 传递给推送通道的 payload 契约 见 [contracts/push.md](contracts/push.md)。