476 lines
12 KiB
Markdown
476 lines
12 KiB
Markdown
# 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/<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`
|
||
- `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. 最后补控制器映射、权限、缓存、消息与联调
|