front/oms表结构与接口设计20260430.md
2026-05-05 18:14:43 +08:00

221 KiB
Raw Blame History

oms 表结构与接口设计文档


OMS 系统说明

OMS(Order Management System,订单管理系统)作为独立服务运行和admin权限管理服务合并,面向跨境物流/仓储业务场景,提供订单、渠道、操作、客户四大核心模块,支撑从客户注册、充值、下单、定价、支付到货物入库出库的全流程管理。

核心模块

模块 说明
订单 订单全生命周期管理,包括创建、预报、支付、发货、跟踪等
渠道 销售产品与物流渠道的配置、定价及买价/卖价计算
操作 入库、出库、打印等仓储操作
客户 客户注册、认证、账户余额、额度及权限管理

1.2 表结构设计公共规范

表的字段命名规范

规范 说明 示例
驼峰命名 字段名开头大写+单词驼峰 ServiceProviderId
单数名词 表名用单数,表示实体 customer 而非 customers
业务前缀 表名按业务模块加前缀 t_order、t_customer

必备字段(所有表)

字段名 字段类型 说明
Id BIGINT 主键,自增,步长 1
IsDeleted TINYINT 软删除:0-否,1-是,默认 0
CreateUserId INT 创建人
CreateTime DATETIME 创建时间
UpdateUserId INT 更新人
UpdateTime DATETIME 更新时间

字段命名规范

规范 说明 示例
布尔字段 用 IsXxx 或 HasXxx IsDeleted、IsActive
外键字段 关联表名Id 或 XxxId CustomerId、WarehouseId
时间字段 XxxTime 或 XxxAt CreateTime、PayTime
禁用保留字 不用 desc、range、match 等 用 Description 替代 Desc

数据类型规范

类型 说明
主键 BIGINT,单表自增
金额/重量 DECIMAL,禁止 float/double
字符串 varchar 长度 ≤ 5000,超出用 TEXT
枚举 小数据量用 TINYINT,可读性要求高用 VARCHAR
状态标志 TINYINT

1.3 接口设计公共规范

规范 说明
操作审计必填 任何新增、编辑、删除操作,必须记录操作者与操作时间
新增接口 创建成功后需落库 CreateUserId、CreateTime
编辑接口 更新成功后需落库 UpdateUserId、UpdateTime
删除接口 逻辑删除时需落库 UpdateUserId、UpdateTime,并更新 IsDeleted=1

审计字段中的操作者信息优先从当前登录会话获取,不允许由前端直接信任覆盖。


需求迭代目录(按日期管理)

迭代编号建议使用 YYYYMMDD-序号,按日期倒序维护;不同功能迭代可使用 -01、-02 递增。

迭代日期 迭代编号 迭代功能 变更模块 备注

| 2026-04-30 | 20260430-01 | 统一登录改造:采用独立认证账号表 t_auth_account,通过 PrincipalType + PrincipalId 关联 user/t_customer 主体,统一登录与令牌签发。 | 系统模块 | 无 | | 2026-04-30 | 20260430-02 | 客户权限策略调整:客户登录后固定授予角色 Customer,统一走 RBAC 菜单与权限编码。 | 系统模块 | 无 | | 2026-04-30 | 20260430-03 | 获取渠道分组| 渠道模块 | 之前漏写这个接口了 |

20260427-03 差异明细(按表结构与接口)

对比范围:oms表结构与接口设计20260427.md vs oms表结构与接口设计20260430.md

一、表结构差异

新增表(1)

t_auth_account

//我把rbac的所有表都复制过来了,对比上一个'oms表结构与接口设计20260427.md',其实新增了很多表和接口,但是你可以忽略

更新表(0)

  • 无

删除表(0)

  • 无

二、接口差异

新增接口(1)

  • GET | /channel/service-channel/group/list (获取渠道分组列表)

更新接口(4)

  • POST | /rbac/auth/login(统一认证改造:登录校验由 t_auth_account 承载;type=1 客户登录成功后固定授予 Customer 角色)
  • POST | /rbac/auth/refresh-token(令牌刷新基于统一认证账号 sub 与主体信息 principal_type/principal_id)
  • GET | /rbac/auth/get-current-user(返回当前主体信息时,客户主体固定返回 roles=["Customer"],并按该角色下发权限/菜单)
  • GET | /auth/profile(统一认证入口下新增主体信息聚合逻辑:同时兼容 user/customer,并返回统一 claims 视图)

删除接口(0)

  • 无

二、订单模块

1.1 核心需求说明

  • 我的订单:支持订单全流程管理,包括分页查询、详情查看、支付、预报、拦截/取消拦截、删除、打印、导出;订单状态覆盖草稿→已预报→已收货→待支付→待发货→运输中→派送成功/失败等全生命周期。
  • 我要查价:根据目的国、运输方式、重量尺寸、货物类型等条件查价,返回可选渠道及费用明细;与正式下单共用「选版本 + 内存匹配」计费逻辑,响应宜携带 rulesVersion / priceVersion 便于与订单对齐。
  • 我要下单:支持下载下单模板、上传 Excel 批量下单、查看任务进度与详情;模板分为标准模板与自定义模板。

1.2 表结构设计

命名约定:表名按业务模块加 t_ 前缀;字段名驼峰命名(开头大写+单词驼峰)。

订单表 t_order

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
ServiceNo VARCHAR 64 - 是 运单号
ClientNo VARCHAR 64 - 否 客户单号
TrackNo VARCHAR 64 - 否 跟踪号
ProductCode VARCHAR 128 - 否 产品code
ChannelCode VARCHAR 128 - 否 渠道code
ConsigneeCountry VARCHAR 8 - 否 国家二字码
CargoAttribute VARCHAR 32 - 否 货物属性:general-普货,electronics-3c&带电,sensitive-敏感货
OrderStatus VARCHAR 32 - 是 订单状态
WarehouseId BIGINT - 外键 否 仓库ID
CustomerId BIGINT - 外键 否 客户ID
SenderId BIGINT - 外键 否 发件人ID → t_order_sender
RecipientId BIGINT - 外键 否 收件人ID → t_order_recipient
DeclarationId BIGINT - 外键 否 申报信息ID → t_order_declaration
ReceiveTime DATETIME - - 否 收货时间
ShipTime DATETIME - - 否 发货时间
PayTime DATETIME - - 否 支付时间
SignTime DATETIME - - 否 签收时间
IsCod TINYINT - - 否 是否COD:0-否,1-是
CodCurrency VARCHAR 16 - 否 COD币种
CodSum DECIMAL 18,4 - 否 COD金额
IsIntercept TINYINT - - 否 是否拦截:0-否,1-是
IsRemote TINYINT - - 否 是否偏远:0-否,1-是
PredeclareFailReason VARCHAR 512 - 否 预报失败原因,预报失败时记录具体失败原因,订单状态仍保留 draft
SalesProductRulesVersion VARCHAR 32 - 否 下单绑定的规则版本号(与发布记录 Version 一致,OperatorType=rules)
SalesProductPriceVersion VARCHAR 32 - 否 下单绑定的价格版本号(与发布记录 Version 一致,OperatorType=price)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

OrderStatus 枚举:draft, predeclared, received, pendingPayment, pendingShip, pendingOnline, shipping, deliverySuccess, deliveryFailed, problematic, deleted, claimed

CargoAttribute 枚举:general-普货,electronics-3c&带电,sensitive-敏感货

下单模板表 t_order_template

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
Name VARCHAR 64 - 是 模板名称
Type VARCHAR 16 - 是 standard/custom
TemplateKey VARCHAR 64 - 否 模板标识
CustomerId BIGINT - 外键 否 客户ID(自定义模板)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

下单任务表 t_order_task

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
TaskName VARCHAR 128 - 是 任务名称
Quantity INT - - 否 数量
Status VARCHAR 16 - 是 处理中/已完成/待处理
TemplateId BIGINT - 外键 否 模板ID
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间
CustomerId BIGINT - 外键 否 客户ID

订单发件人表 t_order_sender

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
OrderId BIGINT - 外键 是 订单ID
SenderName VARCHAR 50 - 否 姓名
Company VARCHAR 255 - 否 公司
Country INT - - 否 国家
Province VARCHAR 50 - 否 州省
City VARCHAR 50 - 否 城市
ZipCode VARCHAR 50 - 否 邮编
StreetAddress1 VARCHAR 500 - 否 地址1
StreetAddress2 VARCHAR 500 - 否 地址2
StreetAddress3 VARCHAR 500 - 否 地址3
HouseNumber VARCHAR 50 - 否 门牌号
Phone VARCHAR 50 - 否 手机
TelePhone VARCHAR 50 - 否 电话
Email VARCHAR 60 - 否 邮箱
IsDefault TINYINT - - 否 是否默认:0-否,1-是
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

订单收件人表 t_order_recipient

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
OrderId BIGINT - 外键 是 订单ID
RecipientsName VARCHAR 30 - 否 收件人名称
CompanyName VARCHAR 60 - 否 收件人公司名称
Country INT - - 否 国家
Phone VARCHAR 20 - 否 收件人手机
TelePhone VARCHAR 20 - 否 收件人电话
ZipCode VARCHAR 15 - 否 收件人邮编
Province VARCHAR 25 - 否 收件人省/州
City VARCHAR 25 - 否 收件人城市
StreetNumber VARCHAR 20 - 否 收件人门牌号
StreetAddress1 VARCHAR 255 - 否 收件人地址1
StreetAddress2 VARCHAR 255 - 否 收件人地址2
StreetAddress3 VARCHAR 255 - 否 收件人地址3
Email VARCHAR 60 - 否 收件人邮箱
TaxType INT - - 否 税号类型
TaxNo VARCHAR 35 - 否 税号
CertificateType INT - - 否 证件类型
CertificateNo VARCHAR 30 - 否 证件号码
Eori VARCHAR 255 - 否 EORI
Vat VARCHAR 255 - 否 Vat
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

订单申报信息表 t_order_declaration

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
OrderId BIGINT - 外键 是 订单ID
CnName VARCHAR 500 - 否 品名--中
EnName VARCHAR 500 - 否 品名--英
Sku VARCHAR 255 - 否 SKU
Unit VARCHAR 5 - 否 单位
UnitPrice DECIMAL 10,2 - 否 单价
UnitWeight DECIMAL 11,3 - 否 单重
Quantity INT - - 否 数量
Amount DECIMAL 11,2 - 否 总金额
Weight DECIMAL 11,3 - 否 总重量
HsCode VARCHAR 50 - 否 HsCode
SkuImage VARCHAR 255 - 否 图片
Category VARCHAR 20 - 否 类别
Brand VARCHAR 50 - 否 品牌
BrandType VARCHAR 50 - 否 品牌类型
IsMagnetic BIT - - 否 是否带磁带电
Distribution VARCHAR 255 - 否 配货信息
Material VARCHAR 50 - 否 材质
EnMaterial VARCHAR 64 - 否 英文材质
Purpose VARCHAR 50 - 否 用途
Attributes VARCHAR 50 - 否 属性
OriginCountry VARCHAR 50 - 否 原产国
SalesLink VARCHAR 255 - 否 销售链接
Model VARCHAR 64 - 否 型号
Specifications VARCHAR 50 - 否 规格
Comment VARCHAR 500 - 否 备注
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

订单件重尺表 t_order_weight

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
OrderId BIGINT - 外键 是 订单ID
Type VARCHAR 16 - 是 类型:forecast/receive/ship/downstream
Length DECIMAL 10,2 - 否 长(cm)
Width DECIMAL 10,2 - 否 宽(cm)
Height DECIMAL 10,2 - 否 高(cm)
ActualWeight DECIMAL 10,3 - 否 实重(kg)
VolumetricWeight DECIMAL 10,3 - 否 体积重(kg)
ChargeableWeight DECIMAL 10,3 - 否 计费重(kg)
Cubic DECIMAL 12,6 - 否 立方(m³)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

Type 枚举:forecast(预报)、receive(收货)、ship(发货)、downstream(下游)

订单费用表 t_order_fee(子表,关联 t_order)

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
OrderId BIGINT - 外键 是 订单ID
Type VARCHAR 16 - 是 类型:receivable(应收)/payable(应付)
CostItem VARCHAR 64 - 是 费用项
Amount DECIMAL 18,4 - 是 金额
Currency VARCHAR 16 - 是 币种:RMB/USD/EUR
DownstreamProvider VARCHAR 128 - 否 下游服务商
PriceNo VARCHAR 64 - 否 价格编号(建议写入订单绑定的 SalesProductPriceVersion 或渠道侧价格版本)
PriceEffectiveTime DATETIME - - 否 价格版本生效时间(对应该次计费所用快照的生效时刻)
ChargingStage VARCHAR 16 - 否 本行费用是在哪一阶段计入:forecast(预报)/inbound(入库)/outbound(出库),与卖价/买价项 ChargingTime 一致,便于对账
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

Type 枚举:receivable(应收)、payable(应付)

1.3 下单计费与版本策略(配置 → 运行时 → 下单)

本节约定销售产品维度的规则/卖价如何进入线上算价链路,以及与 t_order 版本字段的对应关系;与渠道模块中「运营发布 → 生成版本」接口衔接。

1.3.1 总体流程

运营新建版本 → 录入/维护规则与卖价 → 发布并设为生效
        ↓
系统组装结构化 JSON(规则快照 + 价格快照,均绑定 salesProductId 与 version)
        ↓
写入 Redis(按产品/版本可寻址)→ 计费服务实例订阅或定时拉取 → 载入本地内存(热数据)
        ↓
用户下单 / 预估(高 QPS)
        ↓
内存匹配:按 bindTime 选定生效版本 → 规则(黑名单/偏远/计重/进位/价格分区等)→ 价格明细 → 输出费用
        ↓
订单落库:固化 SalesProductRulesVersion、SalesProductPriceVersion(必要时可另存发布记录 Id 便于追溯,非本表字段)
        ↓
后台上新发布、调价 → 仅刷新 Redis 与各实例内存中的「当前生效」视图
        ↓
新订单:bindTime 落在 new version 生效之后 → 绑定新版本算价
老订单:已写入的版本号不变 → 复核/对账/理赔仍以当时快照为准,不因后台最新发布而改历史费用

1.3.2 设计要点

要点 说明
版本不可变 订单创建/预报成功时写入 SalesProductRulesVersion、SalesProductPriceVersion,作为该票货的计费契约;非「改单重算」类流程不得静默改写。
生效与历史 同一 salesProductId 在同一时刻仅一条「对外生效」规则+价格组合;历史 version 保留在 Redis(多版本 key) 与 t_sales_product_publish_record,便于审计与回放。
Redis 建议按 salesProductId + version 存完整结构化快照 JSON;可选维护 current 指针 key 指向当前生效 version,便于实例 O(1) 发现最新配置。
本地内存 实例启动或收到变更通知后,将当前需服务的 JSON 反序列化并预热为内存对象(或编译为匹配结构),下单/预估路径禁止主链路同步穿透远程 DB。
下单与预估 /order/parcel/create 与「我要查价」类预估接口共用同一套选版本与匹配逻辑;预估不落库,但响应中建议返回 rulesVersion / priceVersion 便于与正式单对齐展示。
降级 Redis/内存未命中时,允许回退查询 t_sales_product_publish_record(按 bindTime 取当时生效的 rules/price 各一条,读 Content),命中后异步回写 Redis;并打点告警。

1.3.3 与运营侧发布的衔接

  • 运营在 Admin 完成卖价、排货规则等配置后,通过 发布 生成新版本(参见渠道模块 /channel/sales-product/publish 等);发布成功后由配置同步任务将结构化结果写入 Redis 并通知计费服务刷新内存。
  • 「设为生效」与版本号 version、生效时间 effectiveStartAt(或等价字段)应对齐,以便 bindTime 维度解析「当前应绑哪一版」。

1.3.4 版本确认时机 vs 费用计算时机(ChargingTime)

版本(契约):在下单/预报流程中(如 /order/parcel/create 绑定快照时)即确定 SalesProductRulesVersion、SalesProductPriceVersion(及渠道侧与应付相关的版本,若有)。后续只要未发生「改单重算」等显式流程,不得因后台发布新版本而改写订单已绑定版本。
金额(执行):应收、应付各费用项何时真正跑公式、写 t_order_fee,由卖价主表/买价主表上的 ChargingTime(收费时机) 决定,与版本确认时机解耦。

ChargingTime(建议值) 典型触发节点 应收(Type=receivable) 应付(Type=payable)
forecast / 预报 下单预报成功(如 /order/parcel/create 走完全部校验) 仅对本阶段匹配到的卖价项算价并插入 t_order_fee,ChargingStage=forecast 若本单已确定服务渠道且买价项同为「预报」计费,则同步计算应付并落库;否则可延至确定渠道后的同一阶段或后续阶段(实现上需统一规则)
inbound / 入库 仓库收货确认(件重尺可用 receive 类型重算计费重后再计价) 使用订单已绑定的 price 快照,仅处理 ChargingTime=inbound 的卖价项;计费重优先取收货测量 对 ChargingTime=inbound 的买价项,按绑定版本计算应付
outbound / 出库 仓库出库/发货扫描 使用订单已绑定的 price 快照,仅处理 ChargingTime=outbound 的卖价项 对 ChargingTime=outbound 的买价项,按绑定版本计算应付

规则小结

  1. 先锁版本、再分阶段算钱:版本在预报阶段锁定;各阶段只计算「本阶段 ChargingTime 命中的费用项」,避免一次性把所有费用项都算在预报里(除非配置均为预报)。
  2. 后阶段算价仍读旧版本快照:入库、出库触发算价时,仍从 Redis/内存(或降级 DB)加载该订单已绑定 version 对应的价格/规则内容,不使用当前全局「最新发布」。
  3. 计费重数据源:forecast 阶段用预报件重尺;inbound/outbound 若需按实重/复量,应用对应 t_order_weight.Type 数据重算后再匹配价格因子。
  4. 缺省:若配置未填 ChargingTime,实现上按 forecast 处理,与历史「预报即全算」行为兼容。
  5. 快照字段对齐:发布写入价格快照的 priceItems[*].chargingTime 应与主表 ChargingTime 一致;允许存中文(如「预报」「入库」「出库」)或与 DB 相同的英文编码,计费服务应在入口处归一化为 forecast / inbound / outbound 再参与阶段筛选。

1.4 核心接口设计

我的订单

接口名称 请求方式 请求路径 说明
分页查询订单列表 POST /order/list 支持 status、keyword、createTimeStart/End 筛选
订单详情 GET /order/detail 根据订单ID获取详情
支付 POST /order/pay 订单支付
预报 POST /order/pre-declare 订单预报
拦截 POST /order/intercept 订单拦截
取消拦截 POST /order/cancel-intercept 取消订单拦截
删除 POST /order/delete 删除订单
打印 POST /order/print 打印订单
导出 POST /order/export 导出订单
分页查询订单列表(POST /order/list)
1 接口请求示例

请求 /order/list(POST,分页参数放 Body)

{
  "page": 1, // 页码,从1开始
  "pageSize": 20, // 每页条数
  "status": "all|draft|predeclared|received|...", // 订单状态筛选
  "keyword": "", // 关键词(运单号/客户单号/跟踪号)
  "createTimeStart": "", // 创建时间起
  "createTimeEnd": "" // 创建时间止
}

响应(用于 order/myOrders 列表及订单详情抽屉,字段与 parcel/create 对应,创建时传啥返回啥 + weightList)

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
    {
      "id": 1,
      "clientNo": "CUST...",
      "trackNo": "TRK...",
      "serviceNo": "LP...",
      "productCode": "US_AIR",
      "channelCode": "CH001",
      "cargoAttribute": "general",
      "warehouseId": 1,
      "warehouse": "深圳仓",
      "customerId": 1,
      "isCod": false,
      "codCurrency": "",
      "codSum": "",
      "orderStatus": "待支付",
      "status": "pendingPayment",
      "receiveTime": "",
      "shipTime": "",
      "payTime": "",
      "signTime": "",
      "isIntercept": false,
      "isRemote": false,
      "createTime": "2024-01-01 12:00:00",
      "createBy": "",
      "updateTime": "",
      "updateBy": "",
      "sender": {
        "senderName": "发件人",
        "company": "示例公司",
        "phone": "13800138000",
        "telePhone": "",
        "email": "sender@example.com",
        "countryCode": 0,
        "province": "广东省",
        "city": "深圳市",
        "zipCode": "518000",
        "streetAddress1": "示例地址1",
        "streetAddress2": "",
        "streetAddress3": "",
        "houseNumber": ""
      },
      "receiver": {
        "recipientsName": "收件人1",
        "companyName": "",
        "phone": "13800138000",
        "telePhone": "",
        "email": "",
        "countryCode": 0,
        "province": "California",
        "city": "Los Angeles",
        "streetNumber": "",
        "streetAddress1": "123 Main St",
        "streetAddress2": "",
        "streetAddress3": "",
        "zipCode": "90001",
        "taxType": 0,
        "taxNo": "",
        "certificateType": 0,
        "certificateNo": "",
        "eori": "",
        "vat": ""
      },
      "items": [
        {
          "cnName": "示例商品",
          "enName": "Sample Product",
          "sku": "SKU001",
          "unit": "件",
          "unitPrice": 10,
          "unitWeight": 0.5,
          "quantity": 1,
          "amount": 10,
          "weight": 0.5,
          "hsCode": "1234567890",
          "skuImage": "",
          "category": "普货",
          "brand": "示例品牌",
          "brandType": "自有",
          "isMagnetic": false,
          "distribution": "",
          "material": "塑料",
          "enMaterial": "Plastic",
          "purpose": "日用",
          "attributes": "",
          "originCountry": "中国",
          "salesLink": "",
          "model": "",
          "specifications": "",
          "comment": ""
        }
      ],
      "weightList": [
        {
          "type": "forecast",
          "length": "20",
          "width": "15",
          "height": "10",
          "actualWeight": "2.50",
          "volumetricWeight": "2.00",
          "chargeableWeight": "2.50",
          "cubic": "0.003"
        }
      ]
    }
  ],
    "total": 100
  }
}
2 接口业务逻辑

####### 核心流程

####### 状态与失败处理

