admin/design.md
zzh bb09a51f4a refactor: 合并 OrderTask 至批量任务,移除 t_order_task 依赖
Excel 导入与任务进度统一走 t_order_batch_job;删除旧实体、仓储与 /order/task/* 接口,上传返回 jobId。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 12:36:57 +08:00

12 KiB
Raw Permalink Blame History

OMS 全局设计文档

1. 文档目标

本文用于指导 OMS 在当前复刻项目中的整体落地,输出统一的:

  • 技术架构与分层职责
  • 业务模块边界与核心流程
  • 数据库设计原则与表模型映射
  • DTO、分页、路由、响应、事务等开发约定
  • 文档歧义处理策略

优先级遵循 开发复刻说明,业务内容以 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_batch_job / t_order_batch_job_item
  • 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/<Domain>/
  • 公共 DTO、分页基类放 Domain/Dtos/
  • 实体不直接作为 API 出参

命名统一:

  • 新增:CreateXxxInput
  • 修改:UpdateXxxInput
  • 保存:SaveXxxInput
  • 删除:DeleteXxxInput
  • 分页:XxxPaginatedInput
  • 详情:XxxOutput
  • 列表:XxxListOutput 或 XxxPaginatedOutput

7.2 分页统一约定

  • 所有分页入参继承 PagedQueryInput
  • 基础字段统一为 PageIndex、PageSize
  • 返回值统一为 PagedResult<T>
  • Repository 统一使用 ToPagedListAsync(input.PageIndex, input.PageSize) 收口

7.3 路由约定

复刻项目实现时以复刻说明为准:

  • 路由模式:<Domain>/<Action>
  • 路由使用 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(含批量任务 OrderService.BatchJob)
  • OrderPriceCheckService
  • OrderTemplateService
  • SalesProductService
  • SalesProductPriceService
  • SalesProductAllocationService
  • SalesProductPublishService
  • ServiceChannelService
  • ServiceChannelPriceService
  • ServiceChannelPublishService
  • KpiAreaService
  • WeightRuleService
  • WeightRoundingService
  • AutoTriggerService
  • LabelTemplateService
  • InboundService
  • OutboundService
  • LabelPrintService
  • CustomerService
  • CustomerSubAccountService
  • RechargeService
  • WarehouseAddressService

10. 事务与一致性

以下场景必须显式事务:

  • 创建订单时同时写主表、地址、申报、件重尺、费用
  • 批量任务落库与子项结果回写(t_order_batch_job / t_order_batch_job_item)
  • 保存价格项时同时覆盖因素与价格明细
  • 发布与回滚时版本快照回写
  • 充值审核通过并更新余额

统一写法:

using var ts = TransacationHelper.GetReadCommitted();

// 1. 业务校验
// 2. 主表保存
// 3. 子表保存
// 4. 清缓存 / 发事件

ts.Complete();

11. 安全与运维要求

  • 默认全局鉴权开启
  • 匿名接口必须显式声明
  • 密码字段统一加密存储
  • 所有操作写审计日志
  • CORS 从配置中心读取
  • 代理头开启,保证真实 IP 获取正确
  • Swagger 分组按领域组织

12. 交付物说明

本次交付包含:

建议下一步按以下顺序继续落地:

  1. 先生成 Domain Entities + Repository Interfaces
  2. 再生成 Application DTOs + Services
  3. 然后按模块补齐 Repository 实现
  4. 最后补控制器映射、权限、缓存、消息与联调