feat(order): add customer order foundations
This commit is contained in:
@@ -236,6 +236,33 @@ CREATE TABLE IF NOT EXISTS ord_order_party (
|
||||
CONSTRAINT fk_party_order FOREIGN KEY (order_id) REFERENCES ord_order (id)
|
||||
) ENGINE=InnoDB COMMENT='订单收发货方快照表:固化下单时发货人和收货人信息,避免主数据变化影响历史订单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ord_customer_address (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '客户地址ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
||||
address_type VARCHAR(32) NOT NULL COMMENT 'PICKUP取货地址或PRIVATE_DESTINATION私人目的仓',
|
||||
address_name VARCHAR(64) NOT NULL COMMENT '客户自定义地址名称',
|
||||
company_name VARCHAR(128) NOT NULL COMMENT '公司名称',
|
||||
contact_name VARCHAR(64) NOT NULL COMMENT '联系人',
|
||||
phone VARCHAR(32) NOT NULL COMMENT '联系电话',
|
||||
email VARCHAR(128) NULL COMMENT '联系邮箱',
|
||||
country_code CHAR(2) NOT NULL COMMENT '国家二字码',
|
||||
province VARCHAR(64) NULL COMMENT '省州',
|
||||
city VARCHAR(64) NOT NULL COMMENT '城市',
|
||||
district VARCHAR(64) NULL COMMENT '区县',
|
||||
address_line VARCHAR(255) NOT NULL COMMENT '详细地址',
|
||||
postal_code VARCHAR(20) NULL COMMENT '邮政编码',
|
||||
default_address TINYINT(1) NOT NULL DEFAULT 0 COMMENT '同类型默认地址',
|
||||
active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否可选',
|
||||
created_by BIGINT UNSIGNED NOT NULL,
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_by BIGINT UNSIGNED NOT NULL,
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
deleted TINYINT(1) NOT NULL DEFAULT 0,
|
||||
version INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_customer_address_scope (tenant_id, address_type, active, updated_at)
|
||||
) ENGINE=InnoDB COMMENT='客户自有下单地址簿;不承载平台仓库主档';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ord_order_cargo (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '货物明细ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
||||
@@ -272,6 +299,7 @@ CREATE TABLE IF NOT EXISTS ord_order_cargo (
|
||||
shipment_id VARCHAR(64) NULL COMMENT '货物级 Amazon Shipment ID',
|
||||
reference_id VARCHAR(64) NULL COMMENT '货物级 Amazon Reference ID',
|
||||
product_image_file_id BIGINT UNSIGNED NULL COMMENT '文件中心产品图片逻辑ID',
|
||||
wooden_product TINYINT(1) NOT NULL DEFAULT 0 COMMENT '木制品权威判定快照;1时订单必须商检',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID',
|
||||
@@ -284,6 +312,17 @@ CREATE TABLE IF NOT EXISTS ord_order_cargo (
|
||||
CONSTRAINT fk_cargo_order FOREIGN KEY (order_id) REFERENCES ord_order (id)
|
||||
) ENGINE=InnoDB COMMENT='订单货物明细表:记录件数、重量、体积、申报价值和危险品属性';
|
||||
|
||||
SET @order_wooden_product_sql = IF(
|
||||
EXISTS(SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'baiyue_order' AND table_name = 'ord_order_cargo'
|
||||
AND column_name = 'wooden_product'),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE baiyue_order.ord_order_cargo ADD COLUMN wooden_product TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''木制品权威判定快照;1时订单必须商检'' AFTER product_image_file_id'
|
||||
);
|
||||
PREPARE order_wooden_product_stmt FROM @order_wooden_product_sql;
|
||||
EXECUTE order_wooden_product_stmt;
|
||||
DEALLOCATE PREPARE order_wooden_product_stmt;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ord_order_internal_note (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '内部备注ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
||||
|
||||
@@ -6,6 +6,76 @@ info:
|
||||
security:
|
||||
- bearerAuth: []
|
||||
paths:
|
||||
/api/merchant/v1/order-addresses:
|
||||
get:
|
||||
summary: 查询当前客户下单地址簿
|
||||
parameters:
|
||||
- name: addressType
|
||||
in: query
|
||||
required: false
|
||||
schema: {type: string, enum: [PICKUP, PRIVATE_DESTINATION]}
|
||||
responses:
|
||||
'200': {description: 只返回登录客户可用地址}
|
||||
'403': {description: 需要订单查看、创建或编辑权限}
|
||||
post:
|
||||
summary: 保存当前客户下单地址
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CustomerOrderAddressSaveRequest'}
|
||||
responses:
|
||||
'200': {description: 返回地址内部 ID,Long 按字符串序列化}
|
||||
'403': {description: 需要 merchant:order:create 权限}
|
||||
/api/merchant/v1/order-addresses/{id}:
|
||||
put:
|
||||
summary: 修改当前客户下单地址
|
||||
description: 已创建订单保存独立快照,本操作不会修改历史订单。
|
||||
parameters:
|
||||
- {name: id, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CustomerOrderAddressSaveRequest'}
|
||||
responses: {'200': {description: 成功}, '403': {description: 需要 merchant:order:edit 权限}}
|
||||
delete:
|
||||
summary: 停用当前客户下单地址
|
||||
description: 停用后不能用于新订单,历史订单快照不受影响。
|
||||
parameters:
|
||||
- {name: id, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses: {'200': {description: 成功}, '403': {description: 需要 merchant:order:edit 权限}}
|
||||
/api/merchant/v1/orders/first-leg/batch-imports/template:
|
||||
get:
|
||||
summary: 下载 Excel 批量下单模板
|
||||
responses:
|
||||
'200': {description: xlsx 模板}
|
||||
'403': {description: 需要 merchant:order:create 权限}
|
||||
/api/merchant/v1/orders/first-leg/batch-imports:
|
||||
post:
|
||||
summary: 上传 Excel 批量创建订单草稿
|
||||
description: >-
|
||||
ATOMIC 在任一行失败时整批回滚;PARTIAL 每行独立事务,错误行不影响成功行。
|
||||
同一操作者重试必须复用 Idempotency-Key,每行再以 clientRowId 派生稳定幂等键。
|
||||
原文件和错误报告分别通过 File 的 ORDER_BATCH_IMPORT_SOURCE、ORDER_BATCH_IMPORT_ERROR_REPORT 契约保存。
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/IdempotencyKey'
|
||||
- name: mode
|
||||
in: query
|
||||
required: true
|
||||
schema: {type: string, enum: [ATOMIC, PARTIAL]}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
required: [file]
|
||||
properties:
|
||||
file: {type: string, format: binary, description: 最大 5MB,仅 xlsx;最多 50 行}
|
||||
responses:
|
||||
'200': {description: 返回逐行结果、原文件 ID 及可选错误报告文件 ID}
|
||||
'403': {description: 需要 merchant:order:create 权限}
|
||||
/api/platform/v1/orders/first-leg/inbound-code-policy:
|
||||
get:
|
||||
summary: 平台端查询全系统入仓码模式
|
||||
@@ -686,7 +756,7 @@ components:
|
||||
description: 报价包税维度;独立于订单 taxMode 的买单/退税语义
|
||||
FirstLegOrderDraft:
|
||||
type: object
|
||||
required: [pricingTaxMode, cargoes]
|
||||
required: [customerName, transportMode, cargoes, pickupMethod, receivingWarehouseId, receivingWarehouseName, channelCode, channelName, taxMode, pricingTaxMode, destinationType]
|
||||
properties:
|
||||
fulfillmentType:
|
||||
type: string
|
||||
@@ -699,6 +769,9 @@ components:
|
||||
pattern: '^[A-Za-z0-9._:-]+$'
|
||||
description: 仅 LEGACY_MANUAL 模式填写的旧系统入仓码;AUTO 模式必须省略
|
||||
pricingTaxMode: {$ref: '#/components/schemas/PricingTaxMode'}
|
||||
senderAddressId: {type: string, pattern: '^[1-9][0-9]*$', description: PICKUP 时必填;必须是本客户 PICKUP 地址}
|
||||
privateDestinationAddressId: {type: string, pattern: '^[1-9][0-9]*$', description: PRIVATE 时必填;必须是本客户 PRIVATE_DESTINATION 地址}
|
||||
customsInspection: {type: boolean, nullable: true, description: 非木制品可空;任一货物 woodenProduct=true 时必须为 true}
|
||||
cargoes:
|
||||
type: array
|
||||
minItems: 1
|
||||
@@ -707,7 +780,25 @@ components:
|
||||
订单保存请求中的完整字段以服务端 FirstLegOrderSaveRequest 为准;fulfillmentType
|
||||
省略时固定为 STANDARD,一键代发必须显式传 ONE_CLICK_DROPSHIP,且不复用计费 businessType;pricingTaxMode
|
||||
是新建和编辑订单的必填报价维度;customerId 不接受客户端指定,服务端始终使用认证企业 ID;
|
||||
发货单位和收货单位仅通过 sender/receiver 保存业务快照。历史存量订单的响应字段仍允许为空。
|
||||
发货与私人目的仓只接受客户地址 ID,服务端在订单参与方表冻结快照;地址簿后续修改不回写历史订单。
|
||||
私人目的仓不得写入或伪装为 Warehouse 平台仓主档。历史存量订单的响应字段仍允许为空。
|
||||
CustomerOrderAddressSaveRequest:
|
||||
type: object
|
||||
required: [addressType, addressName, companyName, contactName, phone, countryCode, city, addressLine, defaultAddress]
|
||||
properties:
|
||||
addressType: {type: string, enum: [PICKUP, PRIVATE_DESTINATION]}
|
||||
addressName: {type: string, maxLength: 64}
|
||||
companyName: {type: string, maxLength: 128}
|
||||
contactName: {type: string, maxLength: 64}
|
||||
phone: {type: string, maxLength: 32}
|
||||
email: {type: string, format: email, maxLength: 128, nullable: true}
|
||||
countryCode: {type: string, minLength: 2, maxLength: 2}
|
||||
province: {type: string, maxLength: 64, nullable: true}
|
||||
city: {type: string, maxLength: 64}
|
||||
district: {type: string, maxLength: 64, nullable: true}
|
||||
addressLine: {type: string, maxLength: 255}
|
||||
postalCode: {type: string, maxLength: 20, nullable: true}
|
||||
defaultAddress: {type: boolean}
|
||||
InboundCodePolicy:
|
||||
type: object
|
||||
required: [mode, manualEntryRequired]
|
||||
@@ -769,7 +860,7 @@ components:
|
||||
errorMessage: {type: string}
|
||||
FirstLegOrderCargo:
|
||||
type: object
|
||||
required: [skuNo, packageCount]
|
||||
required: [packageCount, woodenProduct]
|
||||
properties:
|
||||
skuNo: {type: string, maxLength: 64}
|
||||
cargoName: {type: string, maxLength: 128}
|
||||
@@ -801,6 +892,7 @@ components:
|
||||
cargoRemark: {type: string, maxLength: 500}
|
||||
packageType: {type: string, maxLength: 32}
|
||||
dangerousGoods: {type: boolean}
|
||||
woodenProduct: {type: boolean, description: 木制品权威判定快照;为 true 时订单 customsInspection 必须为 true}
|
||||
description: >-
|
||||
原型货物明细字段。FBA 货物的 skuNo、upcNo、shipmentId、referenceId 由服务端按每条货物校验;
|
||||
productImageFileId 必须属于当前登录客户。
|
||||
|
||||
Reference in New Issue
Block a user