####### 校验与异常

订单详情(GET /order/detail)
1 接口请求示例

请求 /order/detail(GET,Query 参数)

?id=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "clientNo": "CUST...",
    "trackNo": "TRK...",
    "serviceNo": "LP...",
    "productCode": "US_AIR",
    "channelCode": "CH001",
    "cargoAttribute": "general",
    "warehouseId": 1,
    "warehouse": "深圳仓",
    "customerId": 1,
    "sender": {},
    "receiver": {},
    "items": [],
    "weightList": []
  }
}
2 接口业务逻辑

####### 核心流程

####### 校验与异常

支付(POST /order/pay)
1 接口请求示例

请求 /order/pay(POST)

{
  "id": 1,
  "requestId": ""
}

requestId 幂等,可选。

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
预报(POST /order/pre-declare)
1 接口请求示例

请求 /order/pre-declare(POST)

{
  "id": 1,
  "requestId": ""
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
拦截(POST /order/intercept)
1 接口请求示例

请求 /order/intercept(POST)

{
  "id": 1,
  "requestId": ""
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
取消拦截(POST /order/cancel-intercept)
1 接口请求示例

请求 /order/cancel-intercept(POST)

{
  "id": 1,
  "requestId": ""
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
删除(POST /order/delete)
1 接口请求示例

请求 /order/delete(POST)

{
  "id": 1,
  "requestId": ""
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
打印(POST /order/print)
1 接口请求示例

请求 /order/print(POST)

{
  "id": 1,
  "requestId": ""
}

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "printUrl": ""
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
导出(POST /order/export)
1 接口请求示例

请求 /order/export(POST)

{
  "status": "all|draft|...",
  "keyword": "",
  "createTimeStart": "",
  "createTimeEnd": ""
}

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "downloadUrl": "",
    "expireAt": ""
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。

我要查价

接口名称 请求方式 请求路径 说明
查价 POST /order/price-check 根据目的国、重量尺寸等查价
查价(POST /order/price-check)
1 接口请求示例

请求 /order/price-check(POST)

{
  "destinationCountry": "US", // 目的国二字码
  "shippingMethod": "", // 运输方式
  "cargoWeight": "2", // 货物重量(kg)
  "length": "20", // 长(cm)
  "width": "15", // 宽(cm)
  "height": "10", // 高(cm)
  "cargoType": "普货", // 货物类型
  "destinationProvince": "", // 目的省州
  "postalCode": "" // 邮编
}

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "shippingMethod": "美国空运专线(普货)",
        "warehouse": "一代深圳仓",
        "deliveryTime": "3-7",
        "volumetricWeight": "2",
        "chargeableWeight": "2",
        "costFormula": "(62*2) +5+7",
        "freight": "62",
        "otherFees": "5",
        "totalCost": "136",
        "maxDeliveryDays": 7,
        "totalCostNum": 136
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。

我要下单

接口名称 请求方式 请求路径 说明
模板列表 GET /order/template/list 获取下单模板列表
下载模板 GET /order/template/download 下载 Excel 模板
上传下单 POST /order/upload multipart/form-data,file + templateId
任务进度列表 GET /order/task/list 批量下单任务列表
任务详情 GET /order/task/detail 任务详情
创建小包 POST /order/parcel/create 创建小包订单
批量创建小包 POST /order/parcel/batch-create 批量创建小包订单
创建小包(POST /order/parcel/create)
1 接口请求示例

请求 /order/parcel/create(POST)

字段与 t_order、t_order_sender、t_order_recipient、t_order_declaration、t_order_weight 表对应,采用 camelCase。

{
  "clientNo": "string", // 客户单号 t_order.ClientNo//必填
  "trackNo": "string", // 跟踪号 t_order.TrackNo
  "serviceNo": "string", // 运单号 t_order.ServiceNo
  "productCode": "string", // 产品代码 t_order.ProductCode//必填
  "channelCode": "string", // 渠道代码 t_order.ChannelCode
  "cargoAttribute": "string", // 货物属性 t_order.CargoAttribute:general-普货,electronics-3c&带电,sensitive-敏感货//必填
  "warehouseId": 0, // 仓库ID t_order.WarehouseId//必填
  "length": 3, // 长(cm) t_order_weight.Length
  "width": 3, // 宽(cm) t_order_weight.Width
  "height": 3, // 高(cm) t_order_weight.Height
  "actualWeight": 3, // 实重(kg) t_order_weight.ActualWeight//必填
  "isCod": false, // 是否COD
  "codSum": "string", // COD金额
  "codCurrency": "string", // COD币种
  "declaredCurrency": "string", // 申报币种//必填
  "declaredSum": "string", // 申报总金额
  "quantity": "string", // 包裹数量//必填
  "receiver": { // 收件人 t_order_recipient
    "recipientsName": "string", // 收件人名称//必填
    "companyName": "string", // 收件人公司名称
    "phone": "string", // 收件人手机//必填
    "telePhone": "string", // 收件人电话
    "email": "string", // 收件人邮箱
    "countryCode": 0, // 国家//必填
    "province": "string", // 收件人省/州
    "city": "string", // 收件人城市
    "streetNumber": "string", // 收件人门牌号
    "streetAddress1": "string", // 收件人地址1//必填
    "streetAddress2": "string", // 收件人地址2
    "streetAddress3": "string", // 收件人地址3
    "zipCode": "string", // 收件人邮编//必填
    "taxType": 0, // 税号类型
    "taxNo": "string", // 税号
    "certificateType": 0, // 证件类型
    "certificateNo": "string", // 证件号码
    "eori": "string", // EORI
    "vat": "string" // Vat
  },
  "sender": { // 发件人 t_order_sender
    "senderName": "string", // 发件人姓名
    "company": "string", // 发件人公司
    "phone": "string", // 发件人手机
    "telePhone": "string", // 发件人电话
    "email": "string", // 发件人邮箱
    "countryCode": 0, // 国家
    "province": "string", // 州省
    "city": "string", // 城市
    "zipCode": "string", // 邮编
    "streetAddress1": "string", // 地址1
    "streetAddress2": "string", // 地址2
    "streetAddress3": "string", // 地址3
    "houseNumber": "string" // 门牌号
  },
  "items": [ // 申报明细 t_order_declaration
    {
      "cnName": "string", // 品名-中
      "enName": "string", // 品名-英//必填
      "sku": "string", // SKU
      "unit": "string", // 单位
      "unitPrice": 0, // 单价//必填
      "unitWeight": 0, // 单重//必填
      "quantity": 0, // 数量//必填
      "amount": 0, // 总金额
      "weight": 0, // 总重量
      "imHsCode": "string", // 进口HsCode
      "exHsCode": "string", // 出口HsCode
      "skuImage": "string", // 图片
      "category": "string", // 类别
      "brand": "string", // 品牌
      "brandType": "string", // 品牌类型
      "isMagnetic": false, // 是否带磁带电
      "distribution": "string", // 配货信息
      "material": "string", // 材质
      "enMaterial": "string", // 英文材质
      "purpose": "string", // 用途
      "attributes": "string", // 属性
      "originCountry": "string", // 原产国
      "salesLink": "string", // 销售链接
      "model": "string", // 型号
      "specifications": "string", // 规格
      "comment": "string" // 备注
    }
  ]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "clientNo": "",
    "serviceNo": "",
    "trackNo": "",
    "labelUrl": ""
  }
}

幂等时可选传 requestId。

2 接口业务逻辑

####### 核心流程

  • 本接口用于创建小包订单预报数据,执行顺序固定为:参数校验 -> 创建订单草稿 -> 包裹限制校验 -> 计费重计算 -> 仅「预报」时机费用计算与落库 -> 更新订单状态 -> 返回结果。(入库/出库时机费用见 §1.3.4,由仓储收货、出库流程触发。)
  • 参数校验失败时,不创建任何订单数据,直接返回参数错误。
  • 进入草稿创建后,先将订单主数据、发件人、收件人、申报明细、预报件重尺数据落库,订单状态固定写入 draft。
  • 后续黑名单、偏远、计费重、费用等流程全部基于已创建的草稿订单继续处理;如任一业务环节失败,订单状态不扩展新枚举,统一保留 draft,并在 t_order.PredeclareFailReason 记录失败原因。

####### 详细业务逻辑

  1. 参数解析与基础数据校验

    • 校验请求体必填字段:productCode、warehouseId、customerId、length、width、height、actualWeight、receiver.recipientsName、receiver.countryCode、receiver.zipCode、sender.senderName、items。
    • 校验数值合法性:length/width/height/actualWeight 必须大于 0。
    • 校验枚举合法性:cargoAttribute 仅允许 general、electronics、sensitive。
    • 查询 t_customer,条件:Id = customerId and IsDeleted = 0,返回字段:Id、Status、CustomerGroup、CustomerCode、CustomerName;客户不存在或状态不可用时返回错误。
    • 查询 t_warehouse_address,条件:Id = warehouseId and IsDeleted = 0,返回字段:Id、WarehouseName;仓库不存在时返回错误。
    • 查询 t_country,仅校验收件人国家,条件:Id = receiver.countryCode and IsDeleted = 0,返回字段:Id、CountryCode、ChineseName、EnglishName;国家不存在时返回错误。
  2. 创建订单草稿

    • 插入 t_order:
      • 写入字段:ServiceNo、ClientNo、TrackNo、ProductCode、ChannelCode、ConsigneeCountry、CargoAttribute、OrderStatus、WarehouseId、CustomerId、IsCod、CodCurrency、CodSum、IsIntercept、IsRemote、PredeclareFailReason、审计字段。
      • 处理规则:
        • OrderStatus 固定写 draft
        • ConsigneeCountry 取收件国家对应的 t_country.CountryCode
        • IsIntercept 初始写 0
        • IsRemote 初始写 0
        • PredeclareFailReason 初始写空
    • 插入 t_order_sender:
      • 条件:使用新生成的 OrderId
      • 写入字段:OrderId、SenderName、Company、Country、Province、City、ZipCode、StreetAddress1、StreetAddress2、StreetAddress3、HouseNumber、Phone、TelePhone、Email
    • 插入 t_order_recipient:
      • 写入字段:OrderId、RecipientsName、CompanyName、Country、Phone、TelePhone、ZipCode、Province、City、StreetNumber、StreetAddress1、StreetAddress2、StreetAddress3、Email、TaxType、TaxNo、CertificateType、CertificateNo、Eori、Vat
    • 插入 t_order_declaration:
      • 对 items 数组逐条入库
      • 写入字段:OrderId、CnName、EnName、Sku、Unit、UnitPrice、UnitWeight、Quantity、Amount、Weight、HsCode、SkuImage、Category、Brand、BrandType、IsMagnetic、Distribution、Material、EnMaterial、Purpose、Attributes、OriginCountry、SalesLink、Model、Specifications、Comment
    • 插入 t_order_weight:
      • 写入一条 Type = forecast 的预报件重尺记录
      • 写入字段:OrderId、Type、Length、Width、Height、ActualWeight、VolumetricWeight、ChargeableWeight、Cubic
      • 初始规则:
        • ActualWeight 取请求值
        • VolumetricWeight、ChargeableWeight 可先写请求值或 0,后续按规则重新计算并覆盖
        • Cubic = Length * Width * Height / 1000000
  3. 查询销售产品配置(用于定位发布记录)

    • 查询 t_sales_product,条件:ProductCode = productCode and IsDeleted = 0 and IsActive = 1
    • 返回字段:Id、ProductCode、ProductName
    • 如不存在,更新 t_order.PredeclareFailReason = '销售产品不存在或未启用',订单状态保持 draft,返回失败。
  4. 绑定销售产品计费快照(强关联:以创建订单当刻绑定的价格与规则为准;运行时优先 Redis + 本地内存)

    • 绑定时点:以订单创建时间 t_order.CreateTime(或本次请求处理时间)作为 bindTime。
    • 主路径(推荐):按 salesProductId = t_sales_product.Id 与 bindTime,从 Redis / 计费服务本地内存 解析「当前应对外生效」的 规则快照 与 价格快照(结构化 JSON,与运营发布组装的版本一致),得到:
      • rulesSnapshot:含 version、effectiveStartAt(或等价字段)、content
      • priceSnapshot:含 version、effectiveStartAt、content
    • 降级路径:当 Redis/内存未命中或版本指针异常时,从 t_sales_product_publish_record 读取:
      • 规则:条件 SalesProductId = t_sales_product.Id and OperatorType = 'rules' and Status = '生效' and PublishTime <= bindTime,按 PublishTime desc 取 1 条,Content 即规则快照正文(与下文 rulesSnapshot.content 同构)。
      • 价格:条件 OperatorType = 'price',其余同上,Content 即价格快照正文。
      • 命中后应异步回写 Redis,并打点监控。
    • 绑定写入 t_order(强关联字段,新单新价、老单不改):
      • SalesProductRulesVersion = rulesSnapshot.version(与发布记录 Version 一致)
      • SalesProductPriceVersion = priceSnapshot.version
    • 绑定失败处理:
      • 若未找到 rulesSnapshot:更新 t_order.PredeclareFailReason = '未命中规则快照版本(内存/Redis/DB)',订单状态保持 draft,返回失败。
      • 若未找到 priceSnapshot:更新 t_order.PredeclareFailReason = '未命中价格快照版本(内存/Redis/DB)',订单状态保持 draft,返回失败。
    • 性能要求:
      • 下单/预估主链路应在进程内内存完成快照读取与匹配;降级读 DB 仅作兜底,应限流并尽快恢复 Redis。
  5. 黑名单校验(拦截型,来自已绑定的 rules 快照 content)

    • 读取 rulesSnapshot.content.areas.blacklist.rules(国家/省市/邮编区间规则集合)。
    • 匹配规则:
      • 国家必须匹配 t_order.ConsigneeCountry
      • 若规则配置了省/市,则订单收件省/市也必须匹配
      • 邮编落在任一 postcodeRanges.left ~ postcodeRanges.right 区间内即视为命中
    • 命中处理:
      • 更新 t_order.PredeclareFailReason = '收件地址命中黑名单区域'
      • t_order.OrderStatus 保持 draft
      • 返回失败结果,不进入后续费用计算。
  6. 偏远区域校验(标记型,来自已绑定的 rules 快照)

    • 读取 rulesSnapshot.content.areas.remote.rules(国家/省市/邮编区间规则集合)。
    • 匹配规则与黑名单一致。
    • 命中则更新 t_order.IsRemote = 1;未命中则更新 t_order.IsRemote = 0
    • 偏远校验不拦截订单,只影响后续费用匹配。
  7. 计费重计算(来自已绑定的 rules 快照)

    • 计费重只基于 t_order_weight 中 Type = forecast 的件重尺数据计算
    • 查询 t_order_weight,条件:OrderId = 当前订单ID and Type = 'forecast' and IsDeleted = 0,返回字段:Length、Width、Height、ActualWeight、VolumetricWeight、ChargeableWeight、Cubic
    • 从 rulesSnapshot.content.weightRule.clientRules 取计重规则:
      • 优先按客户分组选择 client 规则
      • 未匹配到专属规则时,回退使用 client = 公共
    • 计算步骤:
      • gw = t_order_weight.ActualWeight
      • vw = Length * Width * Height / volumetricFactor
      • 根据 condition 判断采用 gw 或 vw 作为未进位计费重
      • 更新 t_order_weight.VolumetricWeight = vw
    • 若 rules 快照未包含 weightRule,更新 t_order.PredeclareFailReason = '销售产品规则快照缺少计重规则',订单状态保持 draft,返回失败。
  8. 计费重进位(来自已绑定的 rules 快照)

    • 从 rulesSnapshot.content.weightRounding.ranges 根据未进位计费重匹配区间:
      • start <= 未进位计费重 <= end
    • 进位值选择:
      • 普通客户取 public
      • 客户组1取 customerGroup1
      • 客户组2取 customerGroup2
      • 无对应值时回退 public
    • 计算规则:
      • 最终计费重 = 按选中的进位值对未进位计费重向上进位
    • 更新 t_order_weight.ChargeableWeight = 最终计费重
    • 若 rules 快照未包含 weightRounding,更新 t_order.PredeclareFailReason = '销售产品规则快照缺少进位规则',订单状态保持 draft,返回失败。
  9. 价格分区匹配(来自已绑定的 rules 快照)

    • 读取 rulesSnapshot.content.areas.price.rules,按收件国家/省市/邮编区间匹配得到 zoneName(如“美国西部”)。
    • 若未匹配到价格分区,更新 t_order.PredeclareFailReason = '价格分区未匹配(规则快照)',订单状态保持 draft,返回失败。
  10. 费用计算与费用落库(来自已绑定的 price 快照;本步骤仅处理「预报」收费时机)

  • 读取 priceSnapshot.content.priceItems 作为卖价项集合;对 status=1 的价格项筛选:仅当该项 chargingTime 为 forecast(预报)或未配置(缺省视为预报) 时参与本接口算价;inbound(入库)、outbound(出库)项跳过,留待仓储流程触发(§1.3.4)。
  • 价格匹配维度以 priceItems[*].factors 定义为准;常用维度包括:分区、重量、货物类型、仓库、客户等。
  • 分区 维度取步骤 9 的 zoneName。
  • 重量 维度取最终计费重 t_order_weight.ChargeableWeight(按配置匹配区间或兜底区间)。
  • 金额计算完成后,将本阶段应计的费用项写入 t_order_fee:
    • 写入字段:OrderId、Type、CostItem、Amount、Currency、PriceNo、PriceEffectiveTime、ChargingStage
    • Type:卖价侧写 receivable;若本接口同步计算渠道应付且规则为预报计费,则对应行写 payable(实现可选,与产品/渠道配置一致)
    • PriceNo:应收建议写入 t_order.SalesProductPriceVersion;应付建议写入渠道买价绑定版本(若有)
    • PriceEffectiveTime:建议写入 priceSnapshot.effectiveStartAt(或等价生效时间)
    • ChargingStage:本步骤固定写 forecast
  • 强校验建议:若订单存在至少一条启用的卖价项,且所有启用项的 chargingTime 均不是预报(例如全部配置为入库后计费),则本步骤可产生 0 条应收;是否允许「预报成功但尚无应收行」由产品策略决定(若不允许,应配置至少一项 forecast 或调整校验)。
  • 若在本阶段应计的项中,存在应算但未匹配到价格明细,更新 t_order.PredeclareFailReason = '产品卖价快照未配置或未匹配到有效价格',订单状态保持 draft,返回失败。
  1. 固定报价示例规则(某产品,来自 price 快照的 continuePricing)
  • 示例规则:
    • 首重:1kg 以内,首重价 18 元
    • 续重:超出 1kg 部分,每 0.5kg 为一个续重单位,续重单价 6 元 / 0.5kg
    • 进位规则:不足 0.5kg 按 0.5kg 进位
  • 适用前提:
    • 该产品已匹配到对应价格分区与卖价配置
    • t_order_weight.ChargeableWeight 已完成最终进位
    • price 快照明细为 calculationFormula = 续单价 且包含 continuePricing
  • 计算口径:
    • 当 ChargeableWeight <= 1 时,总费用 = 18
    • 当 ChargeableWeight > 1 时:
      • 先收首重价 18
      • 超出部分 = ChargeableWeight - 1
      • 超出部分按 0.5kg 向上取整到续重单位数
      • 续重费用 = 续重单位数 * 6
      • 总费用 = 18 + 续重费用
  • 示例:
    • ChargeableWeight = 0.8kg,进位到 1.0kg,总费用 = 18
    • ChargeableWeight = 1.2kg,超出 0.2kg,按 0.5kg 进 1 个续重单位,总费用 = 18 + 6 = 24
    • ChargeableWeight = 1.6kg,超出 0.6kg,按 0.5kg 进 2 个续重单位,总费用 = 18 + 12 = 30
  • 该示例说明:计费重来源仅为 t_order_weight,不参与 t_order_declaration 的商品重量汇总逻辑。
  1. 成功完成预报
  • 当黑名单校验通过、偏远标记完成、计费重计算完成、本阶段(预报)应计费用写入完成后:
    • 更新 t_order.OrderStatus = 'predeclared'
    • 更新 t_order.PredeclareFailReason = ''
    • 更新 t_order.UpdateUserId、t_order.UpdateTime
  • 返回字段:
    • clientNo:取 t_order.ClientNo
    • serviceNo:取 t_order.ServiceNo
    • trackNo:取 t_order.TrackNo
    • labelUrl:若当前流程未生成面单则返回空字符串

####### 状态与失败处理

  • 参数校验失败:不创建订单,直接返回错误。
  • 草稿创建成功但后续业务失败:订单状态统一保留 draft。
  • 黑名单命中:更新 IsIntercept = 1,并写入 PredeclareFailReason。
  • 偏远命中:仅更新 IsRemote = 1,不拦截流程。
  • 计重规则、进位规则、价格分区、卖价配置缺失或未匹配:统一写入 PredeclareFailReason,订单状态保持 draft。

####### 校验与异常

  • 对必填参数、枚举值、数值范围、客户/仓库/国家/销售产品存在性进行校验,异常场景返回统一错误码与错误信息。
  • 草稿创建后的异常场景需要保留订单数据,并将失败原因写入 t_order.PredeclareFailReason,供订单列表和详情页展示。
批量创建小包(POST /order/parcel/batch-create)
1 接口请求示例

请求 /order/parcel/batch-create(POST)

批量请求体为数组,数组内每一项与 /order/parcel/create 的单票请求结构完全一致。

[
  {
    "clientNo": "string", // 客户单号 t_order.ClientNo
    "trackNo": "string", // 跟踪号 t_order.TrackNo
    "serviceNo": "string", // 运单号 t_order.ServiceNo
    "productCode": "string", // 产品代码 t_order.ProductCode
    "channelCode": "string", // 渠道代码 t_order.ChannelCode
    "cargoAttribute": "string", // 货物属性 t_order.CargoAttribute:general-普货,electronics-3c&带电,sensitive-敏感货
    "warehouseId": 0, // 仓库ID t_order.WarehouseId
    "customerId": 0, // 客户ID t_order.CustomerId
    "length": 3, // 长(cm) t_order_weight.Length
    "width": 3, // 宽(cm) t_order_weight.Width
    "height": 3, // 高(cm) t_order_weight.Height
    "actualWeight": 3, // 实重(kg) t_order_weight.ActualWeight
    "volumetricWeight": 3, // 体积重(kg) t_order_weight.VolumetricWeight
    "chargeableWeight": 3, // 计费重(kg) t_order_weight.ChargeableWeight
    "cubic": 0, // 立方(m³) t_order_weight.Cubic
    "isCod": false, // 是否COD
    "codCurrency": "string", // COD币种
    "codSum": "string", // COD金额
    "declaredCurrency": "string", // 申报币种
    "declaredSum": "string", // 申报金额
    "quantity": "string", // 包裹数量
    "receiver": { // 收件人 t_order_recipient
      "recipientsName": "string", // 收件人名称
      "companyName": "string", // 收件人公司名称
      "phone": "string", // 收件人手机
      "telePhone": "string", // 收件人电话
      "email": "string", // 收件人邮箱
      "countryCode": 0, // 国家
      "province": "string", // 收件人省/州
      "city": "string", // 收件人城市
      "streetNumber": "string", // 收件人门牌号
      "streetAddress1": "string", // 收件人地址1
      "streetAddress2": "string", // 收件人地址2
      "streetAddress3": "string", // 收件人地址3
      "zipCode": "string", // 收件人邮编
      "taxType": 0, // 税号类型
      "taxNo": "string", // 税号
      "certificateType": 0, // 证件类型
      "certificateNo": "string", // 证件号码
      "eori": "string", // EORI
      "vat": "string" // Vat
    },
    "sender": { // 发件人 t_order_sender
      "senderName": "string", // 发件人姓名
      "company": "string", // 发件人公司
      "phone": "string", // 发件人手机
      "telePhone": "string", // 发件人电话
      "email": "string", // 发件人邮箱
      "countryCode": 0, // 国家
      "province": "string", // 州省
      "city": "string", // 城市
      "zipCode": "string", // 邮编
      "streetAddress1": "string", // 地址1
      "streetAddress2": "string", // 地址2
      "streetAddress3": "string", // 地址3
      "houseNumber": "string" // 门牌号
    },
    "items": [ // 申报明细 t_order_declaration
      {
        "cnName": "string", // 品名-中
        "enName": "string", // 品名-英
        "sku": "string", // SKU
        "unit": "string", // 单位
        "unitPrice": 0, // 单价
        "unitWeight": 0, // 单重
        "quantity": 0, // 数量
        "amount": 0, // 总金额
        "weight": 0, // 总重量
        "imHsCode": "string", // 进口HsCode
        "exHsCode": "string", // 出口HsCode
        "skuImage": "string", // 图片
        "category": "string", // 类别
        "brand": "string", // 品牌
        "brandType": "string", // 品牌类型
        "isMagnetic": false, // 是否带磁带电
        "distribution": "string", // 配货信息
        "material": "string", // 材质
        "enMaterial": "string", // 英文材质
        "purpose": "string", // 用途
        "attributes": "string", // 属性
        "originCountry": "string", // 原产国
        "salesLink": "string", // 销售链接
        "model": "string", // 型号
        "specifications": "string", // 规格
        "comment": "string" // 备注
      }
    ]
  }
]

响应

{
  "code": 0,
  "msg": "success",
}
2 接口业务逻辑

####### 核心流程

  • 接收批量订单数据并逐条按单票创建规则执行,下发统一批次任务号并返回逐条处理结果。

####### 校验与异常

  • 校验请求数组非空、单次数量上限与单条必填字段;部分失败时返回明细错误信息。
模板列表(GET /order/template/list)
1 接口请求示例

请求 /order/template/list(GET,Query 参数)

?page=1&pageSize=20&type=standard|custom&keyword=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "name": "标准模板",
        "type": "standard",
        "templateKey": "standard_v1",
        "customerId": 0,
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 10
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
下载模板(GET /order/template/download)
1 接口请求示例

请求 /order/template/download(GET,Query 参数)

?templateId=1

响应

直接返回 Excel 文件流,Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
上传下单(POST /order/upload)
1 接口请求示例

请求 /order/upload(POST,multipart/form-data)

字段 类型 说明
file File Excel 文件
templateId number 模板ID

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "taskId": 1
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
任务进度列表(GET /order/task/list)
1 接口请求示例

请求 /order/task/list(GET,Query 参数)

?page=1&pageSize=20&status=&keyword=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "taskName": "批量下单_20240101",
        "quantity": 100,
        "status": "处理中",
        "templateId": 1,
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 10
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
任务详情(GET /order/task/detail)
1 接口请求示例

请求 /order/task/detail(GET,Query 参数)

?taskId=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "taskName": "批量下单_20240101",
    "quantity": 100,
    "successCount": 80,
    "failCount": 20,
    "status": "已完成",
    "templateId": 1,
    "createTime": "2024-01-01 12:00:00",
    "updateTime": "2024-01-01 12:00:00",
    "failList": []
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。

三、渠道模块

2.1 核心需求说明

  • 销售产品:管理对外销售的产品(专线/快递/邮政),配置时效、黑名单区、偏远分区、价格分区、计重规则、计重进位等;支持价格配置。
    • 产品配置:产品基础信息(编码、名称、分组、时效、面单、黑名单区、偏远分区、价格分区、计重规则、计重进位等)。
    • 产品卖价:为每个产品配置多条价格项(运费、保险费、燃油附加费等);每条价格项通过弹窗配置:
      • 基础信息:费用项、费用单位、币种、收费时机、收费条件、计费因素(因素+因素值,如货物类型、分区、重量、仓库、客户等)。
      • 价格表:根据计费因素动态生成价格表,支持分区/货物类型/重量等组合、计算公式(总价/单价/续单价)、计算值、客户组。
    • 排货规则:选择排货方案(成本最低/时效最快/综合最优),配置服务商列表(服务商名称、服务渠道、权重、指定客户)。
    • 发布记录:价格与规则的发布历史,支持查看版本内容、回滚到指定版本。
  • 服务渠道:管理下游服务渠道(支持渠道组+渠道层级),配置预报单号类型、时效、买价等。
    • 渠道配置:渠道基础信息(渠道代码、名称、时效、预报配置、描述、预报前脚本等)。
    • 渠道买价:为每个渠道配置多条买价项(运费、保险费、燃油附加费等);每条买价项通过弹窗配置:
      • 基础信息:费用项、费用单位、币种、收费时机、收费条件、计费因素(因素+因素值)。
      • 价格表:根据计费因素动态生成价格表,支持分区/货物类型/重量等组合、计算公式、计算值、客户组。
    • 发布记录:买价与规则的发布历史,支持查看版本内容、回滚到指定版本。
  • 黑名单区/偏远分区/价格分区:共用 KpiArea 表,仅通过 AreaType 区分;支持分区及明细(国家/省/市/邮编区间)的增删改查。
  • 计重规则/计重进位:配置计费重量规则与进位方式,明细结构与分区类似。
  • 自动触发:配置下单/入库/出库时的自动拦截、警告、问题件等触发规则。
  • 标签设计:保存 vg-print 导出的标签模板 JSON,支持尾程/客户/入库/出库/sku 等类型。

2.2 表结构设计

销售产品表 t_sales_product

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
ProductCode VARCHAR 64 - 是 产品编码
ProductName VARCHAR 128 - 是 产品名称
ProductGroup VARCHAR 32 - 否 分组(专线/快递/邮政)
MinTimeliness INT - - 否 最小时效(天)
MaxTimeliness INT - - 否 最大时效(天)
CustomerWaybill VARCHAR 32 - 否 系统面单/客户面单
BlacklistAreaId BIGINT - 外键 否 黑名单区ID
RemoteAreaId BIGINT - 外键 否 偏远分区ID
PriceAreaId BIGINT - 外键 否 价格分区ID(t_kpi_area,AreaType=price)
WeightRuleId BIGINT - 外键 否 计重规则ID
WeightRoundingId BIGINT - 外键 否 计重进位ID
ProductDescription TEXT - - 否 产品描述
PreStorageScript TEXT - - 否 入库前脚本
IsActive TINYINT - - 是 是否启用
Scheme VARCHAR 32 - 是 排货方案:costLowest/timeFastest/overallBest
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

产品卖价表 t_sales_product_price(子表,关联 t_sales_product)

产品卖价主表,每个产品可配置多条价格项(运费、保险费、燃油附加费等)。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
SalesProductId BIGINT - 外键 是 销售产品ID
SerialNumber INT - - 是 序号
Status TINYINT - - 是 状态:0-禁用,1-启用
PriceName VARCHAR 64 - 是 价格名称(如运费、保险费)
CostItem VARCHAR 64 - 是 费用项
CostUnit VARCHAR 16 - 是 费用单位:kg/票/件
Currency VARCHAR 16 - 是 币种:RMB/USD/EUR
ChargingTime VARCHAR 32 - 否 收费时机:决定本费用项在订单哪一履约阶段写入 t_order_fee(见 §1.3.4)。建议存编码:forecast(预报)、inbound(入库)、outbound(出库);展示可对应中文「预报/入库/出库」。缺省按 forecast。
ChargingCondition VARCHAR 64 - 否 收费条件
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

产品卖价-计费因素表 t_sales_product_price_factor(子表,关联 t_sales_product_price)

弹窗「基础信息」中的计费因素配置,支持货物类型、分区、重量、仓库、客户等。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
PriceId BIGINT - 外键 是 产品卖价ID
SerialNumber INT - - 是 序号(决定因素排序)
Factor VARCHAR 64 - 是 因素:货物类型/分区/重量/仓库/客户
FactorValues JSON - - 否 因素值数组,如 ["普货","敏感货"]
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

产品卖价-价格表明细表 t_sales_product_price_detail(子表,关联 t_sales_product_price)

弹窗「价格表」中的价格明细,表头由计费因素动态生成,存储各组合的价格值。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
PriceId BIGINT - 外键 是 产品卖价ID
FactorValuesJson JSON - - 否 非客户因素组合,如 {"分区":"欧洲","货物类型":"普货","重量":"0-0.5"}
CalculationFormula VARCHAR 32 - 是 计算公式:总价/单价/续单价
CalculatedValue DECIMAL 18,4 - 否 计算值
CustomerGroupValues JSON - - 否 客户组对应价格,如 {"客户组1":10,"客户组2":12}
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

排货规则-服务商表 t_sales_product_allocation_provider(子表,关联 t_sales_product_allocation_rule)

服务商列表:服务商名称、服务渠道、权重、指定客户。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
SalesProductId BIGINT - 外键 是 销售产品ID
SerialNumber INT - - 是 序号
ProviderName VARCHAR 128 - 是 服务商名称
ServiceChannelId BIGINT - 外键 否 服务渠道ID
Weight INT - - 是 权重(评分用)
CustomerIds JSON - - 否 指定客户ID数组,空表示全部
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

Scheme 枚举:costLowest(成本最低)、timeFastest(时效最快)、overallBest(综合最优)

发布记录表 t_sales_product_publish_record(子表,关联 t_sales_product)

价格与规则的发布历史,支持查看版本内容、回滚。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
SalesProductId BIGINT - 外键 是 销售产品ID
Version VARCHAR 32 - 是 版本号,如 20231227112339
OperatorType VARCHAR 16 - 是 操作类型:price(价格)/rules(规则)
Status VARCHAR 16 - 是 状态:生效/回滚/无效
PublishUser VARCHAR 64 - 是 发布人
PublishTime DATETIME - - 是 发布时间
Description VARCHAR 512 - 否 版本备注
Content JSON - - 否 发布内容(价格或规则配置的JSON快照)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间
发布内容 Content(JSON快照)结构规范(用于限制校验与计费)

设计目标:

  1. 强绑定有效期:订单创建时按当时的生效版本(PublishTime)绑定发布记录;后续计算以绑定版本为准。
  2. 计算快:下单/计费/校验不再联查 t_kpi_area*、t_weight_rule*、t_weight_rounding*、t_sales_product_price* 等多表;只读取一次发布记录 Content(可缓存)。
  3. 可回溯:任何时候都能根据订单绑定的发布记录ID拿到当时的规则/价格快照。

性能实现要求(强制):

  • 发布后的规则/价格快照以 t_sales_product_publish_record 为权威落库;同步任务将标准化后的 Content 写入 Redis(按 salesProductId + OperatorType + Version 或 current 指针),并通知计费服务刷新本地内存。
  • 在线下单/预估只读 Redis + 本地内存;仅在 Redis/内存异常时降级直读发布记录表(见订单模块 /order/parcel/create 步骤 4),并应异步回填 Redis。
Redis 与发布同步(在线计费)
  • Key 示例(可按团队规范调整前缀):
    • oms:pricing:sp:{salesProductId}:rules:{version} / ...:price:{version}:存放与 Content 同构的 JSON(或已序列化的二进制)。
    • oms:pricing:sp:{salesProductId}:rules:current / ...:price:current:指向当前对外生效的 version 字符串,便于 O(1) 定位。
  • 在线匹配数据来源:计费服务进程内已解析的 rulesSnapshot / priceSnapshot(来自 Redis 加载或启动预热)。

发布同步流程(必须):

  1. 业务侧完成一次规则或价格发布,写入 t_sales_product_publish_record(含 Version、Status、PublishTime、Content)。
  2. 将 Content 标准化后写入 Redis(对应 OperatorType 的 key);更新 current 指针指向新版本(与「生效」语义一致)。
  3. 通知各计费实例刷新内存;实例冷启动可从 Redis 全量加载,必要时可从发布表补齐缺失版本。
  4. 若 Redis 写入失败:应阻断或重试发布,直至线上可见一致快照,避免「库里有版本但线上算价仍用旧缓存」。
1) 通用字段(rules / price 共用)
  • schemaVersion:快照结构版本(从 1 开始)
  • operatorType:rules 或 price(与发布记录 OperatorType 保持一致)
  • salesProduct:发布时的产品基础信息快照(用于展示与校验,不参与联查)
  • effective:
    • startAt:生效时间(一般等于 PublishTime)
    • endAt:失效时间(可为空,表示至今有效;当有新版本发布时可由系统补齐旧版本 endAt)
  • checksum:可选,用于校验内容是否被篡改(如 sha256)
2) rules 快照内容(限制 + 计重 + 进位)

Content 示例(OperatorType=rules):

{
  "schemaVersion": 1,
  "operatorType": "rules",
  "salesProduct": {
    "salesProductId": 1,
    "productCode": "US_AIR",
    "productName": "美国空运专线(普货)",
    "cargoAttributes": ["general", "electronics", "sensitive"],
    "scheme": "overallBest"
  },
  "effective": { "startAt": "2026-04-25 14:30:00", "endAt": null },
  "areas": {
    "blacklist": {
      "areaName": "黑名单区1",
      "rules": [
        {
          "countryCode": "US",
          "province": null,
          "city": null,
          "postcodeRanges": [
            { "left": "90000", "right": "90010" },
            { "left": "91000", "right": "91099" }
          ]
        }
      ]
    },
    "remote": {
      "areaName": "偏远分区1",
      "rules": [
        {
          "countryCode": "US",
          "province": "California",
          "city": null,
          "postcodeRanges": [{ "left": "90001", "right": "90099" }]
        }
      ]
    },
    "price": {
      "areaName": "价格分区(美国)",
      "rules": [
        {
          "zoneCode": "US_WEST",
          "zoneName": "美国西部",
          "countryCode": "US",
          "province": null,
          "city": null,
          "postcodeRanges": [{ "left": "90000", "right": "96999" }]
        }
      ]
    }
  },
  "weightRule": {
    "weightRuleId": 1,
    "name": "标准计重规则",
    "clientRules": [
      { "client": "公共", "volumetricFactor": 6000, "condition": "gw>vw", "billableWeight": "gw" },
      { "client": "公共", "volumetricFactor": 6000, "condition": "gw<=vw", "billableWeight": "vw" }
    ]
  },
  "weightRounding": {
    "weightRoundingId": 1,
    "name": "标准进位",
    "ranges": [
      { "start": 0, "end": 30, "public": "0.5", "customerGroup1": "0.5", "customerGroup2": "0.5" }
    ]
  },
  "checksum": ""
}

说明:

  • areas.blacklist/remote/price 将 t_kpi_area_info 的明细扁平化内嵌到快照里,避免下单时联查分区表。
  • areas.price.rules[*].zoneCode/zoneName 用于后续计价因子“分区”匹配(对应价格快照的 factorValuesJson.分区)。
  • weightRule.clientRules 将 t_weight_rule_info 直接内嵌,供计算体积重/未进位计费重使用。
  • weightRounding.ranges 将 t_weight_rounding_info 内嵌,供最终计费重进位使用。
3) price 快照内容(卖价配置 + 价格表)

