# 订单批量处理与异步队列方案 > **文档定位**:梳理 OMS 后端现有订单批量相关 API、执行模式与可复用资产,并给出统一异步队列改造建议。 > **对照仓库**:`C:\Users\wilso\Desktop\oms0414-back`(`SimpleAdmin.sln`) > **前端对照**:`E:\oms0414\src\views\order\myOrders\index.vue` > **关联文档**:`docs/oms系统设计-050801.md`(订单章)、`docs/rbac系统设计-060801.md`(权限) > **编写日期**:2026-07-07 > **技术决策**:**选用 RabbitMQ** 作为订单批量异步队列方案(v2.0) --- ## 1 导读 ### 1.1 这份文档解决什么问题? 1. **盘点**当前后端所有「批量处理订单」相关 HTTP 接口(含原生批量与前端循环伪批量)。 2. **说明**各接口入参/出参、Service 实现位置、同步/异步执行方式。 3. **指出**现有最接近队列的组件(`t_order_task`、`SmallBagTrackOrderNotifier`)及其局限。 4. **建议**按业务类型划分异步队列、统一批量 Job API 草案与落地优先级。 5. **定义**基于 **RabbitMQ** 的交换机/队列拓扑、消息契约、Consumer 与 Fake 框架集成方式(**已定稿**)。 ### 1.2 技术决策 | 项 | 决策 | | --- | --- | | 消息中间件 | **RabbitMQ** | | .NET 接入 | 优先复用 Fake 生态 **`Fake.RabbitMQ`**(连接池/通道池);订单 Job 使用 **Work Queue 模式** 自建 Publisher/Consumer | | 与 `Fake.EventBus.RabbitMQ` 关系 | 事件总线用于**跨模块集成事件**(如 Job 完成通知);**订单子任务投递不走 EventBus**,走专用 Work Queue | | 状态持久化 | MySQL **`t_order_batch_job` / `t_order_batch_job_item`** 为权威进度;MQ 仅负责调度与重试 | | 宿主部署 | `SimpleAdmin.Api` 进程内注册 Consumer(`IHostedService`);后期可拆独立 Worker 项目 | ### 1.3 现状结论(摘要) | 维度 | 现状 | | --- | --- | | API 暴露 | `OrderService`(partial class)上 `[HttpPost]` / `[HttpGet]`,Fake 动态 API,**无手写 Controller** | | 原生批量 API | 异常件 3 个 + 小包 `batch-create` + Excel 导入 + 条件导出,共 **5 类** | | 伪批量 | My Orders 页 **8 个单票 API**,前端 `for` 循环逐条调用 | | 队列基础设施 | **规划 RabbitMQ**(项目基线已约定 MQ,见 `oms0414-back/开发复刻说明.md`);当前代码**尚未引用** `Fake.RabbitMQ` | | 轻量异步 | `SmallBagTrackOrderNotifier` 使用 `Task.Run`(无持久化、无重试) | | 任务表 | `t_order_task` 记录 Excel 导入进度,但处理仍在 **HTTP 请求内同步完成** | | 权限 | 前端 `Order.MyOrders.*`;**后端 API 未做细粒度 PermissionCode 校验** | --- ## 2 接口总览 ```mermaid flowchart LR subgraph api [SimpleAdmin.Api] HTTP["/order/batch/jobs"] OS[OrderService] end subgraph db [MySQL] JOB[t_order_batch_job] ITEM[t_order_batch_job_item] end subgraph rmq [RabbitMQ] EX["exchange: oms.order.batch"] QD["queue: order.batch.integration"] QA["queue: order.batch.account"] QB["queue: order.batch.state"] QC["queue: order.batch.exception"] QE["queue: order.batch.document"] QF["queue: order.batch.create"] DLX["DLX: oms.order.batch.dlx"] end subgraph consumers [Consumers IHostedService] CD[IntegrationConsumer] CA[AccountConsumer] CB[StateConsumer] CC[ExceptionConsumer] CE[DocumentConsumer] CF[CreateConsumer] end HTTP --> JOB HTTP --> EX EX --> QD & QA & QB & QC & QE & QF QD & QA & QB & QC & QE & QF --> consumers consumers --> ITEM consumers --> OS QD & QA & QB & QC & QE & QF -.失败.-> DLX ``` ### 2.1 分类一览(改造后目标) ```mermaid flowchart TB subgraph native [原生批量 API] EP["/order/mark-problematic
/order/mark-claimed
/order/handle-status/update"] PCB["/order/parcel/batch-create"] UP["/order/upload + task/*"] EX["/order/export"] end subgraph pseudo [伪批量 - 前端循环单票 API] PAY["/order/pay"] PD["/order/pre-declare"] INT["/order/intercept / cancel-intercept"] DEL["/order/delete"] PRT["/order/print"] TRK["/order/track-upsert-small-bag"] DS["/order/downstream-forward-create-one"] end subgraph svc [OrderService 同步处理] OS[OrderService partial] end subgraph async_hint [现有轻量异步] OT[t_order_task 仅记录] STN[SmallBagTrackOrderNotifier Task.Run] end native --> OS pseudo --> OS UP --> OT PCB --> STN ``` ### 2.2 原生批量 API 清单 | 路由 | 方法 | Service 方法 | 文件 | 批量语义 | 上限 | 执行模式 | | --- | --- | --- | --- | --- | --- | --- | | `/order/mark-problematic` | POST | `MarkProblematicAsync` | `OrderService.Exception.cs` | `List OrderIds` | 200 | 同步 foreach,部分成功 | | `/order/mark-claimed` | POST | `MarkClaimedAsync` | 同上 | `List OrderIds` | 200 | 同上 | | `/order/handle-status/update` | POST | `UpdateHandleStatusAsync` | 同上 | `List OrderIds` | 200 | 同上(仅 `processed`) | | `/order/parcel/batch-create` | POST | `BatchCreateParcelAsync` | `OrderService.cs` | `List` | 2000 | 同步 for,逐条明细 | | `/order/upload` | POST | `UploadAsync` → `ImportOrdersAsync` | `OrderService.Helpers.cs` | Excel 多行 | — | 同步逐行 + 写 `OrderTask` | | `/order/task/list` | GET | `GetTaskListAsync` | `OrderService.Helpers.cs` | 查询导入任务 | — | 只读 | | `/order/task/detail` | GET | `GetTaskDetailAsync` | 同上 | 含失败行 | — | 只读 | | `/order/export` | POST | `ExportAsync` | `OrderService.cs` | 筛选条件全量 | — | 同步生成 xlsx | ### 2.3 伪批量 API 清单(单票入参,前端循环) | 路由 | 方法 | Service 方法 | 文件 | 业务特点 | 前端权限码(参考) | | --- | --- | --- | --- | --- | --- | | `/order/pay` | POST | `PayAsync` | `OrderService.cs` | **扣客户余额**,需事务/幂等 | `Order.MyOrders.Pay` | | `/order/pre-declare` | POST | `PreDeclareAsync` | 同上 | 改订单状态 | `Order.MyOrders.PreDeclare` | | `/order/intercept` | POST | `InterceptAsync` | 同上 | `IsIntercept=1` | `Order.MyOrders.Intercept` | | `/order/cancel-intercept` | POST | `CancelInterceptAsync` | 同上 | `IsIntercept=0` | `Order.MyOrders.CancelIntercept` | | `/order/delete` | POST | `DeleteAsync` | 同上 | 软删 + 物理删 | `Order.MyOrders.Delete` | | `/order/print` | POST | `PrintAsync` | `OrderService.Helpers.cs` | 生成打印 HTML | `Order.MyOrders.Print` / `BatchPrint` | | `/order/track-upsert-small-bag` | POST | `TrackUpsertSmallBagAsync` | `OrderService.ParcelBilling.cs` | HTTP 调轨迹服务 | `Order.MyOrders.CreateTrack` | | `/order/downstream-forward-create-one` | POST | `DownstreamForwardCreateOneAsync` | `OrderService.DownstreamForward.cs` | HTTP 调下游 itfx | `Order.MyOrders.ForwardDownstream` | **公共入参** `OrderActionInput`: ```csharp public class OrderActionInput { [Required] public int Id { get; set; } [StringLength(64)] public string? RequestId { get; set; } } ``` **辅助只读**: | 路由 | 方法 | 说明 | | --- | --- | --- | | `/order/downstream-create-one-body` | GET | 预览下游请求体,不实际转发 | ### 2.4 单票编辑类 API(详情抽屉,非列表批量) | 路由 | 方法 | Service 方法 | 文件 | | --- | --- | --- | --- | | `/order/update` | POST | `UpdateOrderDetailAsync` | `OrderService.OrderEdit.cs` | | `/order/weight/update` | POST | `UpdateOrderWeightsAsync` | 同上 | | `/order/fee/recalculate-receivable` | POST | `RecalculateReceivableFeesAsync` | 同上 | | `/order/fee/recalculate-payable` | POST | `RecalculatePayableFeesAsync` | 同上 | | `/order/fee/add` | POST | `AddOrderFeeAsync` | 同上 | | `/order/parcel/create` | POST | `CreateParcelAsync` | `OrderService.cs` / `ParcelBilling.cs` | ### 2.5 非 OrderIds 的「批量数据处理」 | 路由 | 方法 | 说明 | | --- | --- | --- | | `/order/price-check` | POST | 多产品 × 多仓库运费试算,同步嵌套循环 | | `/order/list` | POST | 分页列表 | | `/order/status-counts` | GET | 状态 Tab 计数 | --- ## 3 DTO 与出参模型 ### 3.1 异常件批量(推荐复用为队列 Job 汇总出参) **文件**:`Oms.Application/Dtos/Orders/OrderExceptionDtos.cs` ```csharp // 统一批量出参 public class OrderBatchActionResultOutput { public int SuccessCount { get; set; } public List Failures { get; set; } = []; } public class OrderBatchActionFailureOutput { public int OrderId { get; set; } public string? ServiceNo { get; set; } public string Reason { get; set; } = string.Empty; } // 问题件 public class OrderMarkProblematicInput { public List OrderIds { get; set; } = []; public int? IssueTemplateId { get; set; } public string? IssueType { get; set; } public string? Title { get; set; } public string? Content { get; set; } public string? Remark { get; set; } } // 理赔件 public class OrderMarkClaimedInput { public List OrderIds { get; set; } = []; public string? ClaimType { get; set; } public decimal? ClaimAmount { get; set; } public string? ClaimCurrency { get; set; } public string? ClaimReason { get; set; } public string? Remark { get; set; } } // 标记已处理 public class OrderHandleStatusUpdateInput { public List OrderIds { get; set; } = []; public string? HandleStatus { get; set; } public string? Remark { get; set; } } ``` **内部约束**:`MaxExceptionBatchSize = 200`(`OrderService.Exception.cs`)。 ### 3.2 小包批量创建 **文件**:`Oms.Application/Dtos/Orders/OrderParcelBatchCreateInput.cs` 等 - **入参**:`OrderParcelBatchCreateInput` 继承 `List`,单条结构与 `/order/parcel/create` 一致。 - **出参**:`OrderParcelBatchCreateOutput { BatchNo, SuccessCount, FailCount, Items[] }` - **上限**:`ParcelBatchMaxCount = 2000`(`OrderService.ParcelBilling.cs`) ### 3.3 Excel 导入 | DTO | 字段 | | --- | --- | | `OrderUploadInput` | `File` (IFormFile), `TemplateId` | | `OrderUploadOutput` | `TaskId` | | `OrderTaskListInput` | 分页查询参数 | | `OrderTaskOutput` / `OrderTaskDetailOutput` | 任务汇总 + 失败明细 `FailList` | ### 3.4 条件导出 | DTO | 字段 | | --- | --- | | `OrderExportInput` | `status`, `keyword`, `createTimeStart`, `createTimeEnd` | | `OrderExportOutput` | `downloadUrl`, `expireAt`(24h 过期) | --- ## 4 现有执行模式详解 ### 4.1 异常件批量(已实现部分成功) **调用链**: ``` MarkProblematicAsync / MarkClaimedAsync / UpdateHandleStatusAsync → NormalizeOrderIds(去重、非空、≤200) → ExecuteProblematicBatchAsync / ExecuteExceptionBatchAsync → 逐条 try/catch,成功 SuccessCount++,失败写入 Failures ``` **问题件单条逻辑**:`OrderExceptionWorkflowService.TryMarkProblematicAsync`(`Issues/OrderExceptionWorkflowService.cs`),含通知(`OrderIssueNotificationService`)。 ### 4.2 小包批量创建 ``` BatchCreateParcelAsync → 生成 BatchNo → for each OrderParcelCreateInput → CreateParcelCoreAsync(预报、计费、落库) → 成功则 EnqueueSmallBagTrackUpsertAsync(轨迹) → 返回逐条 Items 明细 ``` ### 4.3 Excel 导入(有任务表,非真异步) ``` UploadAsync → ImportOrdersAsync → Insert OrderTask(Status=processing) → foreach Excel 行 → CreateImportOrderAsync 或记录 OrderTaskFail → 更新 task Quantity / SuccessCount / FailCount / Status=completed → 返回 { taskId } ``` **局限**:整个导入阻塞当前 HTTP 请求;`Status=processing` 仅为记录,无独立 Consumer。 ### 4.4 轨迹轻量异步(现有唯一 fire-and-forget) **文件**:`Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderNotifier.cs` ```csharp public void Enqueue(SmallBagTrackUpsertRequest request) { _ = Task.Run(async () => { using var scope = scopeFactory.CreateScope(); var client = scope.ServiceProvider.GetRequiredService(); await client.UpsertAsync(request); }); } ``` **性质**:单票、内存队列、无持久化、无重试、进程重启即丢失。 ### 4.5 前端伪批量行为 **文件**:`src/views/order/myOrders/index.vue` - 勾选多行后,对 `pay` / `pre-declare` / `intercept` 等 **逐条 POST** `OrderActionInput`。 - 支付等操作:**任一失败即中断**,无部分成功汇总(与异常件 API 不同)。 - 批量打印 / 轨迹 / 下游:循环调用后前端汇总结果弹窗。 --- ## 5 现有基础设施盘点 | 组件 | 是否存在 | 说明 | | --- | --- | --- | | RabbitMQ Work Queue | ❌ 未接入 | **本期建设** | | `Fake.RabbitMQ` | ❌ 未引用 | 连接池/通道池,见 `SPEC.md` §9.3 | | `Fake.EventBus.RabbitMQ` | ❌ 未引用 | 可选,用于 Job 完成等集成事件 | | 订单专用 `IHostedService` | ❌ | 无 | | `BackgroundService` | ✅ 1 个 | 仅 `XhsScheduledPublishWorker`(小红书定时发布) | | `Task.Run` | ✅ | 轨迹 UpsertSmallBag、导出文件清理等 | | `t_order_task` | ✅ | 导入任务记录 + `t_order_task_fail` 失败行 | | `SmallBagTrackOrderNotifier` | ✅ | 内存 fire-and-forget | ### 5.1 OrderTask 实体(可演进为通用批量 Job 表) **表**:`t_order_task` **实体**:`Oms.Domain/OrdersAggregate/Entities/OrderTask.cs` | 字段 | 说明 | | --- | --- | | `TaskName` | 如 `批量下单_yyyyMMddHHmmss` | | `Quantity` | 总条数 | | `SuccessCount` / `FailCount` | 成功/失败计数 | | `Status` | `processing` → `completed` | | `TemplateId` | Excel 模板 Id | | `CustomerId` | 客户归属 | **演进建议**:扩展 `Action`、`PayloadJson`、`StartedAt`、`FinishedAt`,或新建 `t_order_batch_job` 与之并存。 --- ## 6 RabbitMQ 队列分组(与业务 Action 映射) 按 **业务风险 + 耗时 + 外部依赖** 划分 **6 条业务队列** + **1 条死信队列**: | 队列组 | RabbitMQ Queue | Routing Key | 包含 Action | 并发建议 | Prefetch | | --- | --- | --- | --- | --- | --- | | **D. 外部集成** | `oms.order.batch.integration` | `integration.*` | `track-upsert-small-bag`, `downstream-forward-create-one` | 中(限流防打爆下游) | 5 | | **F. 订单创建** | `oms.order.batch.create` | `create.*` | `parcel-create`, `import-row` | 中 | 10 | | **A. 账务** | `oms.order.batch.account` | `account.*` | `pay` | **低**(按 CustomerId 串行) | 1 | | **B. 状态变更** | `oms.order.batch.state` | `state.*` | `pre-declare`, `intercept`, `cancel-intercept`, `delete`, `handle-status-update` | 高 | 20 | | **C. 异常工作流** | `oms.order.batch.exception` | `exception.*` | `mark-problematic`, `mark-claimed` | 中 | 10 | | **E. 文档生成** | `oms.order.batch.document` | `document.*` | `print`, `export` | 低 | 3 | | **死信** | `oms.order.batch.dlx` | — | 超过最大重试的子任务 | — | — | **Exchange**:`oms.order.batch`(类型 **topic**,持久化 `durable=true`)。 ### 6.1 落地顺序建议 1. **D(外部集成)** — 轨迹、下游预报最阻塞 HTTP,且已有 `SmallBagTrackOrderNotifier` 可替换为 Publisher。 2. **F(创建/导入)** — `OrderTask` 表与失败明细已就绪,补 Worker 即可真异步。 3. **A(支付)** — 资金类须严格幂等与对账。 4. **B / C / E** — 按产品优先级迭代。 --- ## 7 统一批量 Job API 草案 ### 7.1 路由设计 | 路由 | 方法 | 说明 | | --- | --- | --- | | `/order/batch/jobs` | POST | 创建批量任务,写 DB 并 Publish 到 RabbitMQ,立即返回 `jobId` | | `/order/batch/jobs/{id}` | GET | 查询进度与汇总结果 | | `/order/batch/jobs/{id}/items` | GET | 逐条明细(成功/失败/进行中) | | `/order/batch/jobs/{id}/cancel` | POST | 取消未执行子任务(可选) | | `/order/batch/jobs/{id}/retry-failed` | POST | 将 failed 子任务重新 Publish(可选) | ### 7.2 入参草案 ```csharp public class OrderBatchJobCreateInput { /// /// pay | pre-declare | intercept | cancel-intercept | delete | /// print | track-upsert-small-bag | downstream-forward-create-one | /// mark-problematic | mark-claimed | handle-status-update | export | ... /// public string Action { get; set; } = string.Empty; public List OrderIds { get; set; } = []; public JsonElement? Payload { get; set; } public string? RequestId { get; set; } } ``` ### 7.3 出参草案 ```csharp public class OrderBatchJobOutput { public long JobId { get; set; } public string Action { get; set; } = string.Empty; public string Status { get; set; } = string.Empty; public int Total { get; set; } public int SuccessCount { get; set; } public int FailCount { get; set; } public DateTime? StartedAt { get; set; } public DateTime? FinishedAt { get; set; } } ``` 单条明细复用 `OrderBatchActionFailureOutput`,扩展 `Status`:`pending` / `running` / `success` / `failed`。 --- ## 8 RabbitMQ 实施方案(已定稿) ### 8.1 为何选 RabbitMQ | 能力 | 说明 | | --- | --- | | 持久化队列 | 进程重启不丢任务(配合 `delivery_mode=2`) | | 死信 + 延迟重试 | 业务失败与系统失败分离治理 | | 多队列隔离 | 支付、外部 HTTP、导入互不阻塞 | | 水平扩展 | 多 API/Worker 实例共享 Consumer | | 与项目基线一致 | `开发复刻说明.md` 已约定 RabbitMQ;Fake 提供 `Fake.RabbitMQ` 连接池 | **不采用 Hangfire / DB 轮询的原因**:订单批量含大量外部 HTTP 与长耗时导入,需要独立队列削峰与跨实例消费;DB 轮询难以优雅做按客户串行与 DLX。 ### 8.2 NuGet 与模块依赖 在 `SimpleAdmin.Api` / `Oms.Application` 增加: ```xml ``` 模块依赖(`OmsApplicationModule` 或新建 `OmsRabbitMqModule`): ```csharp [DependsOn(typeof(FakeRabbitMqModule))] public class OmsRabbitMqModule : FakeModule { } ``` ### 8.3 配置(appsettings / Consul) ```json { "RabbitMQ": { "Connections": { "Default": { "HostName": "rabbitmq", "Port": 5672, "UserName": "oms", "Password": "***", "VirtualHost": "/oms" } } } } ``` 队列声明在应用启动时由 `OrderBatchQueueInitializer`(`IHostedService`)执行:创建 Exchange、6 条业务 Queue、DLX、绑定关系。 ### 8.4 消息契约 **队列消息体** `OrderBatchJobMessage`(JSON,Newtonsoft 驼峰): ```csharp public class OrderBatchJobMessage { public long JobId { get; set; } public long JobItemId { get; set; } public string Action { get; set; } = string.Empty; // pay, delete, track-upsert-small-bag, ... public int OrderId { get; set; } public int? CustomerId { get; set; } // A 组串行键 public string? PayloadJson { get; set; } // Action 专用参数 public int OperatorUserId { get; set; } public string MessageId { get; set; } = string.Empty; // 幂等键 public int RetryCount { get; set; } } ``` **发布流程**: ``` POST /order/batch/jobs → 写 t_order_batch_job + items(status=pending) → 按 Action 映射 routingKey,逐条 Publish 到 oms.order.batch → 立即返回 { jobId } ``` **消费流程**: ``` Consumer 收到消息 → 查 item 是否已成功(幂等跳过) → item.status=running → IOrderBatchActionExecutor.ExecuteAsync(message) → 成功:item.status=success,更新 job 计数 → 业务失败:item.status=failed + reason,ACK → 系统失败:NACK requeue;RetryCount>=3 → DLX → job 全部终态后 status=completed ``` ### 8.5 与现有组件的替换关系 | 现有 | 改造后 | | --- | --- | | `SmallBagTrackOrderNotifier`(`Task.Run`) | Publish 到 `oms.order.batch.integration`,routingKey=`integration.track-upsert` | | `ImportOrdersAsync` 同步 foreach | 上传存文件/OSS → 写 job → 每行一条消息到 `oms.order.batch.create` | | 前端 My Orders 循环 `pay` 等 | 统一 `POST /order/batch/jobs`,轮询 `GET /order/batch/jobs/{id}` | | 异常件 API `mark-problematic` 等 | **兼容期保留同步 API**;新增 `async=true` 或独立 Job API 走 MQ | ### 8.6 重试与死信策略 | 场景 | 策略 | | --- | --- | | 下游 HTTP 超时/5xx | NACK + requeue,指数退避(`x-message-ttl` + DLX 延迟队列,或 Consumer 内 `Task.Delay` 后重发) | | 业务校验失败(已支付、状态不允许) | 记 failed,**ACK 不重试** | | 消息重复消费 | `MessageId` + DB 唯一约束,已 success 则直接 ACK | | DLX 堆积 | 告警 + 管理端「重新投递」接口 | 建议队列参数: ``` x-dead-letter-exchange: oms.order.batch.dlx x-dead-letter-routing-key: dead ``` ### 8.7 部署拓扑 ```mermaid flowchart TB subgraph prod [生产环境] API1[SimpleAdmin.Api 实例 1] API2[SimpleAdmin.Api 实例 2] RMQ[RabbitMQ Cluster] MySQL[(MySQL)] end API1 & API2 -->|Publish/Consume| RMQ API1 & API2 --> MySQL FE[oms0414 前端] -->|创建 Job / 轮询进度| API1 ``` - **第一期**:Consumer 与 API 同进程(`IHostedService`),减少运维复杂度。 - **第二期**:拆 `Oms.OrderWorker` 独立控制台项目,仅引用 `Oms.Application` + Consumers。 ### 8.8 本地开发 `docker-compose` 增加 RabbitMQ 服务(管理台 15672): ```yaml rabbitmq: image: rabbitmq:3.13-management ports: - "5672:5672" - "15672:15672" environment: RABBITMQ_DEFAULT_USER: oms RABBITMQ_DEFAULT_PASS: oms123 RABBITMQ_DEFAULT_VHOST: /oms ``` ### 8.9 Consumer 执行原则 1. **复用现有 Service**:`IOrderBatchActionExecutor` 按 `action` 分发,内部调用抽离后的单条逻辑。 2. **幂等**:`MessageId = {jobId}:{orderId}:{action}`;DB 唯一键 `(JobId, OrderId, Action)`;支付额外校验 `IsPaid`。 3. **部分成功**:业务失败 ACK 并写 `failed`;系统失败 NACK requeue,超次进 DLX。 4. **并发**:A 组 `prefetch=1` + `customerId` 串行;D 组全局限流。 5. **可观测**:日志带 `JobId/OrderId/Action`;可选 `OrderBatchJobCompletedEto` 走 `Fake.EventBus.RabbitMQ`。 --- ## 9 关键文件索引(规划新增) | 文件(规划路径) | 职责 | | --- | --- | | `Oms.Application/Messaging/OrderBatchJobMessage.cs` | MQ 消息契约 | | `Oms.Application/Messaging/IOrderBatchJobPublisher.cs` | Publish 抽象 | | `Oms.Application/Messaging/OrderBatchQueueInitializer.cs` | 启动声明 Exchange/Queue | | `Oms.Application/Workers/OrderBatch/*Consumer.cs` | 6 组 RabbitMQ Consumer | | `Oms.Application/Services/Orders/Batch/IOrderBatchActionExecutor.cs` | Action 执行分发 | | `Oms.Application/Services/Orders/OrderService.cs` | pay/delete/export/batch-create/upload 等主 API | | `Oms.Application/Services/Orders/OrderService.Exception.cs` | 原生 `OrderIds` 批量异常件 API | | `Oms.Application/Services/Orders/OrderService.ParcelBilling.cs` | 小包创建、轨迹同步 | | `Oms.Application/Services/Orders/OrderService.DownstreamForward.cs` | 下游预报转发 | | `Oms.Application/Services/Orders/OrderService.Helpers.cs` | Excel 导入、打印、任务查询 | | `Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderNotifier.cs` | 待替换为 MQ Publisher | | `Oms.Domain/OrdersAggregate/Entities/OrderBatchJob.cs` | Job 实体(规划) | | `src/views/order/myOrders/index.vue` | 前端伪批量循环(待改 Job API) | --- ## 10 与主设计文档的关系 - 订单状态机、费用、模板字段详见 **`docs/oms系统设计-050801.md` 第 4 章**。 - 客户隔离、`CustomerId` 解析见 **OMS 设计 §1.4** 与 **RBAC 设计文档**。 - Fake 框架 RabbitMQ 能力见 **`oms0414-back/SPEC.md` §9.3**(`Fake.RabbitMQ`、`Fake.EventBus.RabbitMQ`)。 --- ## 11 后续工作清单(RabbitMQ 实施) ### 阶段一:基础设施(D 组) - [ ] `docker-compose` / 生产环境部署 RabbitMQ(vhost `/oms`) - [ ] 引用 `Fake.RabbitMQ`,配置 `RabbitMQ:Connections:Default` - [ ] 新建 `OmsRabbitMqModule`、`OrderBatchQueueInitializer` - [ ] 新建 `t_order_batch_job` / `t_order_batch_job_item` 表 - [ ] 实现 `IOrderBatchJobPublisher` + `OrderBatchJobMessage` - [ ] 实现 `IntegrationBatchConsumer`(轨迹、下游预报) - [ ] 替换 `SmallBagTrackOrderNotifier` 为 MQ Publish ### 阶段二:创建与导入(F 组) - [ ] `/order/upload` 改为上传落库 + 按行入队 `oms.order.batch.create` - [ ] `parcel/batch-create` 改为创建 Job 后异步消费 - [ ] 复用/扩展 `OrderTask` 与 `OrderBatchJob` 关系(如需兼容旧前端) ### 阶段三:统一 Job API + 前端 - [ ] 新增 `/order/batch/jobs` 系列 API - [ ] 前端 My Orders 批量操作改 Job API + 进度轮询 - [ ] 实现 B/C/E/A 组 Consumer 与 `IOrderBatchActionExecutor` ### 阶段四:治理与测试 - [ ] DLX 监控告警、`retry-failed` 管理接口 - [ ] 补充 `SimpleAdmin.Api.IntegrationTests`(Publish → Consume → DB 状态) - [ ] 可选:拆 `Oms.OrderWorker` 独立进程 --- *文档版本:v2.0 | 技术决策:RabbitMQ | 2026-07-07*