# OMS 全局设计文档 ## 1. 文档目标 本文用于指导 OMS 在当前复刻项目中的整体落地,输出统一的: - 技术架构与分层职责 - 业务模块边界与核心流程 - 数据库设计原则与表模型映射 - DTO、分页、路由、响应、事务等开发约定 - 文档歧义处理策略 优先级遵循 [开发复刻说明](/d:/my/itfx/admin/开发复刻说明.md),业务内容以 [oms表结构与接口设计2026040802.md](/d:/my/itfx/admin/oms表结构与接口设计2026040802.md) 为准。 ## 2. 设计原则 ### 2.1 基本原则 - 新系统沿用 `.NET 8 + Fake 模块化 + 分层架构 + SqlSugar + MySQL` 技术基线。 - 新增代码优先遵循复刻说明中的最高优先级约定:出入参模型、分页列表、出入参组织、路由风格、服务职责。 - 数据库采用软删除模型,保留通用审计字段:`IsDeleted`、`CreateUserId`、`CreateTime`、`UpdateUserId`、`UpdateTime`。 - 实体只用于持久化,不直接作为 API 出参。 - 接口响应体只定义业务 `data` 的值,外层 `code/msg` 由框架统一包装。 ### 2.2 复刻目标 - 面向跨境物流 OMS 场景,覆盖订单、渠道、操作、客户、充值、系统六大业务域。 - 与现有 admin 技术风格保持一致,避免出现第二套分页、第二套路由、第二套 DTO 命名。 - 让后续开发能按“模块 -> DTO -> Repository -> Service -> API”稳定扩展。 ## 3. 技术架构 ### 3.1 目标分层 - `src/OMS.Api` - Web 入口、鉴权、Swagger、异常处理、自动控制器映射、CORS、配置中心接入。 - `src/OMS.Application` - 应用服务、事务边界、业务编排、对外 HTTP/缓存/消息调用、输入输出模型转换。 - `src/OMS.Domain` - 实体、公共枚举、常量、转换器、公共 DTO、仓储接口。 - `src/OMS.Repositories` - `SqlSugar` 访问、分页查询、投影查询、复杂联表、基础设施注册。 ### 3.2 基础设施 - 容器:`Autofac` - 日志:`Serilog` - 配置中心:`Consul` - ORM:`SqlSugar` - 缓存:`FreeRedis` - 消息:`RabbitMQ` - 序列化:`Newtonsoft.Json` ### 3.3 模块装配要求 - API 启动链路保留 `CreateSlimBuilder -> AddConsul -> UseAutofac/Serilog -> AddApplication -> AddServiceDefaults -> Build -> InitializeApplication -> Run`。 - Application 模块保留 AutoMapper 扫描、Options 绑定、Redis 初始化、HostService 注册、预热逻辑、命名 HttpClient。 - Repositories 模块保留 MySQL 连接注册、泛型仓储注册、基础设施 Options 注册。 ## 4. 业务模块划分 ### 4.1 订单域 职责: - 我的订单:列表、详情、支付、预报、拦截、取消拦截、删除、打印、导出 - 我要查价:按目的国、运输方式、重量、货物类型返回价格方案 - 我要下单:模板下载、Excel 导入、任务跟踪 核心表: - `t_order` - `t_order_template` - `t_order_task` - `t_order_sender` - `t_order_recipient` - `t_order_declaration` - `t_order_weight` - `t_order_fee` ### 4.2 渠道域 职责: - 销售产品维护 - 产品卖价配置与发布 - 排货规则配置 - 服务渠道维护 - 渠道买价配置与发布 - 黑名单区 / 偏远分区 / 预警分区 - 计重规则 / 计重进位 - 自动触发规则 - 标签模板设计 核心表: - `t_sales_product` - `t_sales_product_price` - `t_sales_product_price_factor` - `t_sales_product_price_detail` - `t_sales_product_allocation_provider` - `t_sales_product_publish_record` - `t_service_channel_group` - `t_service_channel` - `t_service_channel_price` - `t_service_channel_price_factor` - `t_service_channel_price_detail` - `t_service_channel_publish_record` - `t_kpi_area` - `t_kpi_area_info` - `t_weight_rule` - `t_weight_rule_info` - `t_weight_rounding` - `t_weight_rounding_info` - `t_auto_trigger` - `t_label_template` ### 4.3 操作域 职责: - 入库扫描 - 出库扫描 - 标签打印与打印记录追踪 核心表: - `t_inbound_record` - `t_outbound_record` - `t_label_print_record` ### 4.4 客户域 职责: - 客户主账号管理 - 子账号管理 - 登录凭据与客户分组 - 菜单角色与销售/客服归属 核心表: - `t_customer` - `t_customer_sub_account` ### 4.5 充值域 职责: - 提交充值申请 - 审核充值申请 - 审核通过后更新客户余额 - 查询与导出充值记录 核心表: - `t_recharge_record` ### 4.6 系统域 职责: - 仓库地址维护 - 收件地址与客服信息维护 核心表: - `t_warehouse_address` ## 5. 关键业务流程 ### 5.1 订单生命周期 主路径: 1. 客户创建订单或上传批量下单文件。 2. 系统保存订单主表、收发件人、申报信息、预报重量。 3. 用户发起预报 / 支付 / 拦截等动作。 4. 仓内进行入库、出库、打印操作。 5. 系统补充收货、发货、签收、费用、下游轨迹等信息。 状态建议: - `draft` - `predeclared` - `received` - `pendingPayment` - `pendingShip` - `pendingOnline` - `shipping` - `deliverySuccess` - `deliveryFailed` - `problematic` - `deleted` - `claimed` ### 5.2 价格与规则发布 适用于销售产品和服务渠道两条线: 1. 先保存当前价格项/规则明细配置。 2. 将当前完整配置快照写入发布记录表。 3. 标识版本号、操作类型、发布时间、发布人。 4. 回滚时读取目标版本 `Content` 快照,重新覆盖现行配置。 说明: - 发布记录是历史快照,不参与实时计算。 - 实时生效配置仍以业务主表和子表为准。 ### 5.3 充值审核 1. 客户提交充值申请。 2. 系统生成流水号并写入 `t_recharge_record`,状态为待审核。 3. 管理员审核通过时,更新记录审核状态、审核时间、审核人。 4. 同事务增加客户余额。 5. 审核驳回时仅更新审核状态与备注。 ### 5.4 仓内操作 1. 入库扫描记录重量、尺寸、销售产品、目的国、仓库、操作人。 2. 出库扫描记录运单号、仓库、操作人。 3. 标签打印记录模板、时间、是否成功、操作人。 4. 这些操作应与订单状态推进联动。 ## 6. 数据库设计策略 ### 6.1 命名与类型 - 表名统一使用 `t_` 前缀。 - 字段名使用 PascalCase,与文档和现有项目习惯保持一致。 - 主键统一 `BIGINT AUTO_INCREMENT`。 - 金额、重量统一 `DECIMAL`,禁止 `float/double`。 - 动态结构统一使用 `JSON`,包括: - 价格因素值 - 客户组价格映射 - 发布快照内容 - 标签模板内容 - 仓库微信二维码数组 ### 6.2 逻辑外键与物理索引 本次 `db.sql` 采用“逻辑外键 + 二级索引”策略,不建立物理外键约束,原因如下: - 软删除是主流程,物理外键会增加批量导入、历史回滚、数据修复成本。 - OMS 存在多处循环引用或弱约束关系,不适合强外键。 - 发布记录、模板 JSON、动态因子配置更适合松耦合持久化。 索引设计重点: - 编码、单号、手机号、流水号使用唯一索引。 - 列表检索字段使用组合索引,如客户 + 状态 + 时间、产品 + 状态、渠道 + 状态。 - 子表统一对主表关联字段建索引。 ### 6.3 软删除与审计 - 所有业务表保留 `IsDeleted`,默认 `0`。 - 所有写操作必须写入 `CreateUserId/CreateTime`。 - 更新操作必须维护 `UpdateUserId/UpdateTime`。 - Repository 查询默认追加 `IsDeleted = 0` 过滤。 ### 6.4 表设计中的特殊处理 #### 订单主子表双向字段 源文档中 `t_order` 同时保留了: - `SenderId` - `RecipientId` - `DeclarationId` 同时子表又有: - `t_order_sender.OrderId` - `t_order_recipient.OrderId` - `t_order_declaration.OrderId` 本次数据库保留了这组字段以兼容原规格,但实现层建议: - 以子表 `OrderId` 作为真实关联主键 - `SenderId/RecipientId/DeclarationId` 仅作为兼容性或缓存字段使用 - 服务层避免双向来源不一致 #### 排货规则主表缺失 源文档出现了 `t_sales_product_allocation_rule` 命名,但没有给出实际表结构。结合接口与字段定义,确定: - `Scheme` 存在于 `t_sales_product` - 服务商列表存在于 `t_sales_product_allocation_provider` 因此本次不额外创建 `t_sales_product_allocation_rule`。 ## 7. 应用层设计规范 ### 7.1 DTO 分层 - 写模型放 `Application/Dtos//` - 公共 DTO、分页基类放 `Domain/Dtos/` - 实体不直接作为 API 出参 命名统一: - 新增:`CreateXxxInput` - 修改:`UpdateXxxInput` - 保存:`SaveXxxInput` - 删除:`DeleteXxxInput` - 分页:`XxxPaginatedInput` - 详情:`XxxOutput` - 列表:`XxxListOutput` 或 `XxxPaginatedOutput` ### 7.2 分页统一约定 - 所有分页入参继承 `PagedQueryInput` - 基础字段统一为 `PageIndex`、`PageSize` - 返回值统一为 `PagedResult` - Repository 统一使用 `ToPagedListAsync(input.PageIndex, input.PageSize)` 收口 ### 7.3 路由约定 复刻项目实现时以复刻说明为准: - 路由模式:`/` - 路由使用 PascalCase - 方法名保留 `Async`,路由不带 `Async` 推荐动作: - `PaginatedList` - `GetById` - `GetDropdownList` - `Create` - `Update` - `Delete` - `Save` ### 7.4 服务职责 `ApplicationService` 负责: - 参数校验 - 业务校验 - 事务控制 - DTO 转换 - 调用 Repository / Redis / MQ / 外部 HTTP `Repository` 负责: - 单表/多表查询 - 分页 - 子查询 - 只读投影 禁止事项: - API 层写业务逻辑 - Service 层拼接超长 SQL 查询 - Entity 直接返回前端 ## 8. 接口契约冲突与落地方案 ### 8.1 响应包装冲突 OMS 文档原始示例里存在 `code/msg/data` 包装,但当前项目框架已统一处理,所以在新设计中: - 接口文档只写 `data` 对应的业务结构 - 运行时仍由框架统一封装成功/失败响应 ### 8.2 分页字段命名冲突 OMS 示例使用: - `page` - `pageSize` 复刻说明要求: - `PageIndex` - `PageSize` 落地方案: - 后端内部 DTO 和服务统一使用 `PageIndex/PageSize` - 如果前端已固定发送 `page/pageSize`,通过序列化别名或适配 DTO 兼容,不在核心服务层扩散两套命名 ### 8.3 路由风格冲突 OMS 规格文档展示的是 kebab-case 路径示例,例如: - `/order/list` - `/channel/sales-product/list` 复刻说明要求的是 PascalCase 显式路由,例如: - `Order/PaginatedList` - `SalesProduct/PaginatedList` 落地建议: - 新代码主实现使用复刻说明的 PascalCase 路由 - 如果已有前端必须兼容 kebab-case,则在 API 层增加兼容别名或网关转发,不在服务层维护两套业务实现 ## 9. 推荐服务拆分 建议至少拆分为以下应用服务: - `OrderService` - `OrderPriceCheckService` - `OrderTemplateService` - `OrderTaskService` - `SalesProductService` - `SalesProductPriceService` - `SalesProductAllocationService` - `SalesProductPublishService` - `ServiceChannelService` - `ServiceChannelPriceService` - `ServiceChannelPublishService` - `KpiAreaService` - `WeightRuleService` - `WeightRoundingService` - `AutoTriggerService` - `LabelTemplateService` - `InboundService` - `OutboundService` - `LabelPrintService` - `CustomerService` - `CustomerSubAccountService` - `RechargeService` - `WarehouseAddressService` ## 10. 事务与一致性 以下场景必须显式事务: - 创建订单时同时写主表、地址、申报、件重尺、费用 - 批量导入任务落库与任务结果回写 - 保存价格项时同时覆盖因素与价格明细 - 发布与回滚时版本快照回写 - 充值审核通过并更新余额 统一写法: ```csharp using var ts = TransacationHelper.GetReadCommitted(); // 1. 业务校验 // 2. 主表保存 // 3. 子表保存 // 4. 清缓存 / 发事件 ts.Complete(); ``` ## 11. 安全与运维要求 - 默认全局鉴权开启 - 匿名接口必须显式声明 - 密码字段统一加密存储 - 所有操作写审计日志 - CORS 从配置中心读取 - 代理头开启,保证真实 IP 获取正确 - Swagger 分组按领域组织 ## 12. 交付物说明 本次交付包含: - [db.sql](/d:/my/itfx/admin/db.sql):OMS MySQL 建库建表脚本 - [design.md](/d:/my/itfx/admin/design.md):OMS 全局设计文档 建议下一步按以下顺序继续落地: 1. 先生成 `Domain Entities + Repository Interfaces` 2. 再生成 `Application DTOs + Services` 3. 然后按模块补齐 Repository 实现 4. 最后补控制器映射、权限、缓存、消息与联调