Content 示例(OperatorType=price):

{
  "schemaVersion": 1,
  "operatorType": "price",
  "salesProduct": {
    "salesProductId": 1,
    "productCode": "US_AIR",
    "productName": "美国空运专线(普货)"
  },
  "effective": { "startAt": "2026-04-25 14:30:00", "endAt": null },
  "priceItems": [
    {
      "serialNumber": 1,
      "status": 1,
      "priceName": "运费",
      "costItem": "freight",
      "costUnit": "kg",
      "currency": "RMB",
      "chargingTime": "预报",
      "chargingCondition": "",
      "factors": [
        { "serialNumber": 1, "factor": "分区" },
        { "serialNumber": 2, "factor": "重量" }
      ],
      "details": [
        {
          "factorValuesJson": { "分区": "美国西部", "重量": "0-9999" },
          "calculationFormula": "续单价",
          "calculatedValue": 0,
          "customerGroupValues": null,
          "continuePricing": {
            "firstWeightKg": 1,
            "firstPrice": 18,
            "continueUnitKg": 0.5,
            "continueUnitPrice": 6,
            "roundingUnitKg": 0.5
          }
        }
      ]
    }
  ],
  "checksum": ""
}

说明:

  • 为了支持“首重/续重/进位”的可落地配置,当 calculationFormula = 续单价 时,使用 continuePricing 描述完整计费参数(不再依赖额外表字段)。
  • roundingUnitKg 表示计价侧进位粒度(如 0.5kg)。若同时存在规则侧进位(rules 快照里的 weightRounding),计费重进位以规则侧为准,roundingUnitKg 用于价格项自身的续重单位计算兜底(两者一般配置一致)。

服务渠道组表 t_service_channel_group

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
Name VARCHAR 128 - 是 渠道组名称
AppId BIGINT - - 否 应用ID(页面新增/编辑服务商时保存)
ApiServiceProviderId BIGINT - - 否 API服务商ID(页面新增/编辑服务商时保存)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

服务渠道表 t_service_channel

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
GroupId BIGINT - 外键 否 渠道组ID(可选)
ChannelCode VARCHAR 64 - 是 渠道编码
ChannelName VARCHAR 128 - 是 渠道名称
MinTime INT - - 否 最小时效(天)
MaxTime INT - - 否 最大时效(天)
ForecastType VARCHAR 32 - 否 预报单号类型(customer/waybill/tracking)
ForecastCode VARCHAR 128 - 否 预报单号
Description TEXT - - 否 描述
PreScript TEXT - - 否 入库前脚本
IsActive TINYINT - - 是 是否启用
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

渠道买价表 t_service_channel_price(子表,关联 t_service_channel)

渠道买价主表,每个渠道可配置多条买价项(运费、保险费、燃油附加费等)。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
ServiceChannelId BIGINT - 外键 是 服务渠道ID
SerialNumber INT - - 是 序号
Status TINYINT - - 是 状态:0-禁用,1-启用
PriceName VARCHAR 64 - 是 价格名称
CostItem VARCHAR 64 - 是 费用项
CostUnit VARCHAR 16 - 是 费用单位:kg/票/件
Currency VARCHAR 16 - 是 币种:RMB/USD/EUR
ChargingTime VARCHAR 32 - 否 收费时机:与卖价表 ChargingTime 语义一致(§1.3.4),决定应付费用项在预报/入库/出库哪一阶段写入 t_order_fee(Type=payable)。建议编码:forecast / inbound / outbound,缺省 forecast。
ChargingCondition VARCHAR 64 - 否 收费条件
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

渠道买价-计费因素表 t_service_channel_price_factor(子表,关联 t_service_channel_price)

弹窗「基础信息」中的计费因素配置。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
PriceId BIGINT - 外键 是 渠道买价ID
SerialNumber INT - - 是 序号
Factor VARCHAR 64 - 是 因素:货物类型/分区/重量/仓库/客户
FactorValues JSON - - 否 因素值数组
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

渠道买价-价格表明细表 t_service_channel_price_detail(子表,关联 t_service_channel_price)

弹窗「价格表」中的价格明细。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
PriceId BIGINT - 外键 是 渠道买价ID
FactorValuesJson JSON - - 否 非客户因素组合
CalculationFormula VARCHAR 32 - 是 计算公式:总价/单价/续单价
CalculatedValue DECIMAL 18,4 - 否 计算值
CustomerGroupValues JSON - - 否 客户组对应价格
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

服务渠道发布记录表 t_service_channel_publish_record(子表,关联 t_service_channel)

买价与规则的发布历史。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
ServiceChannelId BIGINT - 外键 是 服务渠道ID
Version VARCHAR 32 - 是 版本号
OperatorType VARCHAR 16 - 是 操作类型:price(价格)/rules(规则)
Status VARCHAR 16 - 是 状态:生效/回滚/无效
PublishUser VARCHAR 64 - 是 发布人
PublishTime DATETIME - - 是 发布时间
Description VARCHAR 512 - 否 版本备注
Content JSON - - 否 发布内容JSON快照
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

分区表(黑名单区/偏远分区/价格分区共用)t_kpi_area

三类分区共用本表,仅通过 AreaType 区分业务含义。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
AreaType VARCHAR 32 - 是 类型: blacklist/remote/price
Name VARCHAR 128 - 是 分区名称
SystemName VARCHAR 128 - 否 系统名称
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

AreaType 枚举:blacklist(黑名单区)、remote(偏远分区)、price(价格分区)

分区明细表 t_kpi_area_info

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
AreaId BIGINT - 外键 是 分区ID
CountryCode VARCHAR 8 - 否 国家二字码
CountryName VARCHAR 64 - 否 国家名称
Province VARCHAR 128 - 否 省份
City VARCHAR 128 - 否 城市
LeftPostcode VARCHAR 32 - 否 左侧邮编
RightPostcode VARCHAR 32 - 否 右侧邮编
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

计重规则表 t_weight_rule

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
Name VARCHAR 128 - 是 规则名称
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

计重规则明细表 t_weight_rule_info(子表,关联 t_weight_rule)

计重规则子页面,配置客户组对应的计费规则(条件表达式、计费重取值、材积系数)。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
RuleId BIGINT - 外键 是 计重规则ID
Client VARCHAR 128 - 是 客户/客户组(如:公共、客户组1、客户组2)
Condition VARCHAR 256 - 是 条件表达式(如:gw>vw)
BillableWeight VARCHAR 64 - 是 计费重取值(如:vw、gw)
VolumetricFactor VARCHAR 32 - 是 材积系数(如:6000)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

计重进位表 t_weight_rounding

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
Name VARCHAR 128 - 是 进位名称
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

计重进位明细表 t_weight_rounding_info(子表,关联 t_weight_rounding)

计重进位子页面,配置重量区间的进位值(起始值、结束值、公共/客户组进位值)。

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
RoundingId BIGINT - 外键 是 计重进位ID
StartValue DECIMAL 18,4 - 是 起始值(kg)
EndValue DECIMAL 18,4 - 是 结束值(kg)
Public VARCHAR 32 - 否 公共进位值
CustomerGroup1 VARCHAR 32 - 否 客户组1进位值
CustomerGroup2 VARCHAR 32 - 否 客户组2进位值
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

自动触发表 t_auto_trigger

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
Status TINYINT - - 是 是否启用
Operation VARCHAR 32 - 否 操作: 拦截/警告/问题件
TriggerTiming VARCHAR 32 - 否 触发时机: 下单/入库/出库
TriggerCondition TEXT - - 否 触发条件
PromptMessage VARCHAR 512 - 否 提示信息
Notifier VARCHAR 128 - 否 通知人
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

标签模板表 t_label_template

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
Name VARCHAR 128 - 是 模板名称
TemplateJson JSON - - 否 vg-print 模板 JSON
TemplateType VARCHAR 32 - 否 尾程/客户/入库/出库/sku
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

2.3 核心接口设计

销售产品

接口名称 请求方式 请求路径 说明
产品列表 GET /channel/sales-product/list 产品列表
产品详情 GET /channel/sales-product/detail 产品详情
新增产品 POST /channel/sales-product/create 新增产品
更新产品 POST /channel/sales-product/update 更新产品(包含产品配置 tab 保存)
删除产品 POST /channel/sales-product/delete 删除产品
产品列表(GET /channel/sales-product/list)
1 接口请求示例

请求 /channel/sales-product/list(GET,Query 参数)

?page=1&pageSize=20&productGroup=专线&keyword=&isActive=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "productCode": "US-AIR-P",
        "productName": "美国空运专线(普货)",
        "productGroup": "专线",
        "minTimeliness": 3,
        "maxTimeliness": 7,
        "customerWaybill": "系统面单",
        "blacklistAreaId": 1,
        "remoteAreaId": 2,
        "priceAreaId": 3,
        "weightRuleId": 1,
        "weightRoundingId": 1,
        "productDescription": "美国空运普货专线",
        "isActive": 1,
        "scheme": "costLowest",
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 10
  }
}
2 接口业务逻辑

####### 核心流程

  • 接收分页与筛选参数后构建查询条件(productGroup、keyword、isActive)。 ####### 校验与异常
  • 按分页参数查询销售产品列表,返回 items 与 total。
产品详情(GET /channel/sales-product/detail)
1 接口请求示例

请求 /channel/sales-product/detail(GET,Query 参数)

?id=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "productCode": "US-AIR-P",
    "productName": "美国空运专线(普货)",
    "productGroup": "专线",
    "minTimeliness": 3,
    "maxTimeliness": 7,
    "customerWaybill": "系统面单",
    "blacklistAreaId": 1,
    "remoteAreaId": 2,
    "priceAreaId": 3,
    "weightRuleId": 1,
    "weightRoundingId": 1,
    "productDescription": "美国空运普货专线",
    "preStorageScript": "",
    "isActive": 1,
    "scheme": "costLowest",
    "createTime": "2024-01-01 12:00:00",
    "createBy": "admin",
    "updateTime": "2024-01-01 12:00:00",
    "updateBy": "admin"
  }
}
2 接口业务逻辑

####### 核心流程

  • 根据 id 查询产品主数据及扩展配置,组装详情对象返回。 ####### 校验与异常
  • 若产品不存在或不可访问,返回业务错误码。
新增产品(POST /channel/sales-product/create)
1 接口请求示例

请求 /channel/sales-product/create(POST)

{
  "productCode": "US-AIR-P",
  "productName": "美国空运专线(普货)",
  "productGroup": "专线",
  "minTimeliness": 3,
  "maxTimeliness": 7,
  "customerWaybill": "系统面单",
  "blacklistAreaId": 1,
  "remoteAreaId": 2,
  "priceAreaId": 3,
  "weightRuleId": 1,
  "weightRoundingId": 1,
  "productDescription": "美国空运普货专线",
  "preStorageScript": "",
  "isActive": 1,
  "scheme": "costLowest"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 校验产品编码唯一性与必填字段后新增产品记录。 ####### 校验与异常
  • 初始化产品配置与默认状态,写入审计字段。
更新产品(POST /channel/sales-product/update)
1 接口请求示例

请求 /channel/sales-product/update(POST)

{
  "id": 1,
  "productCode": "US-AIR-P",
  "productName": "美国空运专线(普货)",
  "productGroup": "专线",
  "minTimeliness": 3,
  "maxTimeliness": 7,
  "customerWaybill": "系统面单",
  "blacklistAreaId": 1,
  "remoteAreaId": 2,
  "priceAreaId": 3,
  "weightRuleId": 1,
  "weightRoundingId": 1,
  "productDescription": "美国空运普货专线",
  "preStorageScript": "",
  "isActive": 1,
  "scheme": "costLowest"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据 id 校验产品存在性后更新可变字段(包含产品配置 tab 的保存内容)。 ####### 校验与异常
  • 记录操作人和更新时间,并触发配置缓存刷新。
删除产品(POST /channel/sales-product/delete)
1 接口请求示例

请求 /channel/sales-product/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 校验产品是否可删除(无有效关联配置/任务)后执行逻辑删除。 ####### 校验与异常
  • 更新删除标识及审计字段,避免物理删除带来的历史数据丢失。

产品卖价(子表接口)

接口名称 请求方式 请求路径 说明
价格项列表 GET /channel/sales-product/price/list 按产品ID获取价格项列表
新增价格项 POST /channel/sales-product/price/create 新增价格项(含基础信息+计费因素+价格表)
更新价格项 POST /channel/sales-product/price/update 更新价格项
删除价格项 POST /channel/sales-product/price/delete 删除价格项
切换价格项状态 POST /channel/sales-product/price/toggleStatus 启用/禁用价格项
价格项列表(GET /channel/sales-product/price/list)
1 接口请求示例

请求 /channel/sales-product/price/list(GET,Query 参数)

?salesProductId=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "salesProductId": 1,
        "serialNumber": 1,
        "status": 1,
        "priceName": "运费",
        "costItem": "freight",
        "costUnit": "kg",
        "currency": "RMB",
        "chargingTime": "出库",
        "chargingCondition": "",
        "factors": [
          {
            "id": 1,
            "priceId": 1,
            "serialNumber": 1,
            "factor": "货物类型",
            "factorValues": ["普货", "敏感货"]
          }
        ],
        "details": [
          {
            "id": 1,
            "priceId": 1,
            "factorValuesJson": {"分区": "欧洲", "货物类型": "普货", "重量": "0-0.5"},
            "calculationFormula": "单价",
            "calculatedValue": 62,
            "customerGroupValues": {"客户组1": 60, "客户组2": 65}
          }
        ],
        "version": "20260425143000",
        "publishTime": "2026-04-25 14:30:00",
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 按 salesProductId 查询价格项主表,并聚合返回计费因素与价格明细子数据。
  • 结果按 serialNumber 升序组织,便于前端按配置顺序渲染。

####### 校验与异常

  • 校验 salesProductId 必填且产品存在;不存在时返回业务错误。
  • 仅返回未删除记录,查询异常返回统一错误码。
新增价格项(POST /channel/sales-product/price/create)
1 接口请求示例

请求 /channel/sales-product/price/create(POST)

{
  "salesProductId": 1,
  "serialNumber": 1,
  "status": 1,
  "priceName": "运费",
  "costItem": "freight",
  "costUnit": "kg",
  "currency": "RMB",
  "chargingTime": "出库",
  "chargingCondition": "",
  "factors": [
    {
      "serialNumber": 1,
      "factor": "货物类型",
      "factorValues": ["普货", "敏感货"]
    },
    {
      "serialNumber": 2,
      "factor": "分区",
      "factorValues": ["欧洲", "美国"]
    }
  ],
  "details": [
    {
      "factorValuesJson": {"分区": "欧洲", "货物类型": "普货", "重量": "0-0.5"},
      "calculationFormula": "单价",
      "calculatedValue": 62,
      "customerGroupValues": {"客户组1": 60, "客户组2": 65}
    }
  ]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增价格项主记录,并写入对应 factors 与 details 子记录。
  • 同步写入审计字段,保持主从数据一致性。

####### 校验与异常

  • 校验 salesProductId、priceName、costItem、costUnit 等必填字段。
  • 校验同产品下 serialNumber 不冲突;冲突时返回业务错误。
更新价格项(POST /channel/sales-product/price/update)
1 接口请求示例

请求 /channel/sales-product/price/update(POST)

{
  "id": 1,
  "salesProductId": 1,
  "serialNumber": 1,
  "status": 1,
  "priceName": "运费",
  "costItem": "freight",
  "costUnit": "kg",
  "currency": "RMB",
  "chargingTime": "出库",
  "chargingCondition": "",
  "factors": [],
  "details": []
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按 id 更新价格项主数据,并按最新请求重建/同步因素与明细子数据。
  • 保留版本追溯能力,更新后可参与后续发布流程。

####### 校验与异常

  • 校验 id 存在且归属 salesProductId。
  • 校验更新后配置合法(计算公式、阶梯区间、客户组取值等),不合法时返回业务错误。
删除价格项(POST /channel/sales-product/price/delete)
1 接口请求示例

请求 /channel/sales-product/price/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按价格项 id 执行逻辑删除,并处理关联子表数据的可见性。

####### 校验与异常

  • 校验 id 存在且允许删除(如未处于不可删状态)。
  • 删除失败返回统一业务错误码。
切换价格项状态(POST /channel/sales-product/price/toggleStatus)
1 接口请求示例

请求 /channel/sales-product/price/toggleStatus(POST)

{
  "id": 1,
  "status": 0
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按 id 更新价格项启用状态(status),并刷新相关缓存。

####### 校验与异常

  • 校验 status 仅允许合法枚举值(启用/禁用)。
  • 校验 id 存在,不存在时返回业务错误。

排货规则(子表接口)

接口名称 请求方式 请求路径 说明
获取排货规则 GET /channel/sales-product/allocation/get 按产品ID获取排货方案及服务商列表
保存排货规则 POST /channel/sales-product/allocation/save 保存排货方案及服务商(保存并可选发布)
获取排货规则(GET /channel/sales-product/allocation/get)
1 接口请求示例

请求 /channel/sales-product/allocation/get(GET,Query 参数)

?salesProductId=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "salesProductId": 1,
    "scheme": "costLowest",
    "providers": [
      {
        "id": 1,
        "salesProductId": 1,
        "serialNumber": 1,
        "providerName": "一代物流",
        "serviceChannelId": 10,
        "serviceChannelName": "DHL美国专线",
        "weight": 100,
        "customerIds": [1, 2],
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 根据 salesProductId 查询排货方案与服务商列表并按顺序返回。

####### 校验与异常

  • 校验 salesProductId 必填且产品存在;不存在时返回业务错误。
保存排货规则(POST /channel/sales-product/allocation/save)
1 接口请求示例

请求 /channel/sales-product/allocation/save(POST)

{
  "salesProductId": 1,
  "publish": false,
  "scheme": "costLowest",
  "providers": [
    {
      "id": 0,
      "serialNumber": 1,
      "providerName": "一代物流",
      "serviceChannelId": 10,
      "weight": 100,
      "customerIds": [1, 2]
    }
  ]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 保存排货策略与服务商配置,按 id 判定新增或更新。
  • 当 publish=true 时触发规则发布并生成版本记录。

####### 校验与异常

  • 校验 salesProductId、scheme 与 providers 合法性。
  • 保存失败回滚事务并返回统一错误信息。

发布记录(子表接口)

接口名称 请求方式 请求路径 说明
价格发布记录列表 GET /channel/sales-product/publish/price/list 按产品ID获取价格发布历史
规则发布记录列表 GET /channel/sales-product/publish/rules/list 按产品ID获取规则发布历史
发布 POST /channel/sales-product/publish 发布当前配置(价格或规则)
回滚到版本 POST /channel/sales-product/publish/rollback 回滚到指定版本
价格发布记录列表(GET /channel/sales-product/publish/price/list)
1 接口请求示例

请求 /channel/sales-product/publish/price/list(GET,Query 参数)

?salesProductId=1&page=1&pageSize=20

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "salesProductId": 1,
        "version": "20231227112339",
        "operatorType": "price",
        "status": "生效",
        "publishUser": "admin",
        "publishTime": "2023-12-27 11:23:39",
        "description": "价格调整",
        "content": {},
        "createTime": "2023-12-27 11:23:39"
      }
    ],
    "total": 5
  }
}
2 接口业务逻辑

####### 核心流程

  • 按产品ID分页查询价格类发布历史,返回版本与发布人信息。

####### 校验与异常

  • 校验 salesProductId 与分页参数合法性,异常时返回统一错误码。
规则发布记录列表(GET /channel/sales-product/publish/rules/list)
1 接口请求示例

请求 /channel/sales-product/publish/rules/list(GET,Query 参数)

?salesProductId=1&page=1&pageSize=20

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 2,
        "salesProductId": 1,
        "version": "20231228103000",
        "operatorType": "rules",
        "status": "生效",
        "publishUser": "admin",
        "publishTime": "2023-12-28 10:30:00",
        "description": "规则调整",
        "content": {},
        "createTime": "2023-12-28 10:30:00"
      }
    ],
    "total": 3
  }
}
2 接口业务逻辑

####### 核心流程

  • 按产品ID分页查询规则类发布历史,operatorType 固定为 rules。

####### 校验与异常

  • 校验 salesProductId 与分页参数合法性,异常时返回统一错误码。
发布(POST /channel/sales-product/publish)
1 接口请求示例

请求 /channel/sales-product/publish(POST)

{
  "salesProductId": 1,
  "operatorType": "price",
  "description": "价格调整"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 将当前配置发布为新版本并写入发布记录。

####### 校验与异常

  • 校验 salesProductId、operatorType 必填且可发布。
回滚到版本(POST /channel/sales-product/publish/rollback)
1 接口请求示例

请求 /channel/sales-product/publish/rollback(POST)

{
  "salesProductId": 1,
  "recordId": 1,
  "operatorType": "price"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 将配置回滚到指定发布版本并生成回滚记录。

####### 校验与异常

  • 校验 recordId 版本存在且与产品、类型一致,不一致时返回业务错误。

服务渠道

接口名称 请求方式 请求路径 说明
渠道列表 GET /channel/service-channel/list 渠道列表(含渠道组层级)
渠道详情 GET /channel/service-channel/detail 渠道详情
新增渠道 POST /channel/service-channel/create 新增渠道
更新渠道 POST /channel/service-channel/update 更新渠道(包含渠道配置 tab 保存)
删除渠道 POST /channel/service-channel/delete 删除渠道
服务商分组列表 GET /channel/service-channel/group/list 获取服务商分组列表(下拉/筛选)
新增服务商 POST /channel/service-channel/group/create 新增服务商分组(写入 t_service_channel_group,保存应用ID与API服务商ID)
编辑服务商 POST /channel/service-channel/group/update 编辑服务商分组(更新名称/应用ID/API服务商ID)
删除服务商 POST /channel/service-channel/group/delete 删除服务商分组(若分组下存在渠道需禁止删除)
渠道列表(GET /channel/service-channel/list)
1 接口请求示例

请求 /channel/service-channel/list(GET,Query 参数)

?page=1&pageSize=20&groupId=&keyword=&isActive=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "groupId": 1,
        "groupName": "DHL渠道组",
        "channelCode": "DHL-US",
        "channelName": "DHL美国专线",
        "minTime": 3,
        "maxTime": 7,
        "forecastType": "waybill",
        "forecastCode": "",
        "description": "DHL美国专线渠道",
        "isActive": 1,
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 10
  }
}
2 接口业务逻辑

####### 核心流程

  • 按分页与筛选条件查询渠道列表,返回渠道及所属分组信息。

####### 校验与异常

  • 校验分页参数合法性,异常时返回统一错误码。
渠道详情(GET /channel/service-channel/detail)
1 接口请求示例

请求 /channel/service-channel/detail(GET,Query 参数)

?id=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "groupId": 1,
    "groupName": "DHL渠道组",
    "channelCode": "DHL-US",
    "channelName": "DHL美国专线",
    "minTime": 3,
    "maxTime": 7,
    "forecastType": "waybill",
    "forecastCode": "",
    "description": "DHL美国专线渠道",
    "preScript": "",
    "isActive": 1,
    "createTime": "2024-01-01 12:00:00",
    "createBy": "admin",
    "updateTime": "2024-01-01 12:00:00",
    "updateBy": "admin"
  }
}
2 接口业务逻辑

####### 核心流程

  • 根据渠道 id 查询渠道详情与配置信息。

####### 校验与异常

  • 校验 id 必填且存在,不存在时返回业务错误。
新增渠道(POST /channel/service-channel/create)
1 接口请求示例

请求 /channel/service-channel/create(POST)

{
  "groupId": 1,
  "channelCode": "DHL-US",
  "channelName": "DHL美国专线",
  "minTime": 3,
  "maxTime": 7,
  "forecastType": "waybill",
  "forecastCode": "",
  "description": "DHL美国专线渠道",
  "preScript": "",
  "isActive": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增渠道基础配置并写入审计字段。

####### 校验与异常

  • 校验 groupId、channelCode、channelName 等必填字段,编码冲突时返回业务错误。
服务商分组列表(GET /channel/service-channel/group/list)
1 接口请求示例

请求 /channel/service-channel/group/list(GET,Query 参数)

?keyword=&appId=&apiServiceProviderId=

响应

{
  "code": 0,
  "msg": "success",
  "data": [
    {
      "id": 1,
      "name": "壹号",
      "appId": 8,
      "apiServiceProviderId": 41,
      "createTime": "2026-05-04 14:15:45",
      "updateTime": "1900-01-01 00:00:00"
    }
  ]
}
2 接口业务逻辑

####### 核心流程

  • 查询 t_service_channel_group 未删除分组,可按 keyword、appId、apiServiceProviderId 过滤,按 id 倒序返回。

####### 校验与异常

  • 过滤参数格式非法时返回业务错误;无数据时返回空数组。
新增服务商(POST /channel/service-channel/group/create)
1 接口请求示例

请求 /channel/service-channel/group/create(POST)

{
  "name": "DHL服务商",
  "appId": 1,
  "apiServiceProviderId": 12
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 在 t_service_channel_group 新增服务商分组并写入应用ID与API服务商ID。

####### 校验与异常

  • 校验 name、appId、apiServiceProviderId 必填且有效。
编辑服务商(POST /channel/service-channel/group/update)
1 接口请求示例

请求 /channel/service-channel/group/update(POST)

{
  "id": 1,
  "name": "DHL服务商(更新)",
  "appId": 1,
  "apiServiceProviderId": 12
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据分组 id 更新服务商名称、应用ID与API服务商ID。

####### 校验与异常

  • 校验 id 存在且可编辑,不存在时返回业务错误。
删除服务商(POST /channel/service-channel/group/delete)
1 接口请求示例

请求 /channel/service-channel/group/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据分组 id 执行逻辑删除。

####### 校验与异常

  • 若分组下存在渠道则禁止删除并返回业务错误。
更新渠道(POST /channel/service-channel/update)
1 接口请求示例

请求 /channel/service-channel/update(POST)

{
  "id": 1,
  "groupId": 1,
  "channelCode": "DHL-US",
  "channelName": "DHL美国专线",
  "minTime": 3,
  "maxTime": 7,
  "forecastType": "waybill",
  "forecastCode": "",
  "description": "DHL美国专线渠道",
  "preScript": "",
  "isActive": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新渠道基础信息与渠道配置 tab 数据。

####### 校验与异常

  • 校验 id 存在及字段合法性,更新失败返回业务错误。
删除渠道(POST /channel/service-channel/delete)
1 接口请求示例

请求 /channel/service-channel/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 校验渠道是否可删除后执行逻辑删除并保留历史审计信息。

####### 校验与异常

  • 存在关联配置或不可删除状态时返回业务错误。

渠道买价(子表接口)

接口名称 请求方式 请求路径 说明
买价项列表 GET /channel/service-channel/price/list 按渠道ID获取买价项列表
新增买价项 POST /channel/service-channel/price/create 新增买价项(含基础信息+计费因素+价格表)
更新买价项 POST /channel/service-channel/price/update 更新买价项
删除买价项 POST /channel/service-channel/price/delete 删除买价项
切换买价项状态 POST /channel/service-channel/price/toggleStatus 启用/禁用买价项
买价项列表(GET /channel/service-channel/price/list)
1 接口请求示例

请求 /channel/service-channel/price/list(GET,Query 参数)

?serviceChannelId=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "serviceChannelId": 1,
        "serialNumber": 1,
        "status": 1,
        "priceName": "运费",
        "costItem": "freight",
        "costUnit": "kg",
        "currency": "RMB",
        "chargingTime": "出库",
        "chargingCondition": "",
        "factors": [],
        "details": [],
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 按 serviceChannelId 查询买价项及其因素、明细子项。

####### 校验与异常

  • 校验 serviceChannelId 必填且渠道存在;异常返回统一错误码。
新增买价项(POST /channel/service-channel/price/create)
1 接口请求示例

请求 /channel/service-channel/price/create(POST)

{
  "serviceChannelId": 1,
  "serialNumber": 1,
  "status": 1,
  "priceName": "运费",
  "costItem": "freight",
  "costUnit": "kg",
  "currency": "RMB",
  "chargingTime": "出库",
  "chargingCondition": "",
  "factors": [
    {
      "serialNumber": 1,
      "factor": "货物类型",
      "factorValues": ["普货", "敏感货"]
    }
  ],
  "details": [
    {
      "factorValuesJson": {"分区": "欧洲", "货物类型": "普货", "重量": "0-0.5"},
      "calculationFormula": "单价",
      "calculatedValue": 45,
      "customerGroupValues": {}
    }
  ]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增买价主记录并写入因素、明细子表。

####### 校验与异常

  • 校验必填参数与序号冲突规则,校验失败返回业务错误。
更新买价项(POST /channel/service-channel/price/update)
1 接口请求示例

请求 /channel/service-channel/price/update(POST)

{
  "id": 1,
  "serviceChannelId": 1,
  "serialNumber": 1,
  "status": 1,
  "priceName": "运费",
  "costItem": "freight",
  "costUnit": "kg",
  "currency": "RMB",
  "chargingTime": "出库",
  "chargingCondition": "",
  "factors": [],
  "details": []
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按 id 更新买价主数据并同步子项明细。

####### 校验与异常

  • 校验 id 存在且归属渠道一致,校验失败返回业务错误。
删除买价项(POST /channel/service-channel/price/delete)
1 接口请求示例

请求 /channel/service-channel/price/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据 id 逻辑删除买价项并处理关联子项可见性。

####### 校验与异常

  • 校验 id 存在且允许删除。
切换买价项状态(POST /channel/service-channel/price/toggleStatus)
1 接口请求示例

请求 /channel/service-channel/price/toggleStatus(POST)

{
  "id": 1,
  "status": 0
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按 id 更新买价项启用状态并刷新缓存。

####### 校验与异常

  • 校验 status 枚举与 id 存在性,不合法时返回业务错误。

服务渠道发布记录(子表接口)

接口名称 请求方式 请求路径 说明
价格发布记录列表 GET /channel/service-channel/publish/price/list 按渠道ID获取买价发布历史
规则发布记录列表 GET /channel/service-channel/publish/rules/list 按渠道ID获取规则发布历史
发布 POST /channel/service-channel/publish 发布当前配置(买价或规则)
回滚到版本 POST /channel/service-channel/publish/rollback 回滚到指定版本
价格发布记录列表(GET /channel/service-channel/publish/price/list)
1 接口请求示例

请求 /channel/service-channel/publish/price/list(GET,Query 参数)

?serviceChannelId=1&page=1&pageSize=20

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "serviceChannelId": 1,
        "version": "20231227112339",
        "operatorType": "price",
        "status": "生效",
        "publishUser": "admin",
        "publishTime": "2023-12-27 11:23:39",
        "description": "买价调整",
        "content": {},
        "createTime": "2023-12-27 11:23:39"
      }
    ],
    "total": 5
  }
}
2 接口业务逻辑

####### 核心流程

  • 按渠道ID分页查询买价发布记录并返回版本信息。

####### 校验与异常

  • 校验 serviceChannelId 与分页参数合法性。
规则发布记录列表(GET /channel/service-channel/publish/rules/list)
1 接口请求示例

请求 /channel/service-channel/publish/rules/list(GET,Query 参数)

?serviceChannelId=1&page=1&pageSize=20

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 2,
        "serviceChannelId": 1,
        "version": "20231228103000",
        "operatorType": "rules",
        "status": "生效",
        "publishUser": "admin",
        "publishTime": "2023-12-28 10:30:00",
        "description": "规则调整",
        "content": {},
        "createTime": "2023-12-28 10:30:00"
      }
    ],
    "total": 3
  }
}
2 接口业务逻辑

####### 核心流程

  • 按渠道ID分页查询规则发布记录,operatorType 固定为 rules。

####### 校验与异常

  • 校验 serviceChannelId 与分页参数合法性。
发布(POST /channel/service-channel/publish)
1 接口请求示例

请求 /channel/service-channel/publish(POST)

{
  "serviceChannelId": 1,
  "operatorType": "price",
  "description": "买价调整"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 发布当前渠道配置并生成新的发布版本记录。

####### 校验与异常

  • 校验 serviceChannelId、operatorType 必填且可发布。
回滚到版本(POST /channel/service-channel/publish/rollback)
1 接口请求示例

请求 /channel/service-channel/publish/rollback(POST)

{
  "serviceChannelId": 1,
  "recordId": 1,
  "operatorType": "price"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 回滚到指定版本并生成回滚操作记录。

####### 校验与异常

  • 校验 recordId 与渠道、类型匹配关系,异常时返回业务错误。

黑名单区 / 偏远分区 / 价格分区(共用 KpiArea)

共用 /channel/kpi-area/* 接口,仅通过请求/响应中的 areaType(对应表字段 AreaType)区分分区类型。

类型 areaType
黑名单区 blacklist
偏远分区 remote
价格分区 price
接口名称 请求方式 请求路径 说明
创建分区 POST /channel/kpi-area/create 创建分区
修改分区 POST /channel/kpi-area/update 修改分区
删除分区 POST /channel/kpi-area/delete 删除分区
分区列表 POST /channel/kpi-area/list 分区列表
新增分区明细 POST /channel/kpi-area/info/add 新增分区明细
修改分区明细 POST /channel/kpi-area/info/update 修改分区明细
删除分区明细 POST /channel/kpi-area/info/delete 删除分区明细
分区明细列表 POST /channel/kpi-area/info/list 分区明细列表
创建分区(POST /channel/kpi-area/create)
1 接口请求示例

请求 /channel/kpi-area/create(POST)

{
  "areaType": "blacklist",
  "name": "黑名单区1",
  "systemName": "系统黑名单"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据 areaType 创建分区主记录。

####### 校验与异常

  • 校验 areaType、name 必填且合法。
修改分区(POST /channel/kpi-area/update)
1 接口请求示例

请求 /channel/kpi-area/update(POST)

{
  "id": 1,
  "areaType": "blacklist",
  "name": "黑名单区1",
  "systemName": "系统黑名单"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新分区名称与系统名称。

####### 校验与异常

  • 校验 id 存在且与 areaType 匹配。
删除分区(POST /channel/kpi-area/delete)
1 接口请求示例

请求 /channel/kpi-area/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据 id 执行分区逻辑删除。

####### 校验与异常

  • 分区存在明细时按业务规则拦截或级联处理。
分区列表(POST /channel/kpi-area/list)
1 接口请求示例

请求 /channel/kpi-area/list(POST)

{
  "areaType": "blacklist",
  "page": 1,
  "pageSize": 20
}

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "areaType": "blacklist",
        "name": "黑名单区1",
        "systemName": "系统黑名单",
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 5
  }
}
2 接口业务逻辑

####### 核心流程

  • 按 areaType 分页查询分区列表。

####### 校验与异常

  • 校验分页参数与 areaType 合法性。
新增分区明细(POST /channel/kpi-area/info/add)
1 接口请求示例

请求 /channel/kpi-area/info/add(POST)

{
  "areaId": 1,
  "countryCode": "US",
  "countryName": "美国",
  "province": "加州",
  "city": "洛杉矶",
  "leftPostcode": "90001",
  "rightPostcode": "90099"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 向指定分区新增明细记录(国家/省市/邮编区间)。

####### 校验与异常

  • 校验 areaId 存在且区间数据合法。
修改分区明细(POST /channel/kpi-area/info/update)
1 接口请求示例

请求 /channel/kpi-area/info/update(POST)

{
  "id": 1,
  "areaId": 1,
  "countryCode": "US",
  "countryName": "美国",
  "province": "加州",
  "city": "洛杉矶",
  "leftPostcode": "90001",
  "rightPostcode": "90099"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据明细 id 更新分区明细字段。

####### 校验与异常

  • 校验 id 存在,更新内容合法。
删除分区明细(POST /channel/kpi-area/info/delete)
1 接口请求示例

请求 /channel/kpi-area/info/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据明细 id 执行逻辑删除。

####### 校验与异常

  • 校验 id 存在,不存在时返回业务错误。
分区明细列表(POST /channel/kpi-area/info/list)
1 接口请求示例

请求 /channel/kpi-area/info/list(POST)

{
  "areaId": 1,
  "page": 1,
  "pageSize": 20
}

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "areaId": 1,
        "countryCode": "US",
        "countryName": "美国",
        "province": "加州",
        "city": "洛杉矶",
        "leftPostcode": "90001",
        "rightPostcode": "90099",
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 10
  }
}
2 接口业务逻辑

####### 核心流程

  • 按 areaId 分页查询分区明细列表。

####### 校验与异常

  • 校验 areaId 与分页参数合法性。

计重规则 / 计重进位

接口名称 请求方式 请求路径 说明
规则列表 POST /channel/weight-rule/list 规则列表
创建规则 POST /channel/weight-rule/create 创建规则
更新规则 POST /channel/weight-rule/update 更新规则
删除规则 POST /channel/weight-rule/delete 删除规则
规则明细列表 POST /channel/weight-rule/info/list 规则明细列表
新增明细 POST /channel/weight-rule/info/add 新增明细
更新明细 POST /channel/weight-rule/info/update 更新明细
删除明细 POST /channel/weight-rule/info/delete 删除明细
进位列表 POST /channel/weight-rounding/list 进位列表
创建进位 POST /channel/weight-rounding/create 创建进位
更新进位 POST /channel/weight-rounding/update 更新进位
删除进位 POST /channel/weight-rounding/delete 删除进位
进位明细列表 POST /channel/weight-rounding/info/list 进位明细列表
新增进位明细 POST /channel/weight-rounding/info/add 新增进位明细
更新进位明细 POST /channel/weight-rounding/info/update 更新进位明细
删除进位明细 POST /channel/weight-rounding/info/delete 删除进位明细
规则列表(POST /channel/weight-rule/list)
1 接口请求示例

请求 /channel/weight-rule/list(POST)

{
  "page": 1,
  "pageSize": 20
}

响应

{
  "code": 0,
  "msg": "success",
  "data": { "items": [{ "id": 1, "name": "标准计重规则" }], "total": 5 }
}
2 接口业务逻辑

####### 核心流程

  • 分页查询计重规则主表。 ####### 校验与异常
  • 校验分页参数合法性。
创建规则(POST /channel/weight-rule/create)
1 接口请求示例

请求 /channel/weight-rule/create(POST)

{ "name": "标准计重规则" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 新增计重规则并写入审计信息。 ####### 校验与异常
  • 校验 name 必填且不重复。
更新规则(POST /channel/weight-rule/update)
1 接口请求示例

请求 /channel/weight-rule/update(POST)

{ "id": 1, "name": "标准计重规则" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新规则信息。 ####### 校验与异常
  • 校验 id 存在。
删除规则(POST /channel/weight-rule/delete)
1 接口请求示例

请求 /channel/weight-rule/delete(POST)

{ "id": 1 }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 对规则执行逻辑删除。 ####### 校验与异常
  • 校验是否存在关联明细。
规则明细列表(POST /channel/weight-rule/info/list)
1 接口请求示例

请求 /channel/weight-rule/info/list(POST)

{ "ruleId": 1, "page": 1, "pageSize": 20 }

响应

{
  "code": 0,
  "msg": "success",
  "data": { "items": [{ "id": 1, "ruleId": 1, "client": "公共" }], "total": 3 }
}
2 接口业务逻辑

####### 核心流程

  • 按 ruleId 分页查询规则明细。 ####### 校验与异常
  • 校验 ruleId 必填且有效。
新增明细(POST /channel/weight-rule/info/add)
1 接口请求示例

请求 /channel/weight-rule/info/add(POST)

{ "ruleId": 1, "client": "公共", "condition": "gw>vw", "billableWeight": "vw", "volumetricFactor": "6000" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 新增规则明细。 ####### 校验与异常
  • 校验 ruleId 与字段合法性。
更新明细(POST /channel/weight-rule/info/update)
1 接口请求示例

请求 /channel/weight-rule/info/update(POST)

{ "id": 1, "ruleId": 1, "client": "公共", "condition": "gw>vw", "billableWeight": "vw", "volumetricFactor": "6000" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新规则明细。 ####### 校验与异常
  • 校验 id 存在且归属正确。
删除明细(POST /channel/weight-rule/info/delete)
1 接口请求示例

请求 /channel/weight-rule/info/delete(POST)

{ "id": 1 }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 删除规则明细(逻辑删除)。 ####### 校验与异常
  • 校验 id 存在。
进位列表(POST /channel/weight-rounding/list)
1 接口请求示例

请求 /channel/weight-rounding/list(POST)

{ "page": 1, "pageSize": 20 }

响应

{
  "code": 0,
  "msg": "success",
  "data": { "items": [{ "id": 1, "name": "标准进位" }], "total": 5 }
}
2 接口业务逻辑

####### 核心流程

  • 分页查询计重进位主表。 ####### 校验与异常
  • 校验分页参数。
创建进位(POST /channel/weight-rounding/create)
1 接口请求示例

请求 /channel/weight-rounding/create(POST)

{ "name": "标准进位" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 新增进位规则。 ####### 校验与异常
  • 校验 name 必填。
更新进位(POST /channel/weight-rounding/update)
1 接口请求示例

请求 /channel/weight-rounding/update(POST)

{ "id": 1, "name": "标准进位" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新进位规则。 ####### 校验与异常
  • 校验 id 存在。
删除进位(POST /channel/weight-rounding/delete)
1 接口请求示例

请求 /channel/weight-rounding/delete(POST)

{ "id": 1 }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 逻辑删除进位规则。 ####### 校验与异常
  • 校验是否可删除。
进位明细列表(POST /channel/weight-rounding/info/list)
1 接口请求示例

请求 /channel/weight-rounding/info/list(POST)

{ "roundingId": 1, "page": 1, "pageSize": 20 }

响应

{
  "code": 0,
  "msg": "success",
  "data": { "items": [{ "id": 1, "roundingId": 1, "startValue": 0, "endValue": 1 }], "total": 5 }
}
2 接口业务逻辑

####### 核心流程

  • 按 roundingId 分页查询进位明细。 ####### 校验与异常
  • 校验 roundingId 存在。
新增进位明细(POST /channel/weight-rounding/info/add)
1 接口请求示例

请求 /channel/weight-rounding/info/add(POST)

{ "roundingId": 1, "startValue": 0, "endValue": 1, "public": "0.5", "customerGroup1": "0.5", "customerGroup2": "0.25" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 新增进位明细。 ####### 校验与异常
  • 校验区间与分组字段合法性。
更新进位明细(POST /channel/weight-rounding/info/update)
1 接口请求示例

请求 /channel/weight-rounding/info/update(POST)

{ "id": 1, "roundingId": 1, "startValue": 0, "endValue": 1, "public": "0.5", "customerGroup1": "0.5", "customerGroup2": "0.25" }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新进位明细。 ####### 校验与异常
  • 校验 id 存在且归属正确。
删除进位明细(POST /channel/weight-rounding/info/delete)
1 接口请求示例

请求 /channel/weight-rounding/info/delete(POST)

{ "id": 1 }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 删除进位明细(逻辑删除)。 ####### 校验与异常
  • 校验 id 存在。

自动触发

接口名称 请求方式 请求路径 说明
列表 GET /channel/auto-trigger/list 列表
新增 POST /channel/auto-trigger/create 新增
更新 POST /channel/auto-trigger/update 更新
删除 POST /channel/auto-trigger/delete 删除
切换启用状态 POST /channel/auto-trigger/toggleStatus 切换启用状态
列表(GET /channel/auto-trigger/list)
1 接口请求示例

请求 /channel/auto-trigger/list(GET,Query 参数)

?page=1&pageSize=20&operation=&triggerTiming=

响应

{
  "code": 0,
  "msg": "success",
  "data": { "items": [{ "id": 1, "operation": "拦截", "triggerTiming": "下单" }], "total": 5 }
}
2 接口业务逻辑

####### 核心流程

  • 分页查询自动触发规则列表。 ####### 校验与异常
  • 校验分页与筛选参数合法。
新增(POST /channel/auto-trigger/create)
1 接口请求示例

请求 /channel/auto-trigger/create(POST)

{
  "status": 1,
  "operation": "拦截",
  "triggerTiming": "下单",
  "triggerCondition": "weight>30",
  "promptMessage": "重量超过30kg,请确认",
  "notifier": "admin@example.com"
}

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 新增自动触发规则。 ####### 校验与异常
  • 校验关键字段必填。
更新(POST /channel/auto-trigger/update)
1 接口请求示例

请求 /channel/auto-trigger/update(POST)

{
  "id": 1,
  "status": 1,
  "operation": "拦截",
  "triggerTiming": "下单",
  "triggerCondition": "weight>30",
  "promptMessage": "重量超过30kg,请确认",
  "notifier": "admin@example.com"
}

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 根据 id 更新自动触发规则。 ####### 校验与异常
  • 校验 id 存在且可编辑。
删除(POST /channel/auto-trigger/delete)
1 接口请求示例

请求 /channel/auto-trigger/delete(POST)

{ "id": 1 }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 逻辑删除自动触发规则。 ####### 校验与异常
  • 校验 id 存在且可删除。
切换启用状态(POST /channel/auto-trigger/toggleStatus)
1 接口请求示例

请求 /channel/auto-trigger/toggleStatus(POST)

{ "id": 1, "status": 0 }

响应

{ "code": 0, "msg": "success", "data": null }
2 接口业务逻辑

####### 核心流程

  • 按 id 切换规则启用状态。 ####### 校验与异常
  • 校验 status 枚举合法性。

标签设计

接口名称 请求方式 请求路径 说明
保存标签模板 POST /channel/label-template/save 保存标签模板
1 接口请求示例

请求 /channel/label-template/save(POST)

{
  "id": 0,
  "name": "尾程标签模板1",
  "templateType": "lastMile",
  "templateJson": {}
}

参数说明:id 模板ID,0为新增;templateType 类型:lastMile(尾程)/customer(客户)/inbound(入库)/outbound(出库)/sku;templateJson vg-print 导出的模板 JSON。

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "name": "尾程标签模板1",
    "templateType": "lastMile",
    "templateJson": {},
    "createTime": "2024-01-01 12:00:00",
    "updateTime": "2024-01-01 12:00:00"
  }
}


2 接口业务逻辑

####### 核心流程

  • 按本节接口定义执行业务处理流程,完成参数解析、数据查询/写入与结果返回。

####### 校验与异常

  • 对必填参数、状态流转与数据存在性进行校验;异常场景返回统一错误码与错误信息。

四、操作模块

3.1 核心需求说明

  • 入库扫描:扫描运单号完成入库,记录实重、尺寸、销售产品、目的国、仓库、操作人、操作时间;支持查看最近入库记录。
  • 出库扫描:扫描运单号完成出库,记录仓库、操作人、操作时间;支持查看最近出库记录。
  • 标签打印:按运单号/客户单号/跟踪号/其他单号选择标签模板打印;记录打印结果与操作人。

3.2 表结构设计

入库记录表 t_inbound_record

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
WaybillNo VARCHAR 64 - 是 运单号
Weight DECIMAL 10,2 - 否 实重(kg)
Length DECIMAL 10,2 - 否 长(cm)
Width DECIMAL 10,2 - 否 宽(cm)
Height DECIMAL 10,2 - 否 高(cm)
SalesProductId BIGINT - 外键 否 销售产品ID
DestinationCountry VARCHAR 8 - 否 目的国
WarehouseId BIGINT - 外键 否 仓库ID
OperateTime DATETIME - - 是 操作时间
OperatorId BIGINT - 外键 否 操作人ID
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

出库记录表 t_outbound_record

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
WaybillNo VARCHAR 64 - 是 运单号
WarehouseId BIGINT - 外键 否 仓库ID
OperateTime DATETIME - - 是 操作时间
OperatorId BIGINT - 外键 否 操作人ID
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

标签打印记录表 t_label_print_record

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
WaybillNo VARCHAR 64 - 是 运单号
CustomerOrderNo VARCHAR 64 - 否 客户单号
TrackingNo VARCHAR 64 - 否 跟踪号
OtherNumber VARCHAR 64 - 否 其他单号
LabelTemplateId BIGINT - 外键 否 标签模板ID
PrintSuccess TINYINT - - 是 是否打印成功
PrintTime DATETIME - - 是 打印时间
OperatorId BIGINT - 外键 否 操作人ID
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

3.3 核心接口设计

入库扫描

接口名称 请求方式 请求路径 说明
入库 POST /operation/inbound/create 入库
最近入库记录 GET /operation/inbound/recent-list 最近入库记录
入库(POST /operation/inbound/create)
1 接口请求示例

请求 /operation/inbound/create(POST)

{
  "waybillNo": "LP1234567890",
  "weight": 2.5,
  "length": 20,
  "width": 15,
  "height": 10,
  "salesProductId": 1,
  "destinationCountry": "US",
  "warehouseId": 1
}

参数说明:waybillNo 运单号;weight 实重(kg);length/width/height 长宽高(cm);salesProductId 销售产品ID;destinationCountry 目的国二字码;warehouseId 仓库ID。操作时间、操作人由服务端从当前会话获取。

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "waybillNo": "LP1234567890",
    "weight": 2.5,
    "length": 20,
    "width": 15,
    "height": 10,
    "salesProductId": 1,
    "destinationCountry": "US",
    "warehouseId": 1,
    "operateTime": "2024-01-01 12:00:00",
    "operatorId": 1,
    "createTime": "2024-01-01 12:00:00"
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
最近入库记录(GET /operation/inbound/recent-list)
1 接口请求示例

请求 /operation/inbound/recent-list(GET,Query 参数)

?limit=20&warehouseId=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "waybillNo": "LP1234567890",
        "weight": 2.5,
        "length": 20,
        "width": 15,
        "height": 10,
        "salesProductId": 1,
        "salesProductName": "美国空运专线(普货)",
        "destinationCountry": "US",
        "warehouseId": 1,
        "warehouseName": "深圳仓",
        "operateTime": "2024-01-01 12:00:00",
        "operatorId": 1,
        "operatorName": "张三",
        "createTime": "2024-01-01 12:00:00"
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。

出库扫描

接口名称 请求方式 请求路径 说明
出库 POST /operation/outbound/create 出库
最近出库记录 GET /operation/outbound/recent-list 最近出库记录
出库(POST /operation/outbound/create)
1 接口请求示例

请求 /operation/outbound/create(POST)

{
  "waybillNo": "LP1234567890",
  "warehouseId": 1
}

参数说明:waybillNo 运单号;warehouseId 仓库ID(可选,不传则从订单或默认仓库获取)。操作时间、操作人由服务端从当前会话获取。

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "waybillNo": "LP1234567890",
    "warehouseId": 1,
    "operateTime": "2024-01-01 12:00:00",
    "operatorId": 1,
    "createTime": "2024-01-01 12:00:00"
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
最近出库记录(GET /operation/outbound/recent-list)
1 接口请求示例

请求 /operation/outbound/recent-list(GET,Query 参数)

?limit=20&warehouseId=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "waybillNo": "LP1234567890",
        "warehouseId": 1,
        "warehouseName": "深圳仓",
        "operateTime": "2024-01-01 12:00:00",
        "operatorId": 1,
        "operatorName": "张三",
        "createTime": "2024-01-01 12:00:00"
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。

标签打印

接口名称 请求方式 请求路径 说明
打印标签 POST /operation/print-label/print 打印标签
最近打印记录 GET /operation/print-label/recent-list 最近打印记录
标签模板列表 GET /operation/print-label/template-list 标签模板列表
打印标签(POST /operation/print-label/print)
1 接口请求示例

请求 /operation/print-label/print(POST)

{
  "number": "LP1234567890",
  "numberType": "waybill",
  "labelTemplateId": 1
}

参数说明:number 运单号/客户单号/跟踪号/其他单号;numberType 单号类型:waybill(运单号)/customerOrder(客户单号)/tracking(跟踪号)/other(其他单号);labelTemplateId 标签模板ID,可选,不传则按 templateType 取默认模板。也可传 templateType:lastMile(尾程)/customer(客户)/inbound(入库)/outbound(出库)/sku。

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "waybillNo": "LP1234567890",
    "customerOrderNo": "",
    "trackingNo": "",
    "otherNumber": "",
    "labelTemplateId": 1,
    "labelTemplateName": "尾程标签模板1",
    "printSuccess": 1,
    "printTime": "2024-01-01 12:00:00",
    "operatorId": 1,
    "createTime": "2024-01-01 12:00:00"
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
最近打印记录(GET /operation/print-label/recent-list)
1 接口请求示例

请求 /operation/print-label/recent-list(GET,Query 参数)

?limit=20&labelTemplateId=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "waybillNo": "LP1234567890",
        "customerOrderNo": "CUST001",
        "trackingNo": "TRK001",
        "otherNumber": "",
        "labelTemplateId": 1,
        "labelTemplateName": "尾程标签模板1",
        "printSuccess": 1,
        "printTime": "2024-01-01 12:00:00",
        "operatorId": 1,
        "operatorName": "张三",
        "createTime": "2024-01-01 12:00:00"
      }
    ]
  }
}
2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。
标签模板列表(GET /operation/print-label/template-list)
1 接口请求示例

请求 /operation/print-label/template-list(GET,Query 参数)

?templateType=lastMile

参数说明:templateType 可选,筛选模板类型:lastMile/customer/inbound/outbound/sku。不传则返回全部可用模板。

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "name": "尾程标签模板1",
        "templateType": "lastMile",
        "templateJson": {},
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ]
  }
}


2 接口业务逻辑

####### 核心流程

  • 按接口定义执行业务流程,完成参数解析、数据处理与结果返回。

####### 校验与异常

  • 对必填参数、状态与数据存在性进行校验,异常场景返回统一错误码与错误信息。

五、客户模块

4.1 核心需求说明

  • 客户管理:客户信息的增删改查,支持客户编号、手机、邮箱、余额、额度、状态等管理;支持重置密码;已有 customer API。
  • 子账号:主客户可创建子账号,子账号共享主客户余额与额度,独立登录与权限。

4.2 表结构设计

客户表 t_customer

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
CustomerCode VARCHAR 32 - 是 客户编号,规则:前缀w+年份+序号(如W2501)
CustomerName VARCHAR 128 - 是 客户名称
WechatAvatar VARCHAR 255 - 否 微信头像URL
WechatNickname VARCHAR 64 - 否 微信昵称
Email VARCHAR 64 - 否 邮箱,唯一,用于登录/找回密码
Phone VARCHAR 16 - 是 手机号,唯一,用于登录/验证
Balance DECIMAL 18,2 - 是 账户余额,默认0
TotalQuota DECIMAL 18,2 - 是 总额度,默认0
UsedQuota DECIMAL 18,2 - 是 已用额度,默认0
Status TINYINT - - 是 状态:0-禁用,1-正常,2-冻结
Remark VARCHAR 512 - 否 备注信息
CreateUserId INT - - 是 创建人(系统/管理员账号)
CreateTime DATETIME - - 是 创建时间,默认当前时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间
Salesman VARCHAR 32 - 否 所属销售员账号
CustomerService VARCHAR 32 - 否 所属客服账号
CustomerGroup TINYINT - - 否 客户分组:0-普通客户,1-VIP1,2-VIP2,3-VIP3,4-VIP4,5-VIP5
Role VARCHAR 64 - 否 角色,用于菜单权限
LastLoginIp VARCHAR 64 - 否 最后在线IP
LastLoginTime DATETIME - - 否 最后在线时间
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
WechatOpenid VARCHAR 64 - 否 微信OpenID,唯一,关联微信账号
Password VARCHAR 64 - 是 密码(MD5加密存储)

CustomerGroup 枚举:0-普通客户、1-VIP1、2-VIP2、3-VIP3、4-VIP4、5-VIP5

子账号表 t_customer_sub_account

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
MainCustomerId BIGINT - 外键(t_customer.Id) 是 主客户ID
SubAccountCode VARCHAR 32 - 是 子账号编号,规则:主客户编号+"_"+序号
SubWechatAvatar VARCHAR 255 - 否 子账号微信头像
SubWechatNickname VARCHAR 64 - 否 子账号微信昵称
SubPhone VARCHAR 16 - 是 子账号手机号,唯一
SubEmail VARCHAR 64 - 否 子账号邮箱
SubPassword VARCHAR 64 - 是 子账号密码(MD5加密)
SubStatus TINYINT - - 是 子账号状态:0-禁用,1-正常
CreateUserId INT - - 是 创建人(主客户/管理员)
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间
IsDeleted TINYINT - - 是 是否删除:0-否,1-是

4.3 核心接口设计

接口名称 请求方式 请求路径 说明
客户列表 GET /customer/list 客户列表
客户详情 GET /customer/get 客户详情
创建客户 POST /customer/create 创建客户
更新客户 POST /customer/update 更新客户
删除客户 POST /customer/delete 删除客户
重置密码 POST /customer/reset-password 重置密码

个人中心可复用 /customer/get,传入当前登录客户 ID。

客户列表(GET /customer/list)
1 接口请求示例

请求 /customer/list(GET,Query 参数)

?page=1&pageSize=20&keyword=&status=1&customerGroup=&salesman=&customerService=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "customerCode": "W2501",
        "wechatAvatar": "",
        "wechatNickname": "",
        "email": "customer@example.com",
        "phone": "13800138000",
        "balance": 1000.00,
        "totalQuota": 5000.00,
        "usedQuota": 500.00,
        "status": 1,
        "remark": "",
        "salesman": "sales1",
        "customerService": "cs1",
        "customerGroup": 1,
        "lastLoginIp": "192.168.1.1",
        "lastLoginTime": "2024-01-01 12:00:00",
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 50
  }
}
2 接口业务逻辑

####### 核心流程

  • 根据筛选参数分页查询客户列表,返回客户基础信息、状态与余额额度信息。

####### 校验与异常

  • 校验分页参数合法性;当筛选条件无匹配数据时返回空列表与 total=0。
客户详情(GET /customer/get)
1 接口请求示例

请求 /customer/get(GET,Query 参数)

?id=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "customerCode": "W2501",
    "wechatAvatar": "",
    "wechatNickname": "",
    "email": "customer@example.com",
    "phone": "13800138000",
    "balance": 1000.00,
    "totalQuota": 5000.00,
    "usedQuota": 500.00,
    "status": 1,
    "remark": "",
    "salesman": "sales1",
    "customerService": "cs1",
    "customerGroup": 1,
    "lastLoginIp": "192.168.1.1",
    "lastLoginTime": "2024-01-01 12:00:00",
    "createTime": "2024-01-01 12:00:00",
    "createBy": "admin",
    "updateTime": "2024-01-01 12:00:00",
    "updateBy": "admin"
  }
}
2 接口业务逻辑

####### 核心流程

  • 按客户 ID 查询客户详情,返回完整客户资料与审计字段。

####### 校验与异常

  • 校验 id 必填且存在;不存在时返回业务错误码。
创建客户(POST /customer/create)
1 接口请求示例

请求 /customer/create(POST)

{
  "customerCode": "W2501",
  "customerName": "张三客户",
  "wechatAvatar": "https://cdn.example.com/avatar/w2501.png",
  "wechatNickname": "张三",
  "phone": "13800138000",
  "email": "customer@example.com",
  "password": "123456",
  "balance": 1000.00,
  "totalQuota": 5000.00,
  "usedQuota": 500.00,
  "status": 1,
  "role": "customer",
  "remark": "",
  "salesman": "sales1",
  "customerService": "cs1",
  "customerGroup": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增客户账号并写入客户基础资料(客户编号/名称、微信信息、联系方式)、余额额度、角色与业务归属信息。

####### 校验与异常

  • 校验手机号/邮箱唯一性与必填字段,冲突时返回业务错误。
更新客户(POST /customer/update)
1 接口请求示例

请求 /customer/update(POST)

{
  "id": 1,
  "customerCode": "W2501",
  "customerName": "张三客户",
  "wechatAvatar": "https://cdn.example.com/avatar/w2501.png",
  "wechatNickname": "张三",
  "phone": "13800138000",
  "email": "customer@example.com",
  "balance": 1000.00,
  "totalQuota": 5000.00,
  "usedQuota": 500.00,
  "status": 1,
  "role": "customer",
  "remark": "",
  "salesman": "sales1",
  "customerService": "cs1",
  "customerGroup": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据客户 ID 更新客户资料(编号/名称、微信信息、联系方式)、余额额度、状态、角色与业务归属字段。

####### 校验与异常

  • 校验 id 存在与可更新状态;非法状态流转时返回业务错误。
删除客户(POST /customer/delete)
1 接口请求示例

请求 /customer/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按客户 ID 执行逻辑删除,保留历史审计数据。

####### 校验与异常

  • 校验 id 存在且可删除;存在关联数据限制时返回业务错误。
重置密码(POST /customer/reset-password)
1 接口请求示例

请求 /customer/reset-password(POST)

{
  "id": 1,
  "newPassword": "123456"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据客户 ID 重置登录密码并更新密码变更时间。

####### 校验与异常

  • 校验 id 与 newPassword 合法性,不满足密码策略时返回业务错误。


六、充值管理

5.1 核心需求说明

  • 充值流程:客户提交充值金额 → 选择支付方式(微信/支付宝)→ 上传充值截图 → 提交审核 → 管理员审核(通过/驳回)→ 审核通过后更新客户余额。
  • 充值记录:完整留存充值全流程信息,支持查询、导出;充值状态包含:待审核、审核通过、审核驳回。

5.2 表结构设计

充值记录表 t_recharge_record

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
CustomerId BIGINT - 外键(t_customer.Id) 是 客户ID(主账号/子账号关联主账号ID)
SerialNumber VARCHAR 64 - 是 流水号,规则:RECHARGE+日期+随机6位数字
RechargeTime DATETIME - - 是 充值提交时间,默认当前时间
PayType TINYINT - - 是 支付方式:1-微信,2-支付宝
RechargeAmount DECIMAL 18,2 - 是 充值金额,≥0.01
RechargeScreenshot VARCHAR 255 - 否 充值截图URL(存储文件服务器地址)
RechargeStatus TINYINT - - 是 充值状态:0-待审核,1-审核通过,2-审核驳回
Remark VARCHAR 512 - 否 备注(客户/审核人填写)
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间
AuditTime DATETIME - - 否 审核时间
AuditBy VARCHAR 32 - 否 审核人(管理员账号)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0

5.3 核心接口设计

接口名称 请求方式 请求路径 请求参数 响应参数 接口说明
提交充值申请 POST /recharge/recharge/submit customerId, payType, rechargeAmount, screenshotUrl, remark code, msg, data.serialNumber 生成流水号,保存充值记录,状态为待审核
审核充值申请 POST /recharge/recharge-record/approve 或 reject id, auditStatus, auditBy, remark code, msg 审核通过则更新客户余额,更新审核时间、状态、审核人
查询充值记录 GET /recharge/recharge-record/list customerId, serialNumber, startTime, endTime, status list, total 多条件分页查询充值记录
导出充值记录 GET /recharge/export customerId, startTime, endTime 文件流 导出充值记录为Excel文件
提交充值申请(POST /recharge/recharge/submit)
1 接口请求示例

请求 /recharge/recharge/submit(POST)

{
  "customerId": 1,
  "rechargeAmount": 500,
  "payType": 1,
  "rechargeScreenshot": "https://example.com/upload/screenshot.jpg",
  "remark": "充值500元"
}

参数说明:customerId 客户ID(客户端提交时可不传,取当前登录客户);rechargeAmount 充值金额,≥0.01;payType 支付方式:1-微信,2-支付宝;rechargeScreenshot 充值截图URL;remark 备注。

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "serialNumber": "RECHARGE2024010100123456",
    "customerId": 1,
    "rechargeAmount": 500.00,
    "payType": 1,
    "rechargeScreenshot": "https://example.com/upload/screenshot.jpg",
    "rechargeStatus": 0,
    "remark": "充值500元",
    "rechargeTime": "2024-01-01 12:00:00",
    "createTime": "2024-01-01 12:00:00"
  }
}
2 接口业务逻辑

####### 核心流程

  • 创建充值记录并生成流水号,初始状态为待审核。

####### 校验与异常

  • 校验金额、支付方式与截图信息合法性,不合法时返回业务错误。
审核充值申请-通过(POST /recharge/recharge-record/approve)
1 接口请求示例

请求 /recharge/recharge-record/approve(POST)

{
  "id": 1,
  "remark": "审核通过"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 审核通过后更新充值状态与审核信息,并增加客户余额。

####### 校验与异常

  • 校验记录状态必须为待审核;重复审核或状态冲突时返回业务错误。
审核充值申请-驳回(POST /recharge/recharge-record/reject)
1 接口请求示例

请求 /recharge/recharge-record/reject(POST)

{
  "id": 1,
  "remark": "截图不清晰,请重新上传"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 审核驳回后更新充值状态与审核备注,不变更客户余额。

####### 校验与异常

  • 校验记录状态与审核权限,非法操作时返回业务错误。
查询充值记录(GET /recharge/recharge-record/list)
1 接口请求示例

请求 /recharge/recharge-record/list(GET,Query 参数)

?page=1&pageSize=20&customerId=1&serialNumber=&rechargeStatus=0&startTime=2024-01-01&endTime=2024-01-31

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "customerId": 1,
        "customerCode": "W2501",
        "customerPhone": "13800138000",
        "serialNumber": "RECHARGE2024010100123456",
        "rechargeTime": "2024-01-01 12:00:00",
        "payType": 1,
        "payTypeName": "微信",
        "rechargeAmount": 500.00,
        "rechargeScreenshot": "https://example.com/upload/screenshot.jpg",
        "rechargeStatus": 0,
        "rechargeStatusName": "待审核",
        "remark": "充值500元",
        "auditTime": null,
        "auditBy": null,
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 20
  }
}
2 接口业务逻辑

####### 核心流程

  • 按客户、流水号、状态和时间区间进行分页查询,返回记录列表与总数。

####### 校验与异常

  • 校验时间区间与分页参数合法性,查询异常时返回统一错误码。
导出充值记录(GET /recharge/export)
1 接口请求示例

请求 /recharge/export(GET,Query 参数)

?customerId=1&startTime=2024-01-01&endTime=2024-01-31

响应

返回 Excel 文件流,Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

2 接口业务逻辑

####### 核心流程

  • 根据筛选条件导出充值记录为 Excel 文件流。

####### 校验与异常

  • 校验导出条件与数据权限,导出失败时返回统一错误信息。


七、系统模块

6.1 核心需求说明

  • 仓库地址:管理仓库收货地址信息,包括主仓/中转仓/退货仓/其他类型;支持收件人、联系电话、收货地址、客服电话、客服微信及二维码等配置。
  • 国家管理:维护国家基础资料(中文名称、英文名称、二字代码),供渠道分区、下单地址等模块复用。
  • 字典管理:维护系统字典项,支持按字典类型分组管理字典编码、名称和排序,供下拉选项、状态映射等场景统一复用。
  • 统一认证:新增认证账号层,统一登录接口,兼容内部用户(user)与客户(t_customer)两类主体登录。

6.2 表结构设计

统一认证账号表 t_auth_account

字段名 字段类型 长度 主键/外键 非空 说明
Id VARCHAR 36 主键 是 GUID 主键
LoginName VARCHAR 64 - 是 登录名(账号/手机号/邮箱,唯一)
PasswordHash VARCHAR 256 - 是 密码哈希
PasswordSalt VARCHAR 128 - 是 密码盐值
PrincipalType VARCHAR 16 - 是 主体类型:user/customer
PrincipalId VARCHAR 64 - 是 主体ID(关联 user.Id 或 t_customer.Id)
Status TINYINT - - 是 状态:0-禁用,1-启用
LastLoginTime DATETIME - - 否 最后登录时间
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

用户表 user

字段名 字段类型 长度 主键/外键 非空 说明
Id CHAR 36 主键 是 GUID 主键
Name VARCHAR 32 - 是 用户姓名
Account VARCHAR 32 - 是 登录账号(唯一)
EncryptPassword_Password LONGTEXT - - 是 加密后的密码
EncryptPassword_Salt LONGTEXT - - 是 密码盐值
Email VARCHAR 32 - 否 邮箱(唯一)
Avatar VARCHAR 128 - 否 头像地址
ConcurrencyStamp CHAR 36 - 是 并发戳(GUID)
CreateUserId CHAR 36 - 是 创建人
CreateTime DATETIME(6) - - 是 创建时间
UpdateUserId CHAR 36 - 是 更新人
UpdateTime DATETIME(6) - - 是 更新时间
IsDeleted TINYINT(1) - - 是 是否删除:0-否,1-是,默认0
OrganizationId CHAR 36 - 否 所属组织ID
UserId INT - - 是 自增映射ID(user id for map)

用户角色关联表 user_role

字段名 字段类型 长度 主键/外键 非空 说明
Id CHAR 36 主键 是 GUID 主键
UserId CHAR 36 外键(关联 user.Id) 是 用户ID
RoleId CHAR 36 - 是 角色ID
CreateUserId CHAR 36 - 是 创建人
CreateTime DATETIME - - 是 创建时间

角色表 role

字段名 字段类型 长度 主键/外键 非空 说明
Id CHAR 36 主键 是 GUID 主键
Name VARCHAR 32 - 是 角色名称
Code VARCHAR 32 - 是 角色编码(唯一)
ConcurrencyStamp CHAR 36 - 是 并发戳(GUID)
CreateUserId CHAR 36 - 是 创建人
CreateTime DATETIME(6) - - 是 创建时间
UpdateUserId CHAR 36 - 是 更新人
UpdateTime DATETIME(6) - - 是 更新时间
IsDeleted TINYINT(1) - - 是 是否删除:0-否,1-是,默认0

角色权限关联表 role_permission

字段名 字段类型 长度 主键/外键 非空 说明
Id CHAR 36 主键 是 GUID 主键
RoleId CHAR 36 外键(关联 role.Id) 是 角色ID
PermissionCode VARCHAR 255 - 是 权限编码
CreateUserId CHAR 36 - 是 创建人
CreateTime DATETIME(6) - - 是 创建时间

组织表 organization

字段名 字段类型 长度 主键/外键 非空 说明
Id CHAR 36 主键 是 GUID 主键
ParentId CHAR 36 - 否 父级组织ID
Name VARCHAR 128 - 是 组织名称
Code VARCHAR 64 - 是 组织编码(唯一)
Type VARCHAR 32 - 是 组织类型
LeaderId CHAR 36 - 否 负责人用户ID
Order INT - - 是 排序
Description VARCHAR 512 - 否 描述
IsEnabled TINYINT(1) - - 是 是否启用:0-否,1-是
ConcurrencyStamp CHAR 36 - 是 并发戳(GUID)
CreateUserId CHAR 36 - 是 创建人
CreateTime DATETIME(6) - - 是 创建时间
UpdateUserId CHAR 36 - 是 更新人
UpdateTime DATETIME(6) - - 是 更新时间
IsDeleted TINYINT(1) - - 是 是否删除:0-否,1-是,默认0

菜单表 menu

字段名 字段类型 长度 主键/外键 非空 说明
Id CHAR 36 主键 是 GUID 主键
PId CHAR 36 - 是 父级菜单ID
Name VARCHAR 64 - 是 菜单名称
PermissionCode VARCHAR 64 - 是 权限编码(唯一)
Type INT - - 是 菜单类型
Icon VARCHAR 64 - 否 图标
Route VARCHAR 64 - 否 路由地址
Component VARCHAR 64 - 否 组件路径
Order INT - - 是 排序
IsHidden TINYINT(1) - - 是 是否隐藏:0-否,1-是
IsCached TINYINT(1) - - 是 是否缓存:0-否,1-是
Description VARCHAR 256 - 否 描述
ConcurrencyStamp CHAR 36 - 是 并发戳(GUID)
CreateUserId CHAR 36 - 是 创建人
CreateTime DATETIME(6) - - 是 创建时间
UpdateUserId CHAR 36 - 是 更新人
UpdateTime DATETIME(6) - - 是 更新时间
IsDeleted TINYINT(1) - - 是 是否删除:0-否,1-是,默认0

国家表 t_country

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
ChineseName VARCHAR 128 - 是 中文名称
EnglishName VARCHAR 128 - 是 英文名称
CountryCode VARCHAR 2 - 是 国家二字代码(ISO 3166-1 alpha-2)
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

字典表 t_dict

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
DictType VARCHAR 64 - 是 字典类型(如 notice_type、warehouse_type)
DictSort INT - - 是 字典排序,值越小越靠前
DictCode VARCHAR 64 - 是 字典编码(同类型下唯一)
DictName VARCHAR 128 - 是 字典名称
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

公告通知表 t_notice

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
NoticeType VARCHAR 16 - 是 通知类型:notice-公告,message-站内信
Title VARCHAR 200 - 是 标题
Content TEXT - - 是 内容
IsPopup TINYINT - - 是 是否弹窗:0-否,1-是
ReceiverType VARCHAR 16 - 是 接收对象:user-用户,customer-客户
ReceiverIds JSON - - 是 接收人 ID 列表
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

通知已读明细表 t_notice_read

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
NoticeId BIGINT - 外键(关联 t_notice.Id) 是 通知 ID
ReceiverType VARCHAR 16 - 是 接收对象:user-用户,customer-客户
ReceiverId BIGINT - - 是 已读主体 ID(用户 ID/客户 ID)
ReadTime DATETIME - - 是 已读时间
CreateTime DATETIME - - 是 创建时间

仓库地址表 t_warehouse_address

字段名 字段类型 长度 主键/外键 非空 说明
Id BIGINT - 主键 是 自增唯一标识
WarehouseName VARCHAR 128 - 是 仓库名称
WarehouseType VARCHAR 32 - 是 main/transit/return/other
Recipient VARCHAR 64 - 否 收件人
ContactPhone VARCHAR 32 - 否 联系电话
ShippingAddress TEXT - - 否 收货地址
ServicePhone VARCHAR 32 - 否 客服电话
ServiceWechat VARCHAR 64 - 否 客服微信
ServiceWechatFiles JSON - - 否 微信二维码图片
IsDeleted TINYINT - - 是 是否删除:0-否,1-是,默认0
CreateUserId INT - - 是 创建人
CreateTime DATETIME - - 是 创建时间
UpdateUserId INT - - 否 更新人
UpdateTime DATETIME - - 否 更新时间

6.3 核心接口设计

接口名称 请求方式 请求路径 说明
统一登录 POST /auth/login 统一账号登录(user/customer)
刷新令牌 POST /auth/refresh 刷新访问令牌
退出登录 POST /auth/logout 当前会话退出
当前主体信息 GET /auth/profile 获取当前登录主体及权限摘要
国家列表 GET /system/country/list 查询国家列表
字典列表 GET /system/dict/list 按类型分页查询字典
新增字典 POST /system/dict/create 新增字典项
更新字典 POST /system/dict/update 更新字典项
删除字典 POST /system/dict/delete 删除字典项
仓库列表 GET /system/warehouse/list 仓库列表
仓库详情 GET /system/warehouse/detail 仓库详情
新增仓库 POST /system/warehouse/create 新增
更新仓库 POST /system/warehouse/update 更新
删除仓库 POST /system/warehouse/delete 删除
通知列表 GET /system/notice/list 分页查询通知
新增通知 POST /system/notice/create 新增公告/站内信
编辑通知 POST /system/notice/update 编辑公告/站内信
删除通知 POST /system/notice/delete 删除公告/站内信
确认已读 POST /system/notice/read-confirm 当前用户/客户确认已读

6.4 统一认证与鉴权约定

  • 登录时先校验 t_auth_account,再通过 PrincipalType + PrincipalId 加载业务主体(user/t_customer)。
  • 令牌建议统一包含:sub(认证账号ID)、principal_type、principal_id、org_id(客户可空)、roles/scopes。
  • 管理后台接口默认要求 principal_type=user;客户中心接口默认要求 principal_type=customer。
  • user 继续沿用成熟 RBAC(GUID 体系);customer 固定授予角色编码 Customer,直接复用 role_permission + menu 控制菜单与权限。
  • 当 principal_type=customer 时,服务端统一覆盖角色集合为 ["Customer"]。
  • 客户侧接口必须附加数据隔离条件(如 CustomerId = principal_id),防止跨客户越权访问。

6.5 RBAC Swagger 接口清单(下载)

来源:https://api.nanafa.com/admin/index.html?urls.primaryName=RBAC

实际文档地址:/admin/swagger/RBAC/swagger.json(共 48 个接口)

6.5.1 认证(Auth)

接口名称 请求方式 请求路径 说明
登录 POST /rbac/auth/login 用户登录
刷新令牌 POST /rbac/auth/refresh-token 刷新 token
修改密码 POST /rbac/auth/change-password 当前用户改密
更新资料 PUT /rbac/auth/update-profile 更新当前用户资料
上传头像 POST /rbac/auth/upload-avatar 上传当前用户头像
当前用户信息 GET /rbac/auth/get-current-user 获取当前登录用户

6.5.2 用户(User)

接口名称 请求方式 请求路径 说明
用户列表 GET /rbac/user/get-list 分页查询用户
用户详情 GET /rbac/user/get 查询用户详情
创建用户 POST /rbac/user/create 新增用户
更新用户 PUT /rbac/user/update 编辑用户
删除用户 DELETE /rbac/user/delete 删除单个用户
批量删除用户 DELETE /rbac/user/delete-batch 批量删除用户
分配角色 POST /rbac/user/assign-roles 给用户分配角色
用户角色 GET /rbac/user/get-user-roles 查询用户角色
用户权限 GET /rbac/user/get-user-permissions 查询用户权限
角色下用户 GET /rbac/user/get-users-by-role 查询某角色下用户
更新用户头像 PUT /rbac/user/update-avatar 更新用户头像
更新用户密码 PUT /rbac/user/update-password 重置/修改用户密码
权限判断 POST /rbac/user/has-permission 判断用户是否具备某权限

6.5.3 角色(Role)

接口名称 请求方式 请求路径 说明
角色列表 GET /rbac/role/get-list 分页查询角色
全部角色 GET /rbac/role/get-all-roles 查询全部角色
角色详情 GET /rbac/role/get 查询角色详情
创建角色 POST /rbac/role/create 新增角色
更新角色 PUT /rbac/role/update 编辑角色
删除角色 DELETE /rbac/role/delete 删除角色
分配权限 POST /rbac/role/assign-permissions 给角色分配权限
角色权限 GET /rbac/role/get-role-permissions 查询角色权限
角色用户数 GET /rbac/role/get-role-user-count 查询角色下用户数
角色用户列表 GET /rbac/role/get-role-users 查询角色下用户列表

6.5.4 权限(Permission)

接口名称 请求方式 请求路径 说明
全量权限 GET /rbac/permission/get-all-permissions 查询全部权限编码
权限树 GET /rbac/permission/get-permission-tree 查询权限树
单权限校验 POST /rbac/permission/check-permission 校验单个权限
多权限校验 POST /rbac/permission/check-permissions 批量校验权限

6.5.5 组织(Organization)

接口名称 请求方式 请求路径 说明
组织列表 GET /rbac/organization/get-list 分页查询组织
组织树 GET /rbac/organization/get-tree 查询组织树
组织详情 GET /rbac/organization/get 查询组织详情
创建组织 POST /rbac/organization/create 新增组织
更新组织 PUT /rbac/organization/update 编辑组织
删除组织 DELETE /rbac/organization/delete 删除组织
移动组织 POST /rbac/organization/move 调整组织节点位置

6.5.6 菜单(Menu)

接口名称 请求方式 请求路径 说明
菜单详情 GET /rbac/menu/get 查询菜单详情
菜单树 GET /rbac/menu/get-menu-tree 查询菜单树
用户菜单 GET /rbac/menu/get-user-menus 查询当前用户可见菜单
创建菜单 POST /rbac/menu/create 新增菜单
更新菜单 PUT /rbac/menu/update 编辑菜单
删除菜单 DELETE /rbac/menu/delete 删除菜单
移动菜单 POST /rbac/menu/move-menu 移动菜单节点
更新菜单排序 PUT /rbac/menu/update-order 更新菜单排序

6.6 RBAC 接口详细设计(按统一结构)

来源:https://api.nanafa.com/admin/index.html?urls.primaryName=RBAC
本节先按现有文档结构落地 Auth 分组,User/Role/Organization/Menu/Permission 分组按同模板继续追加。

登录(POST /rbac/auth/login)
1 接口请求示例

请求 /rbac/auth/login(POST,Query 参数)

?account=admin&password=123456&type=0

响应

{
  "accessToken": "eyJhbGciOi...",
  "refreshToken": "d35f3d87-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tokenType": "Bearer",
  "expiresIn": 7200,
  "userId": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
2 接口业务逻辑

####### 核心流程

  • 根据 account + password + type 鉴权,登录成功后签发 accessToken 与 refreshToken。
  • 返回 LoginResultDto:accessToken、refreshToken、tokenType、expiresIn、userId。

####### 校验与异常

  • 校验账号、密码必填;type 默认 0。
  • 鉴权失败或用户状态异常时返回 ApplicationExceptionResult(400)。
  • 当 type=1(客户)登录成功时,服务端固定返回角色 Customer 对应的权限与菜单集合。
刷新令牌(POST /rbac/auth/refresh-token)
1 接口请求示例

请求 /rbac/auth/refresh-token(POST,Query 参数)

?refreshToken=d35f3d87-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "accessToken": "eyJhbGciOi...",
  "refreshToken": "2f83baf2-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tokenType": "Bearer",
  "expiresIn": 7200,
  "userId": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
2 接口业务逻辑

####### 核心流程

  • 校验 refreshToken 有效性,生成并返回新令牌对。

####### 校验与异常

  • refreshToken 无效、过期或被吊销时返回 ApplicationExceptionResult(400)。
修改密码(POST /rbac/auth/change-password)
1 接口请求示例

请求 /rbac/auth/change-password(POST,Query 参数)

?oldPassword=old123&newPassword=new123456

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 使用当前登录主体校验旧密码,成功后更新为新密码。

####### 校验与异常

  • 旧密码错误、密码策略不满足或主体不存在时返回 ApplicationExceptionResult(400)。
更新资料(PUT /rbac/auth/update-profile)
1 接口请求示例

请求 /rbac/auth/update-profile(PUT,Query 参数)

?name=管理员A&email=admin@example.com

响应

{
  "id": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "管理员A",
  "account": "admin",
  "email": "admin@example.com",
  "avatar": "https://cdn.example.com/avatar/admin.png",
  "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "organizationName": "总部",
  "roles": [
    "Admin"
  ],
  "permissions": [
    "rbac:user:get-list"
  ],
  "menus": []
}
2 接口业务逻辑

####### 核心流程

  • 更新当前登录用户的基础资料(姓名、邮箱),返回最新 UserInfoDto。

####### 校验与异常

  • 邮箱格式非法或与现有账号冲突时返回 ApplicationExceptionResult(400)。
上传头像(POST /rbac/auth/upload-avatar)
1 接口请求示例

请求 /rbac/auth/upload-avatar(POST,Body)

"<binary-or-formdata-file>"

响应

"https://cdn.example.com/avatar/20260430/a1b2c3.png"
2 接口业务逻辑

####### 核心流程

  • 接收头像文件并上传文件存储,返回头像 URL(字符串)。

####### 校验与异常

  • 文件为空、类型不合法或上传失败时返回 ApplicationExceptionResult(400)。
当前用户信息(GET /rbac/auth/get-current-user)
1 接口请求示例

请求 /rbac/auth/get-current-user(GET)

无请求参数,基于当前登录令牌解析用户身份。

响应

{
  "id": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "管理员A",
  "account": "admin",
  "email": "admin@example.com",
  "avatar": "https://cdn.example.com/avatar/admin.png",
  "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "organizationName": "总部",
  "roles": [
    "Admin"
  ],
  "permissions": [
    "rbac:user:get-list",
    "rbac:role:get-list"
  ],
  "menus": []
}
2 接口业务逻辑

####### 核心流程

  • 根据 token 解析用户,聚合返回用户基础信息、角色、权限与菜单。

####### 校验与异常

  • token 无效、用户不存在或已禁用时返回 ApplicationExceptionResult(400)。
  • 当当前主体为客户(principal_type=customer)时,roles 固定为 ["Customer"],菜单与权限按该角色返回。

6.6.1 用户(User)

用户列表(GET /rbac/user/get-list)
1 接口请求示例

请求 /rbac/user/get-list(GET,Query 参数)

?Keyword=admin&RoleId=&OrganizationId=&Page=1&PageSize=20&OrderBy=CreateTime&Descending=true

响应

{
  "total": 1,
  "items": [
    {
      "id": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "name": "管理员A",
      "account": "admin",
      "email": "admin@example.com",
      "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "organizationName": "总部",
      "roles": [
        "Admin"
      ]
    }
  ]
}
2 接口业务逻辑

####### 核心流程

  • 按关键字、角色、组织与分页参数查询用户,返回 UserDtoPagedResultDto。 ####### 校验与异常
  • 分页参数非法或排序字段不支持时返回 ApplicationExceptionResult(400)。
用户详情(GET /rbac/user/get)
1 接口请求示例

请求 /rbac/user/get(GET,Query 参数)

?id=8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "id": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "管理员A",
  "account": "admin",
  "email": "admin@example.com",
  "avatar": "https://cdn.example.com/avatar/admin.png",
  "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "organizationName": "总部",
  "roles": [
    "Admin"
  ]
}
2 接口业务逻辑

####### 核心流程

  • 根据用户 ID 查询并返回 UserDto。 ####### 校验与异常
  • id 不存在或已删除返回 ApplicationExceptionResult(400)。
创建用户(POST /rbac/user/create)
1 接口请求示例

请求 /rbac/user/create(POST,Body)

{
  "name": "测试用户",
  "account": "test001",
  "password": "123456",
  "email": "test001@example.com",
  "avatar": "",
  "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "roleIds": [
    "f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  ]
}

响应

{
  "id": "c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "测试用户",
  "account": "test001",
  "email": "test001@example.com",
  "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "organizationName": "总部",
  "roles": [
    "Operator"
  ]
}
2 接口业务逻辑

####### 核心流程

  • 创建用户账号并关联组织、角色,返回 UserDto。 ####### 校验与异常
  • account/email 重复、组织不存在、角色无效时返回 ApplicationExceptionResult(400)。
更新用户(PUT /rbac/user/update)
1 接口请求示例

请求 /rbac/user/update(PUT,Query + Body)

?id=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
  "name": "测试用户A",
  "email": "test001a@example.com",
  "avatar": "https://cdn.example.com/avatar/test001.png",
  "organizationId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

响应

{
  "id": "c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "测试用户A",
  "account": "test001",
  "email": "test001a@example.com"
}
2 接口业务逻辑

####### 核心流程

  • 按 id 更新用户基础信息,返回更新后 UserDto。 ####### 校验与异常
  • 用户不存在、邮箱冲突或组织非法时返回 ApplicationExceptionResult(400)。
删除用户(DELETE /rbac/user/delete)
1 接口请求示例

请求 /rbac/user/delete(DELETE,Query 参数)

?id=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 逻辑删除指定用户及其关联关系。 ####### 校验与异常
  • 用户不存在、不可删除主体(如内置管理员)返回 ApplicationExceptionResult(400)。
批量删除用户(DELETE /rbac/user/delete-batch)
1 接口请求示例

请求 /rbac/user/delete-batch(DELETE,Query 参数)

?ids=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx,ae9f2c10-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 批量逻辑删除用户。 ####### 校验与异常
  • 任一 ID 无效或存在不可删除用户时返回 ApplicationExceptionResult(400)。
分配角色(POST /rbac/user/assign-roles)
1 接口请求示例

请求 /rbac/user/assign-roles(POST,Query + Body)

?userId=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[
  "f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 覆盖式更新用户角色关联(user_role)。 ####### 校验与异常
  • 用户不存在、角色 ID 非法时返回 ApplicationExceptionResult(400)。
用户角色(GET /rbac/user/get-user-roles)
1 接口请求示例

请求 /rbac/user/get-user-roles(GET,Query 参数)

?userId=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

[
  {
    "id": "f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "管理员",
    "code": "Admin"
  }
]
2 接口业务逻辑

####### 核心流程

  • 查询指定用户角色列表。 ####### 校验与异常
  • 用户不存在时返回 ApplicationExceptionResult(400)。
用户权限(GET /rbac/user/get-user-permissions)
1 接口请求示例

请求 /rbac/user/get-user-permissions(GET,Query 参数)

?userId=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

[
  "rbac:user:get-list",
  "rbac:role:get-list"
]
2 接口业务逻辑

####### 核心流程

  • 聚合用户全部权限编码并返回。 ####### 校验与异常
  • 用户不存在或状态异常时返回 ApplicationExceptionResult(400)。
角色下用户(GET /rbac/user/get-users-by-role)
1 接口请求示例

请求 /rbac/user/get-users-by-role(GET,Query 参数)

?roleId=f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

[
  {
    "id": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "管理员A",
    "account": "admin"
  }
]
2 接口业务逻辑

####### 核心流程

  • 查询某角色下的用户列表。 ####### 校验与异常
  • 角色不存在时返回 ApplicationExceptionResult(400)。
更新用户头像(PUT /rbac/user/update-avatar)
1 接口请求示例

请求 /rbac/user/update-avatar(PUT,Query 参数)

?id=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx&avatarUrl=https://cdn.example.com/avatar/test001.png

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 更新指定用户头像地址。 ####### 校验与异常
  • 用户不存在或头像地址非法时返回 ApplicationExceptionResult(400)。
更新用户密码(PUT /rbac/user/update-password)
1 接口请求示例

请求 /rbac/user/update-password(PUT,Query + Body)

?id=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
  "oldPassword": "123456",
  "newPassword": "new123456"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 按用户 ID 更新密码。 ####### 校验与异常
  • 原密码错误、密码策略不满足时返回 ApplicationExceptionResult(400)。
权限判断(POST /rbac/user/has-permission)
1 接口请求示例

请求 /rbac/user/has-permission(POST,Query 参数)

?userId=c2a1d3e4-xxxx-xxxx-xxxx-xxxxxxxxxxxx&permissionCode=rbac:user:get-list

响应

true
2 接口业务逻辑

####### 核心流程

  • 判断用户是否具备指定权限编码。 ####### 校验与异常
  • 参数缺失或用户不存在时返回 ApplicationExceptionResult(400)。

6.6.2 角色(Role)

角色列表(GET /rbac/role/get-list)
1 接口请求示例

请求 /rbac/role/get-list(GET,Query 参数)

?Keyword=admin&Page=1&PageSize=20&OrderBy=CreateTime&Descending=true

响应

{
  "total": 1,
  "items": [
    {
      "id": "f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "name": "管理员",
      "code": "Admin",
      "permissions": [
        "rbac:user:get-list"
      ]
    }
  ]
}
2 接口业务逻辑

####### 核心流程

  • 分页查询角色并返回 RoleDtoPagedResultDto。 ####### 校验与异常
  • 分页参数非法时返回 ApplicationExceptionResult(400)。
全部角色(GET /rbac/role/get-all-roles)
1 接口请求示例

请求 /rbac/role/get-all-roles(GET)

无请求参数。 响应

[
  {
    "id": "f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "管理员",
    "code": "Admin"
  }
]
2 接口业务逻辑

####### 核心流程

  • 返回全部可用角色列表。 ####### 校验与异常
  • 查询异常返回 ApplicationExceptionResult(400)。
角色详情(GET /rbac/role/get)
1 接口请求示例

请求 /rbac/role/get(GET,Query 参数)

?id=f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "id": "f8d31e2c-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "管理员",
  "code": "Admin",
  "permissions": [
    "rbac:user:get-list"
  ]
}
2 接口业务逻辑

####### 核心流程

  • 根据角色 ID 返回 RoleDto。 ####### 校验与异常
  • 角色不存在时返回 ApplicationExceptionResult(400)。
创建角色(POST /rbac/role/create)
1 接口请求示例

请求 /rbac/role/create(POST,Body)

{
  "name": "运营",
  "code": "Operator",
  "permissions": [
    "rbac:user:get-list",
    "rbac:order:get-list"
  ]
}

响应

{
  "id": "6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "运营",
  "code": "Operator",
  "permissions": [
    "rbac:user:get-list",
    "rbac:order:get-list"
  ]
}
2 接口业务逻辑

####### 核心流程

  • 创建角色并初始化权限集。 ####### 校验与异常
  • code 重复或权限编码非法时返回 ApplicationExceptionResult(400)。
更新角色(PUT /rbac/role/update)
1 接口请求示例

请求 /rbac/role/update(PUT,Query + Body)

?id=6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
  "name": "运营A"
}

响应

{
  "id": "6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "运营A",
  "code": "Operator"
}
2 接口业务逻辑

####### 核心流程

  • 更新角色名称并返回 RoleDto。 ####### 校验与异常
  • 角色不存在时返回 ApplicationExceptionResult(400)。
删除角色(DELETE /rbac/role/delete)
1 接口请求示例

请求 /rbac/role/delete(DELETE,Query 参数)

?id=6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 删除角色及其关联权限关系。 ####### 校验与异常
  • 角色被使用且不允许删除时返回 ApplicationExceptionResult(400)。
分配权限(POST /rbac/role/assign-permissions)
1 接口请求示例

请求 /rbac/role/assign-permissions(POST,Query + Body)

?roleId=6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[
  "rbac:user:get-list",
  "rbac:role:get-list"
]

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 覆盖更新角色权限(role_permission)。 ####### 校验与异常
  • 角色不存在、权限编码非法时返回 ApplicationExceptionResult(400)。
角色权限(GET /rbac/role/get-role-permissions)
1 接口请求示例

请求 /rbac/role/get-role-permissions(GET,Query 参数)

?roleId=6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

[
  "rbac:user:get-list",
  "rbac:role:get-list"
]
2 接口业务逻辑

####### 核心流程

  • 查询角色已授权权限编码列表。 ####### 校验与异常
  • 角色不存在时返回 ApplicationExceptionResult(400)。
角色用户数(GET /rbac/role/get-role-user-count)
1 接口请求示例

请求 /rbac/role/get-role-user-count(GET,Query 参数)

?roleId=6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

12
2 接口业务逻辑

####### 核心流程

  • 统计角色下用户数。 ####### 校验与异常
  • 角色不存在时返回 ApplicationExceptionResult(400)。
角色用户列表(GET /rbac/role/get-role-users)
1 接口请求示例

请求 /rbac/role/get-role-users(GET,Query 参数)

?roleId=6d4a7b9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

[
  {
    "id": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "管理员A",
    "account": "admin"
  }
]
2 接口业务逻辑

####### 核心流程

  • 返回角色下用户集合。 ####### 校验与异常
  • 角色不存在时返回 ApplicationExceptionResult(400)。

6.6.3 组织(Organization)

组织列表(GET /rbac/organization/get-list)
1 接口请求示例

请求 /rbac/organization/get-list(GET)

无请求参数。 响应

[
  {
    "id": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "parentId": null,
    "name": "总部",
    "code": "HQ",
    "type": "Company",
    "order": 1,
    "isEnabled": true
  }
]
2 接口业务逻辑

####### 核心流程

  • 查询组织平铺列表。 ####### 校验与异常
  • 查询异常返回 ApplicationExceptionResult(400)。
组织树(GET /rbac/organization/get-tree)
1 接口请求示例

请求 /rbac/organization/get-tree(GET)

无请求参数。 响应

[
  {
    "id": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "总部",
    "children": []
  }
]
2 接口业务逻辑

####### 核心流程

  • 按父子关系构建并返回组织树。 ####### 校验与异常
  • 数据异常(循环父子关系)时返回 ApplicationExceptionResult(400)。
组织详情(GET /rbac/organization/get)
1 接口请求示例

请求 /rbac/organization/get(GET,Query 参数)

?id=3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "id": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "parentId": null,
  "name": "总部",
  "code": "HQ",
  "type": "Company",
  "leaderId": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "leaderName": "管理员A",
  "order": 1,
  "description": "总部组织",
  "isEnabled": true
}
2 接口业务逻辑

####### 核心流程

  • 根据组织 ID 查询 OrganizationDto。 ####### 校验与异常
  • 组织不存在时返回 ApplicationExceptionResult(400)。
创建组织(POST /rbac/organization/create)
1 接口请求示例

请求 /rbac/organization/create(POST,Body)

{
  "parentId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "运营部",
  "code": "OP",
  "type": "Department",
  "leaderId": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "order": 10,
  "description": "运营部门",
  "isEnabled": true
}

响应

{
  "id": "91fb7e02-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "运营部",
  "code": "OP",
  "type": "Department"
}
2 接口业务逻辑

####### 核心流程

  • 新增组织节点并返回 OrganizationDto。 ####### 校验与异常
  • 编码重复、父节点不存在时返回 ApplicationExceptionResult(400)。
更新组织(PUT /rbac/organization/update)
1 接口请求示例

请求 /rbac/organization/update(PUT,Query + Body)

?id=91fb7e02-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
  "name": "运营中心",
  "type": "Department",
  "leaderId": "8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "order": 20,
  "description": "运营中心",
  "isEnabled": true
}

响应

{
  "id": "91fb7e02-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "运营中心",
  "code": "OP"
}
2 接口业务逻辑

####### 核心流程

  • 按 ID 更新组织信息。 ####### 校验与异常
  • 组织不存在或状态非法时返回 ApplicationExceptionResult(400)。
删除组织(DELETE /rbac/organization/delete)
1 接口请求示例

请求 /rbac/organization/delete(DELETE,Query 参数)

?id=91fb7e02-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 删除组织节点。 ####### 校验与异常
  • 有子节点或被用户引用时返回 ApplicationExceptionResult(400)。
移动组织(POST /rbac/organization/move)
1 接口请求示例

请求 /rbac/organization/move(POST,Query + Body)

?id=91fb7e02-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
  "newParentId": "3c8a8f65-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 调整组织父节点,重建树关系。 ####### 校验与异常
  • 新父节点非法、移动后形成循环层级时返回 ApplicationExceptionResult(400)。

6.6.4 菜单(Menu)

菜单详情(GET /rbac/menu/get)
1 接口请求示例

请求 /rbac/menu/get(GET,Query 参数)

?id=7df1e9a0-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "id": "7df1e9a0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "pId": "00000000-0000-0000-0000-000000000000",
  "name": "系统管理",
  "permissionCode": "rbac:system",
  "type": 1,
  "route": "/system",
  "component": "system/index",
  "order": 1,
  "isHidden": false,
  "isCached": true
}
2 接口业务逻辑

####### 核心流程

  • 根据菜单 ID 查询 MenuDto。 ####### 校验与异常
  • 菜单不存在时返回 ApplicationExceptionResult(400)。
菜单树(GET /rbac/menu/get-menu-tree)
1 接口请求示例

请求 /rbac/menu/get-menu-tree(GET)

无请求参数。 响应

[
  {
    "id": "7df1e9a0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "系统管理",
    "children": []
  }
]
2 接口业务逻辑

####### 核心流程

  • 返回完整菜单树。 ####### 校验与异常
  • 查询异常返回 ApplicationExceptionResult(400)。
用户菜单(GET /rbac/menu/get-user-menus)
1 接口请求示例

请求 /rbac/menu/get-user-menus(GET,Query 参数)

?userId=8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

[
  {
    "id": "7df1e9a0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "name": "系统管理",
    "route": "/system"
  }
]
2 接口业务逻辑

####### 核心流程

  • 根据用户权限返回可见菜单集合。 ####### 校验与异常
  • 用户不存在时返回 ApplicationExceptionResult(400)。
创建菜单(POST /rbac/menu/create)
1 接口请求示例

请求 /rbac/menu/create(POST,Body)

{
  "pId": "00000000-0000-0000-0000-000000000000",
  "name": "用户管理",
  "permissionCode": "rbac:user:get-list",
  "type": 2,
  "icon": "User",
  "route": "/system/user",
  "component": "system/user/index",
  "order": 10,
  "isHidden": false,
  "isCached": true,
  "description": "用户管理菜单"
}

响应

{
  "id": "cc9ad54f-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "用户管理",
  "permissionCode": "rbac:user:get-list"
}
2 接口业务逻辑

####### 核心流程

  • 新增菜单并返回 MenuDto。 ####### 校验与异常
  • permissionCode 重复、父节点不存在时返回 ApplicationExceptionResult(400)。
更新菜单(PUT /rbac/menu/update)
1 接口请求示例

请求 /rbac/menu/update(PUT,Query + Body)

?id=cc9ad54f-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
  "name": "用户中心",
  "permissionCode": "rbac:user:get-list",
  "icon": "User",
  "route": "/system/user",
  "component": "system/user/index",
  "isHidden": false,
  "isCached": true,
  "description": "用户中心菜单"
}

响应

{
  "id": "cc9ad54f-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "name": "用户中心",
  "permissionCode": "rbac:user:get-list"
}
2 接口业务逻辑

####### 核心流程

  • 更新菜单信息并返回 MenuDto。 ####### 校验与异常
  • 菜单不存在、编码冲突时返回 ApplicationExceptionResult(400)。
删除菜单(DELETE /rbac/menu/delete)
1 接口请求示例

请求 /rbac/menu/delete(DELETE,Query 参数)

?id=cc9ad54f-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 删除菜单节点。 ####### 校验与异常
  • 菜单存在子节点或被引用时返回 ApplicationExceptionResult(400)。
移动菜单(POST /rbac/menu/move-menu)
1 接口请求示例

请求 /rbac/menu/move-menu(POST,Query 参数)

?menuId=cc9ad54f-xxxx-xxxx-xxxx-xxxxxxxxxxxx&targetParentId=7df1e9a0-xxxx-xxxx-xxxx-xxxxxxxxxxxx

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 调整菜单父子层级。 ####### 校验与异常
  • 节点非法或形成循环层级时返回 ApplicationExceptionResult(400)。
更新菜单排序(PUT /rbac/menu/update-order)
1 接口请求示例

请求 /rbac/menu/update-order(PUT,Query 参数)

?id=cc9ad54f-xxxx-xxxx-xxxx-xxxxxxxxxxxx&order=20

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 更新菜单排序值。 ####### 校验与异常
  • order 非法或菜单不存在时返回 ApplicationExceptionResult(400)。

6.6.5 权限(Permission)

全量权限(GET /rbac/permission/get-all-permissions)
1 接口请求示例

请求 /rbac/permission/get-all-permissions(GET)

无请求参数。 响应

[
  "rbac:user:get-list",
  "rbac:role:get-list"
]
2 接口业务逻辑

####### 核心流程

  • 返回系统全部权限编码列表。 ####### 校验与异常
  • 查询异常返回 ApplicationExceptionResult(400)。
权限树(GET /rbac/permission/get-permission-tree)
1 接口请求示例

请求 /rbac/permission/get-permission-tree(GET)

无请求参数。 响应

[
  {
    "permissionCode": "rbac:user",
    "children": [
      {
        "permissionCode": "rbac:user:get-list"
      }
    ]
  }
]
2 接口业务逻辑

####### 核心流程

  • 返回权限树结构,供角色授权界面使用。 ####### 校验与异常
  • 数据异常时返回 ApplicationExceptionResult(400)。
单权限校验(POST /rbac/permission/check-permission)
1 接口请求示例

请求 /rbac/permission/check-permission(POST,Query 参数)

?userId=8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx&permissionCode=rbac:user:get-list

响应

true
2 接口业务逻辑

####### 核心流程

  • 校验指定用户是否具备某个权限。 ####### 校验与异常
  • 用户不存在或权限码为空时返回 ApplicationExceptionResult(400)。
多权限校验(POST /rbac/permission/check-permissions)
1 接口请求示例

请求 /rbac/permission/check-permissions(POST,Query + Body)

?userId=8f4b2a3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx
[
  "rbac:user:get-list",
  "rbac:role:get-list"
]

响应

{
  "rbac:user:get-list": true,
  "rbac:role:get-list": false
}
2 接口业务逻辑

####### 核心流程

  • 批量校验权限并返回映射结果。 ####### 校验与异常
  • 请求体为空或用户不存在时返回 ApplicationExceptionResult(400)。
国家列表(GET /system/country/list)
1 接口请求示例

请求 /system/country/list(GET)

无请求参数,返回全部国家字段。

响应

{
  "code": 0,
  "msg": "success",
  "data": [
    {
      "id": 1,
      "chineseName": "中国",
      "englishName": "China",
      "countryCode": "CN"
    },
    {
      "id": 2,
      "chineseName": "美国",
      "englishName": "United States",
      "countryCode": "US"
    }
  ]
}
2 接口业务逻辑

####### 核心流程

  • 查询 t_country 全量有效数据,按 countryCode 或 englishName 排序返回。

####### 校验与异常

  • 仅返回未删除记录;无数据时返回空数组。
字典列表(GET /system/dict/list)
1 接口请求示例

请求 /system/dict/list(GET,Query 参数)

?page=1&pageSize=20&dictType=warehouse_type&keyword=主仓

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "dictType": "warehouse_type",
        "dictSort": 1,
        "dictCode": "main",
        "dictName": "主仓",
        "createTime": "2026-04-27 10:00:00",
        "updateTime": "2026-04-27 10:00:00"
      }
    ],
    "total": 1
  }
}
2 接口业务逻辑

####### 核心流程

  • 按 dictType、关键词分页查询 t_dict,按 dictSort 升序、id 降序返回。

####### 校验与异常

  • 校验分页参数合法性;仅返回未删除记录,查询异常时返回统一错误码。
新增字典(POST /system/dict/create)
1 接口请求示例

请求 /system/dict/create(POST)

{
  "dictType": "warehouse_type",
  "dictSort": 1,
  "dictCode": "main",
  "dictName": "主仓"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增字典项并写入创建审计信息。

####### 校验与异常

  • 校验 dictType、dictSort、dictCode、dictName 必填及格式合法性。
  • 校验同一 dictType 下 dictCode 唯一,重复时返回业务错误。
更新字典(POST /system/dict/update)
1 接口请求示例

请求 /system/dict/update(POST)

{
  "id": 1,
  "dictType": "warehouse_type",
  "dictSort": 2,
  "dictCode": "transit",
  "dictName": "中转仓"
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据字典 ID 更新字典类型、排序、编码、名称及审计信息。

####### 校验与异常

  • 校验 id 存在且未删除,更新字段合法。
  • 若更新后 dictType + dictCode 与其他记录冲突,返回业务错误。
删除字典(POST /system/dict/delete)
1 接口请求示例

请求 /system/dict/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据字典 ID 执行逻辑删除并保留历史审计信息。

####### 校验与异常

  • 校验 id 存在与删除前置条件,不存在或已删除时返回业务错误。
仓库列表(GET /system/warehouse/list)
1 接口请求示例

请求 /system/warehouse/list(GET,Query 参数)

?page=1&pageSize=20&warehouseType=main&keyword=

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 1,
        "warehouseName": "深圳主仓",
        "warehouseType": "main",
        "warehouseTypeName": "主仓",
        "recipient": "张三",
        "contactPhone": "0755-12345678",
        "shippingAddress": "广东省深圳市南山区xxx路xxx号",
        "servicePhone": "400-xxx-xxxx",
        "serviceWechat": "itfx_service",
        "serviceWechatFiles": ["https://example.com/qrcode1.jpg"],
        "createTime": "2024-01-01 12:00:00",
        "updateTime": "2024-01-01 12:00:00"
      }
    ],
    "total": 5
  }
}
2 接口业务逻辑

####### 核心流程

  • 按仓库类型与关键词分页查询仓库地址信息列表。

####### 校验与异常

  • 校验分页参数与筛选条件合法性,异常时返回统一错误码。
仓库详情(GET /system/warehouse/detail)
1 接口请求示例

请求 /system/warehouse/detail(GET,Query 参数)

?id=1

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "id": 1,
    "warehouseName": "深圳主仓",
    "warehouseType": "main",
    "recipient": "张三",
    "contactPhone": "0755-12345678",
    "shippingAddress": "广东省深圳市南山区xxx路xxx号",
    "servicePhone": "400-xxx-xxxx",
    "serviceWechat": "itfx_service",
    "serviceWechatFiles": ["https://example.com/qrcode1.jpg"],
    "createTime": "2024-01-01 12:00:00",
    "createBy": "admin",
    "updateTime": "2024-01-01 12:00:00",
    "updateBy": "admin"
  }
}
2 接口业务逻辑

####### 核心流程

  • 根据仓库 ID 查询仓库详情,返回完整地址与客服信息。

####### 校验与异常

  • 校验 id 必填且存在,不存在时返回业务错误。
新增仓库(POST /system/warehouse/create)
1 接口请求示例

请求 /system/warehouse/create(POST)

{
  "warehouseName": "深圳主仓",
  "warehouseType": "main",
  "recipient": "张三",
  "contactPhone": "0755-12345678",
  "shippingAddress": "广东省深圳市南山区xxx路xxx号",
  "servicePhone": "400-xxx-xxxx",
  "serviceWechat": "itfx_service",
  "serviceWechatFiles": ["https://example.com/qrcode1.jpg"]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增仓库地址配置并写入创建审计信息。

####### 校验与异常

  • 校验仓库名称、类型及地址字段完整性,不合法时返回业务错误。
更新仓库(POST /system/warehouse/update)
1 接口请求示例

请求 /system/warehouse/update(POST)

{
  "id": 1,
  "warehouseName": "深圳主仓",
  "warehouseType": "main",
  "recipient": "张三",
  "contactPhone": "0755-12345678",
  "shippingAddress": "广东省深圳市南山区xxx路xxx号",
  "servicePhone": "400-xxx-xxxx",
  "serviceWechat": "itfx_service",
  "serviceWechatFiles": ["https://example.com/qrcode1.jpg"]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据仓库 ID 更新仓库基础信息与联系方式。

####### 校验与异常

  • 校验 id 存在与更新字段合法性,更新失败时返回业务错误。
删除仓库(POST /system/warehouse/delete)
1 接口请求示例

请求 /system/warehouse/delete(POST)

{
  "id": 1
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据仓库 ID 执行逻辑删除并保留历史记录。

####### 校验与异常

  • 校验 id 存在与删除前置条件,冲突时返回业务错误。
通知列表(GET /system/notice/list)
1 接口请求示例

请求 /system/notice/list(GET,Query 参数)

?page=1&pageSize=20&noticeType=notice&receiverType=user&keyword=活动

响应

{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": 101,
        "noticeType": "notice",
        "noticeTypeName": "公告",
        "title": "五一放假通知",
        "content": "仓库 5 月 1 日-5 月 3 日暂停收货。",
        "isPopup": 1,
        "receiverType": "user",
        "receiverTypeName": "用户",
        "receiverIds": [1001, 1002, 1003],
        "readCount": 2,
        "receiverCount": 3,
        "createTime": "2026-04-25 12:00:00",
        "updateTime": "2026-04-25 12:00:00"
      }
    ],
    "total": 1
  }
}
2 接口业务逻辑

####### 核心流程

  • 按通知类型、接收对象、关键词分页查询 t_notice。
  • 已读数通过聚合 t_notice_read(按 NoticeId + ReceiverId 去重)计算,接收人总数按 receiverIds 统计。

####### 校验与异常

  • 校验分页参数合法性,仅返回未删除记录;异常时返回统一错误码。
新增通知(POST /system/notice/create)
1 接口请求示例

请求 /system/notice/create(POST)

{
  "noticeType": "notice",
  "title": "五一放假通知",
  "content": "仓库 5 月 1 日-5 月 3 日暂停收货。",
  "isPopup": 1,
  "receiverType": "user",
  "receiverIds": [1001, 1002, 1003]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 新增公告/站内信并写入接收对象与接收人列表。

####### 校验与异常

  • 校验 noticeType、title、content、isPopup、receiverType、receiverIds 必填及枚举合法性。
  • receiverIds 为空或包含无效用户/客户时返回业务错误。
编辑通知(POST /system/notice/update)
1 接口请求示例

请求 /system/notice/update(POST)

{
  "id": 101,
  "noticeType": "message",
  "title": "账单补充说明",
  "content": "请于本周内完成 4 月账单核对。",
  "isPopup": 0,
  "receiverType": "customer",
  "receiverIds": [2001, 2002]
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据通知 ID 更新通知主体内容与接收范围。
  • 如接收人发生变化,清理 t_notice_read 中不在新接收范围内的已读明细。

####### 校验与异常

  • 校验 id 存在且未删除,更新字段合法。
  • 已发布通知可编辑但必须保留至少 1 个接收人。
删除通知(POST /system/notice/delete)
1 接口请求示例

请求 /system/notice/delete(POST)

{
  "id": 101
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 根据通知 ID 执行逻辑删除,保留历史审计信息。

####### 校验与异常

  • 校验 id 必填且存在,不存在或已删除时返回业务错误。
确认已读(POST /system/notice/read-confirm)
1 接口请求示例

请求 /system/notice/read-confirm(POST)

{
  "id": 101
}

响应

{
  "code": 0,
  "msg": "success",
  "data": null
}
2 接口业务逻辑

####### 核心流程

  • 当前登录用户/客户调用后,在 t_notice_read 中按 NoticeId + ReceiverType + ReceiverId 幂等写入已读记录,并记录 readTime。

####### 校验与异常

  • 校验通知存在且未删除。
  • 校验当前主体在通知接收范围内,不在范围内时返回无权限错误。


附录

附录一:接口路径规范(kebab-case 汇总)

模块 路径前缀 示例
订单 /order/ list, detail, pay, pre-declare, cancel-intercept, delete, price-check
渠道-销售产品 /channel/sales-product/ list, detail, create, update, delete, price/list, allocation/get
渠道-服务渠道 /channel/service-channel/ list, detail, create, update, delete, group/create, group/update, group/delete, price/list
渠道-计重 /channel/weight-rule/, weight-rounding/ list, create, update, delete, info/list
渠道-自动触发 /channel/auto-trigger/ list, create, update, delete, toggle-status
渠道-分区(KpiArea) /channel/kpi-area/ create, update, delete, list, info/add, info/update, info/delete, info/list
渠道-标签 /channel/label-template/save
操作 /operation/ inbound/create, inbound/recent-list, outbound/create, print-label/print
客户 /customer/ list, get, create, update, delete, reset-password
充值 /recharge/ recharge/submit, recharge-record/list, approve, reject
系统 /system/ country/list, warehouse/list, warehouse/detail, warehouse/create, warehouse/update, warehouse/delete, notice/list, notice/create, notice/update, notice/delete, notice/read-confirm

附录二:分区类型说明(黑名单/偏远/价格)

页面 areaType 说明
黑名单区 blacklist 黑名单分区
偏远分区 remote 偏远分区
价格分区 price 用于计价/价格表关联的分区

调用 KpiArea 接口时,通过 areaType 区分不同业务分区,无需新建表或接口。

附录三:状态码与枚举

订单状态

status 中文
draft 草稿
predeclared 已预报
received 已收货
pendingPayment 待支付
pendingShip 待发货
pendingOnline 待上网
shipping 运输中
deliverySuccess 派送成功
deliveryFailed 派送失败
problematic 问题件
deleted 已删除
claimed 已理赔

充值状态

payStatus 中文
0 待审核
1 成功
2 失败

仓库类型

warehouseType 中文
main 主仓
transit 中转仓
return 退货仓
other 其他

通知类型

noticeType 中文
notice 公告
message 站内信

接收对象类型

receiverType 中文
user 用户
customer 客户

客户分组(客户表)

customerGroup 中文
0 普通客户
1 VIP1
2 VIP2
3 VIP3
4 VIP4
5 VIP5

文档版本:v1.1 | 最后更新:2026-04-27