refactor: 仓储表 C_* 改为 c_*,优化专线小包批量模板
- 仓储实体与 db.sql 统一为小写 c_ 前缀,新增 migrate_rename_warehouse_C_to_c.sql - 专线小包批量模板精简版/标准版双模板,Excel 必填标红与发件地址上传参数 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
d791f7b251
commit
a1daea6b35
66
db.sql
66
db.sql
@ -1,4 +1,4 @@
|
|||||||
-- OMS Admin schema
|
-- OMS Admin schema
|
||||||
-- Target database: MySQL 8.0+
|
-- Target database: MySQL 8.0+
|
||||||
-- Notes:
|
-- Notes:
|
||||||
-- 1. Physical foreign keys are intentionally omitted. The project uses logical foreign keys plus indexes to reduce import friction,
|
-- 1. Physical foreign keys are intentionally omitted. The project uses logical foreign keys plus indexes to reduce import friction,
|
||||||
@ -36,16 +36,16 @@ DROP TABLE IF EXISTS `t_xhs_analysis_session`;
|
|||||||
DROP TABLE IF EXISTS `t_xhs_publish_record`;
|
DROP TABLE IF EXISTS `t_xhs_publish_record`;
|
||||||
DROP TABLE IF EXISTS `t_xhs_task`;
|
DROP TABLE IF EXISTS `t_xhs_task`;
|
||||||
DROP TABLE IF EXISTS `t_xhs_agent`;
|
DROP TABLE IF EXISTS `t_xhs_agent`;
|
||||||
DROP TABLE IF EXISTS `C_inbound_box_line`;
|
DROP TABLE IF EXISTS `c_inbound_box_line`;
|
||||||
DROP TABLE IF EXISTS `C_inbound_box`;
|
DROP TABLE IF EXISTS `c_inbound_box`;
|
||||||
DROP TABLE IF EXISTS `C_inbound_notice`;
|
DROP TABLE IF EXISTS `c_inbound_notice`;
|
||||||
DROP TABLE IF EXISTS `C_parcel_item`;
|
DROP TABLE IF EXISTS `c_parcel_item`;
|
||||||
DROP TABLE IF EXISTS `C_parcel_arrival`;
|
DROP TABLE IF EXISTS `c_parcel_arrival`;
|
||||||
DROP TABLE IF EXISTS `C_parcel`;
|
DROP TABLE IF EXISTS `c_parcel`;
|
||||||
DROP TABLE IF EXISTS `C_inventory`;
|
DROP TABLE IF EXISTS `c_inventory`;
|
||||||
DROP TABLE IF EXISTS `C_sku_platform_map`;
|
DROP TABLE IF EXISTS `c_sku_platform_map`;
|
||||||
DROP TABLE IF EXISTS `C_sku`;
|
DROP TABLE IF EXISTS `c_sku`;
|
||||||
DROP TABLE IF EXISTS `C_bin_location`;
|
DROP TABLE IF EXISTS `c_bin_location`;
|
||||||
DROP TABLE IF EXISTS `t_sales_store_order_line`;
|
DROP TABLE IF EXISTS `t_sales_store_order_line`;
|
||||||
DROP TABLE IF EXISTS `t_sales_store_order`;
|
DROP TABLE IF EXISTS `t_sales_store_order`;
|
||||||
DROP TABLE IF EXISTS `t_sales_store`;
|
DROP TABLE IF EXISTS `t_sales_store`;
|
||||||
@ -1229,10 +1229,10 @@ CREATE TABLE `t_customer_account_flow` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户账户资金流水';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户账户资金流水';
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- 仓储模块(C_*)+ 店铺订单(t_sales_store*)
|
-- 仓储模块(c_*)+ 店铺订单(t_sales_store*)
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TABLE `C_sku` (
|
CREATE TABLE `c_sku` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id',
|
`CustomerId` INT NOT NULL COMMENT '客户ID → t_customer.Id',
|
||||||
`SkuCode` VARCHAR(64) NOT NULL COMMENT '库内SKU编码',
|
`SkuCode` VARCHAR(64) NOT NULL COMMENT '库内SKU编码',
|
||||||
@ -1254,7 +1254,7 @@ CREATE TABLE `C_sku` (
|
|||||||
KEY `idx_c_sku_customer` (`CustomerId`, `IsDeleted`)
|
KEY `idx_c_sku_customer` (`CustomerId`, `IsDeleted`)
|
||||||
) COMMENT='仓储-SKU主数据';
|
) COMMENT='仓储-SKU主数据';
|
||||||
|
|
||||||
CREATE TABLE `C_bin_location` (
|
CREATE TABLE `c_bin_location` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`WarehouseId` INT NOT NULL COMMENT '仓库ID → t_warehouse_address.Id',
|
`WarehouseId` INT NOT NULL COMMENT '仓库ID → t_warehouse_address.Id',
|
||||||
`BinCode` VARCHAR(32) NOT NULL COMMENT '库位编码',
|
`BinCode` VARCHAR(32) NOT NULL COMMENT '库位编码',
|
||||||
@ -1273,12 +1273,12 @@ CREATE TABLE `C_bin_location` (
|
|||||||
KEY `idx_c_bin_warehouse` (`WarehouseId`, `IsEnabled`)
|
KEY `idx_c_bin_warehouse` (`WarehouseId`, `IsEnabled`)
|
||||||
) COMMENT='仓储-库位主数据';
|
) COMMENT='仓储-库位主数据';
|
||||||
|
|
||||||
CREATE TABLE `C_inventory` (
|
CREATE TABLE `c_inventory` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
||||||
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
||||||
`SkuId` INT NOT NULL COMMENT 'SKU ID → C_sku.Id',
|
`SkuId` INT NOT NULL COMMENT 'SKU ID → c_sku.Id',
|
||||||
`BinLocationId` INT NOT NULL COMMENT '库位ID → C_bin_location.Id',
|
`BinLocationId` INT NOT NULL COMMENT '库位ID → c_bin_location.Id',
|
||||||
`Qty` INT NOT NULL DEFAULT 0 COMMENT '可用库存数量',
|
`Qty` INT NOT NULL DEFAULT 0 COMMENT '可用库存数量',
|
||||||
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||||||
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||||||
@ -1291,7 +1291,7 @@ CREATE TABLE `C_inventory` (
|
|||||||
KEY `idx_c_inv_sku_wh` (`CustomerId`, `SkuId`, `WarehouseId`)
|
KEY `idx_c_inv_sku_wh` (`CustomerId`, `SkuId`, `WarehouseId`)
|
||||||
) COMMENT='仓储-库存余额(按库位)';
|
) COMMENT='仓储-库存余额(按库位)';
|
||||||
|
|
||||||
CREATE TABLE `C_inbound_notice` (
|
CREATE TABLE `c_inbound_notice` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
||||||
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
||||||
@ -1313,9 +1313,9 @@ CREATE TABLE `C_inbound_notice` (
|
|||||||
KEY `idx_c_inbound_customer_status` (`CustomerId`, `ReceiptStatus`, `CreateTime`)
|
KEY `idx_c_inbound_customer_status` (`CustomerId`, `ReceiptStatus`, `CreateTime`)
|
||||||
) COMMENT='仓储-入库预报主表';
|
) COMMENT='仓储-入库预报主表';
|
||||||
|
|
||||||
CREATE TABLE `C_inbound_box` (
|
CREATE TABLE `c_inbound_box` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`InboundNoticeId` INT NOT NULL COMMENT '入库预报ID → C_inbound_notice.Id',
|
`InboundNoticeId` INT NOT NULL COMMENT '入库预报ID → c_inbound_notice.Id',
|
||||||
`BoxSeqNo` VARCHAR(16) NOT NULL COMMENT '箱序号',
|
`BoxSeqNo` VARCHAR(16) NOT NULL COMMENT '箱序号',
|
||||||
`MarkBoxNo` VARCHAR(64) NULL COMMENT '箱唛号/箱号',
|
`MarkBoxNo` VARCHAR(64) NULL COMMENT '箱唛号/箱号',
|
||||||
`WeightG` DECIMAL(10,2) NULL COMMENT '箱重(g)',
|
`WeightG` DECIMAL(10,2) NULL COMMENT '箱重(g)',
|
||||||
@ -1333,14 +1333,14 @@ CREATE TABLE `C_inbound_box` (
|
|||||||
KEY `idx_c_inbound_box_notice` (`InboundNoticeId`, `IsDeleted`)
|
KEY `idx_c_inbound_box_notice` (`InboundNoticeId`, `IsDeleted`)
|
||||||
) COMMENT='仓储-入库预报箱';
|
) COMMENT='仓储-入库预报箱';
|
||||||
|
|
||||||
CREATE TABLE `C_inbound_box_line` (
|
CREATE TABLE `c_inbound_box_line` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`InboundBoxId` INT NOT NULL COMMENT '入库箱ID → C_inbound_box.Id',
|
`InboundBoxId` INT NOT NULL COMMENT '入库箱ID → c_inbound_box.Id',
|
||||||
`SkuId` INT NOT NULL COMMENT 'SKU ID → C_sku.Id',
|
`SkuId` INT NOT NULL COMMENT 'SKU ID → c_sku.Id',
|
||||||
`SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码',
|
`SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码',
|
||||||
`PlannedQty` INT NOT NULL DEFAULT 0 COMMENT '计划入库数量',
|
`PlannedQty` INT NOT NULL DEFAULT 0 COMMENT '计划入库数量',
|
||||||
`ReceivedQty` INT NULL COMMENT '实收数量',
|
`ReceivedQty` INT NULL COMMENT '实收数量',
|
||||||
`BinLocationId` INT NULL COMMENT '上架库位ID → C_bin_location.Id',
|
`BinLocationId` INT NULL COMMENT '上架库位ID → c_bin_location.Id',
|
||||||
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||||||
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||||||
`CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人',
|
`CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人',
|
||||||
@ -1352,7 +1352,7 @@ CREATE TABLE `C_inbound_box_line` (
|
|||||||
KEY `idx_c_inbound_box_line_sku` (`SkuId`)
|
KEY `idx_c_inbound_box_line_sku` (`SkuId`)
|
||||||
) COMMENT='仓储-入库箱内SKU行';
|
) COMMENT='仓储-入库箱内SKU行';
|
||||||
|
|
||||||
CREATE TABLE `C_parcel` (
|
CREATE TABLE `c_parcel` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
||||||
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
||||||
@ -1372,11 +1372,11 @@ CREATE TABLE `C_parcel` (
|
|||||||
KEY `idx_c_parcel_status` (`CustomerId`, `LifecycleStatus`)
|
KEY `idx_c_parcel_status` (`CustomerId`, `LifecycleStatus`)
|
||||||
) COMMENT='仓储-客户包裹';
|
) COMMENT='仓储-客户包裹';
|
||||||
|
|
||||||
CREATE TABLE `C_parcel_arrival` (
|
CREATE TABLE `c_parcel_arrival` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
||||||
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
||||||
`ParcelId` INT NULL COMMENT '关联包裹 C_parcel.Id',
|
`ParcelId` INT NULL COMMENT '关联包裹 c_parcel.Id',
|
||||||
`TrackingNo` VARCHAR(64) NOT NULL COMMENT '国内快递单号',
|
`TrackingNo` VARCHAR(64) NOT NULL COMMENT '国内快递单号',
|
||||||
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||||||
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||||||
@ -1389,14 +1389,14 @@ CREATE TABLE `C_parcel_arrival` (
|
|||||||
KEY `idx_c_parcel_arrival_ctime` (`CreateTime`)
|
KEY `idx_c_parcel_arrival_ctime` (`CreateTime`)
|
||||||
) COMMENT='仓储-快递到仓记录';
|
) COMMENT='仓储-快递到仓记录';
|
||||||
|
|
||||||
CREATE TABLE `C_parcel_item` (
|
CREATE TABLE `c_parcel_item` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`ParcelId` INT NOT NULL COMMENT '包裹ID → C_parcel.Id',
|
`ParcelId` INT NOT NULL COMMENT '包裹ID → c_parcel.Id',
|
||||||
`ProductName` VARCHAR(512) NULL COMMENT '商品名称',
|
`ProductName` VARCHAR(512) NULL COMMENT '商品名称',
|
||||||
`AttributeText` VARCHAR(256) NULL COMMENT '规格属性',
|
`AttributeText` VARCHAR(256) NULL COMMENT '规格属性',
|
||||||
`ImageUrl` VARCHAR(1024) NULL COMMENT '商品图片URL',
|
`ImageUrl` VARCHAR(1024) NULL COMMENT '商品图片URL',
|
||||||
`Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量',
|
`Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量',
|
||||||
`SkuId` INT NULL COMMENT '库内SKU ID → C_sku.Id',
|
`SkuId` INT NULL COMMENT '库内SKU ID → c_sku.Id',
|
||||||
`SkuCode` VARCHAR(64) NULL COMMENT '冗余SKU编码',
|
`SkuCode` VARCHAR(64) NULL COMMENT '冗余SKU编码',
|
||||||
`BinLocationId` INT NULL COMMENT '上架库位ID',
|
`BinLocationId` INT NULL COMMENT '上架库位ID',
|
||||||
`Remark` VARCHAR(512) NULL COMMENT '备注',
|
`Remark` VARCHAR(512) NULL COMMENT '备注',
|
||||||
@ -1410,12 +1410,12 @@ CREATE TABLE `C_parcel_item` (
|
|||||||
KEY `idx_c_parcel_item_parcel` (`ParcelId`, `IsDeleted`)
|
KEY `idx_c_parcel_item_parcel` (`ParcelId`, `IsDeleted`)
|
||||||
) COMMENT='仓储-包裹明细';
|
) COMMENT='仓储-包裹明细';
|
||||||
|
|
||||||
CREATE TABLE `C_sku_platform_map` (
|
CREATE TABLE `c_sku_platform_map` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
||||||
`StoreId` INT NOT NULL COMMENT '店铺ID → t_sales_store.Id',
|
`StoreId` INT NOT NULL COMMENT '店铺ID → t_sales_store.Id',
|
||||||
`PlatformSku` VARCHAR(128) NOT NULL COMMENT '平台listing SKU',
|
`PlatformSku` VARCHAR(128) NOT NULL COMMENT '平台listing SKU',
|
||||||
`SkuId` INT NOT NULL COMMENT '库内SKU ID → C_sku.Id',
|
`SkuId` INT NOT NULL COMMENT '库内SKU ID → c_sku.Id',
|
||||||
`SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码',
|
`SkuCode` VARCHAR(64) NOT NULL COMMENT '冗余SKU编码',
|
||||||
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||||||
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||||||
@ -1518,7 +1518,7 @@ CREATE TABLE `t_sales_store_order_line` (
|
|||||||
`Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量',
|
`Quantity` INT NOT NULL DEFAULT 0 COMMENT '数量',
|
||||||
`Currency` VARCHAR(8) NULL COMMENT '币种',
|
`Currency` VARCHAR(8) NULL COMMENT '币种',
|
||||||
`IsShipExcluded` TINYINT NOT NULL DEFAULT 0 COMMENT '是否拒绝发货',
|
`IsShipExcluded` TINYINT NOT NULL DEFAULT 0 COMMENT '是否拒绝发货',
|
||||||
`MappedSkuId` INT NULL COMMENT '映射库内SKU → C_sku.Id',
|
`MappedSkuId` INT NULL COMMENT '映射库内SKU → c_sku.Id',
|
||||||
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||||||
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||||||
`CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人',
|
`CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人',
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
-- 已有库增量:快递到仓表 C_parcel_arrival
|
-- 已有库增量:快递到仓表 c_parcel_arrival
|
||||||
-- 对应功能:操作 → 快递到仓;全量结构见根目录 db.sql
|
-- 对应功能:操作 → 快递到仓;全量结构见根目录 db.sql
|
||||||
-- 可重复执行(IF NOT EXISTS)
|
-- 可重复执行(IF NOT EXISTS)
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `C_parcel_arrival` (
|
CREATE TABLE IF NOT EXISTS `c_parcel_arrival` (
|
||||||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
`Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
`CustomerId` INT NOT NULL COMMENT '客户ID',
|
||||||
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
`WarehouseId` INT NOT NULL COMMENT '仓库ID',
|
||||||
`ParcelId` INT NULL COMMENT '关联包裹 C_parcel.Id',
|
`ParcelId` INT NULL COMMENT '关联包裹 c_parcel.Id',
|
||||||
`TrackingNo` VARCHAR(64) NOT NULL COMMENT '国内快递单号',
|
`TrackingNo` VARCHAR(64) NOT NULL COMMENT '国内快递单号',
|
||||||
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
`IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||||||
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||||||
|
|||||||
@ -1,20 +1,16 @@
|
|||||||
-- 已有库增量:包裹明细增加属性字段 AttributeText
|
-- 已有库增量:c_parcel_item.AttributeText
|
||||||
-- 可重复执行
|
-- 可重复执行
|
||||||
|
|
||||||
SET @col_exists := (
|
SET @col_exists := (
|
||||||
SELECT COUNT(1)
|
SELECT COUNT(1)
|
||||||
FROM information_schema.COLUMNS
|
FROM information_schema.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = DATABASE()
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
AND TABLE_NAME = 'C_parcel_item'
|
AND TABLE_NAME = 'c_parcel_item'
|
||||||
AND COLUMN_NAME = 'AttributeText'
|
AND COLUMN_NAME = 'AttributeText'
|
||||||
);
|
);
|
||||||
|
|
||||||
SET @sql := IF(
|
SET @sql := IF(
|
||||||
@col_exists = 0,
|
@col_exists = 0,
|
||||||
'ALTER TABLE `C_parcel_item` ADD COLUMN `AttributeText` VARCHAR(256) NULL COMMENT ''规格属性'' AFTER `ProductName`',
|
'ALTER TABLE `c_parcel_item` ADD COLUMN `AttributeText` VARCHAR(256) NULL COMMENT ''规格属性'' AFTER `ProductName`',
|
||||||
'SELECT ''C_parcel_item.AttributeText already exists'' AS info'
|
'SELECT ''c_parcel_item.AttributeText already exists'' AS info'
|
||||||
);
|
);
|
||||||
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
PREPARE stmt FROM @sql;
|
|
||||||
EXECUTE stmt;
|
|
||||||
DEALLOCATE PREPARE stmt;
|
|
||||||
|
|||||||
@ -1,20 +1,16 @@
|
|||||||
-- 已有库增量:包裹明细增加商品图片 ImageUrl
|
-- 已有库增量:c_parcel_item.ImageUrl
|
||||||
-- 可重复执行
|
-- 可重复执行
|
||||||
|
|
||||||
SET @col_exists := (
|
SET @col_exists := (
|
||||||
SELECT COUNT(1)
|
SELECT COUNT(1)
|
||||||
FROM information_schema.COLUMNS
|
FROM information_schema.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = DATABASE()
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
AND TABLE_NAME = 'C_parcel_item'
|
AND TABLE_NAME = 'c_parcel_item'
|
||||||
AND COLUMN_NAME = 'ImageUrl'
|
AND COLUMN_NAME = 'ImageUrl'
|
||||||
);
|
);
|
||||||
|
|
||||||
SET @sql := IF(
|
SET @sql := IF(
|
||||||
@col_exists = 0,
|
@col_exists = 0,
|
||||||
'ALTER TABLE `C_parcel_item` ADD COLUMN `ImageUrl` VARCHAR(1024) NULL COMMENT ''商品图片URL'' AFTER `AttributeText`',
|
'ALTER TABLE `c_parcel_item` ADD COLUMN `ImageUrl` VARCHAR(1024) NULL COMMENT ''商品图片URL'' AFTER `AttributeText`',
|
||||||
'SELECT ''C_parcel_item.ImageUrl already exists'' AS info'
|
'SELECT ''c_parcel_item.ImageUrl already exists'' AS info'
|
||||||
);
|
);
|
||||||
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
PREPARE stmt FROM @sql;
|
|
||||||
EXECUTE stmt;
|
|
||||||
DEALLOCATE PREPARE stmt;
|
|
||||||
|
|||||||
@ -3,5 +3,5 @@
|
|||||||
OMS / 共用库的建表脚本已统一到仓库根目录 `db.sql`。
|
OMS / 共用库的建表脚本已统一到仓库根目录 `db.sql`。
|
||||||
|
|
||||||
- 新环境:直接执行 `db.sql`(会 DROP 后重建,勿在有生产数据的库上执行)
|
- 新环境:直接执行 `db.sql`(会 DROP 后重建,勿在有生产数据的库上执行)
|
||||||
- 已有库:用 diff 对比 `db.sql` 与现库结构后手工 ALTER;本目录下单个表脚本(如 `C_parcel_arrival.sql`、`C_parcel_item_AttributeText.sql`、`C_parcel_item_ImageUrl.sql`)可直接在已有库执行增量建表
|
- 已有库:用 diff 对比 `db.sql` 与现库结构后手工 ALTER;本目录下单个表脚本(如 `c_parcel_arrival.sql`、`c_parcel_item_AttributeText.sql`、`c_parcel_item_ImageUrl.sql`)可直接在已有库执行增量建表;若仍为旧名 `C_*`,先执行 `migrate_rename_warehouse_C_to_c.sql`
|
||||||
- 数据权限表(`user_org_perm` 等)若 RBAC 与 OMS 分库,请只在 RBAC 库执行 `db.sql` 末尾对应段落
|
- 数据权限表(`user_org_perm` 等)若 RBAC 与 OMS 分库,请只在 RBAC 库执行 `db.sql` 末尾对应段落
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
--
|
--
|
||||||
-- 用法:在业务库执行本脚本;若仍报错,把报错 SQL 里的表名追加到下方列表。
|
-- 用法:在业务库执行本脚本;若仍报错,把报错 SQL 里的表名追加到下方列表。
|
||||||
|
|
||||||
SET @tables := 't_order_stock_bind,C_inventory,C_parcel,C_parcel_item,C_parcel_arrival,C_sku,C_bin_location,C_inbound_notice,C_inbound_box,C_inbound_box_line,C_sku_platform_map,t_sales_store,t_sales_store_order,t_sales_store_order_line,t_customer_sender_address';
|
SET @tables := 't_order_stock_bind,c_inventory,c_parcel,c_parcel_item,c_parcel_arrival,c_sku,c_bin_location,c_inbound_notice,c_inbound_box,c_inbound_box_line,c_sku_platform_map,t_sales_store,t_sales_store_order,t_sales_store_order_line,t_customer_sender_address';
|
||||||
|
|
||||||
DROP PROCEDURE IF EXISTS sp_add_concurrency_stamp_if_missing;
|
DROP PROCEDURE IF EXISTS sp_add_concurrency_stamp_if_missing;
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
|
|||||||
34
sql/migrate_rename_warehouse_C_to_c.sql
Normal file
34
sql/migrate_rename_warehouse_C_to_c.sql
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-- 仓储表 C_* → c_*(小写前缀,对齐 t_* 命名风格)
|
||||||
|
-- 可重复执行:源表不存在或目标表已存在则跳过
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS sp_rename_warehouse_table_if_needed;
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE PROCEDURE sp_rename_warehouse_table_if_needed(IN old_name VARCHAR(128), IN new_name VARCHAR(128))
|
||||||
|
BEGIN
|
||||||
|
IF EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = old_name
|
||||||
|
) AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.TABLES
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = new_name
|
||||||
|
) THEN
|
||||||
|
SET @ddl := CONCAT('RENAME TABLE `', old_name, '` TO `', new_name, '`');
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
END IF;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_sku', 'c_sku');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_bin_location', 'c_bin_location');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_inventory', 'c_inventory');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_inbound_notice', 'c_inbound_notice');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_inbound_box', 'c_inbound_box');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_inbound_box_line', 'c_inbound_box_line');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_parcel', 'c_parcel');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_parcel_arrival', 'c_parcel_arrival');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_parcel_item', 'c_parcel_item');
|
||||||
|
CALL sp_rename_warehouse_table_if_needed('C_sku_platform_map', 'c_sku_platform_map');
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS sp_rename_warehouse_table_if_needed;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
-- 物流单绑定包裹/库存:t_order_stock_bind + C_inventory/C_parcel_item 冻结与可用字段
|
-- 物流单绑定包裹/库存:t_order_stock_bind + c_inventory/c_parcel_item 冻结与可用字段
|
||||||
-- 见 oms系统设计-050801.md §4.2.11 / §4.4.6 / §3.1.2
|
-- 见 oms系统设计-050801.md §4.2.11 / §4.4.6 / §3.1.2
|
||||||
-- ConcurrencyStamp 默认用固定 GUID,避免 DEFAULT (UUID()) 触发复制 1674
|
-- ConcurrencyStamp 默认用固定 GUID,避免 DEFAULT (UUID()) 触发复制 1674
|
||||||
-- 可重复执行
|
-- 可重复执行
|
||||||
@ -10,10 +10,10 @@ CREATE TABLE IF NOT EXISTS `t_order_stock_bind` (
|
|||||||
`WarehouseId` INT NOT NULL COMMENT '仓库',
|
`WarehouseId` INT NOT NULL COMMENT '仓库',
|
||||||
`BindType` VARCHAR(20) NOT NULL COMMENT 'inventory / parcelItem',
|
`BindType` VARCHAR(20) NOT NULL COMMENT 'inventory / parcelItem',
|
||||||
`SkuId` INT NULL COMMENT 'SKU',
|
`SkuId` INT NULL COMMENT 'SKU',
|
||||||
`InventoryId` INT NULL COMMENT 'C_inventory.Id,可空=按SKU分摊',
|
`InventoryId` INT NULL COMMENT 'c_inventory.Id,可空=按SKU分摊',
|
||||||
`BinLocationId` INT NULL COMMENT '库位快照',
|
`BinLocationId` INT NULL COMMENT '库位快照',
|
||||||
`ParcelId` INT NULL COMMENT 'C_parcel.Id',
|
`ParcelId` INT NULL COMMENT 'c_parcel.Id',
|
||||||
`ParcelItemId` INT NULL COMMENT 'C_parcel_item.Id',
|
`ParcelItemId` INT NULL COMMENT 'c_parcel_item.Id',
|
||||||
`BindQty` INT NOT NULL COMMENT '绑定数量',
|
`BindQty` INT NOT NULL COMMENT '绑定数量',
|
||||||
`Status` VARCHAR(20) NOT NULL DEFAULT 'bound' COMMENT 'bound/deducted/released',
|
`Status` VARCHAR(20) NOT NULL DEFAULT 'bound' COMMENT 'bound/deducted/released',
|
||||||
`SkuCode` VARCHAR(64) NULL,
|
`SkuCode` VARCHAR(64) NULL,
|
||||||
@ -47,60 +47,74 @@ SET @sql := IF(
|
|||||||
);
|
);
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
-- C_inventory.FrozenQty
|
-- c_inventory.FrozenQty(兼容尚未 rename 的旧表名 C_inventory)
|
||||||
SET @col_exists := (
|
SET @inv_table := IF(
|
||||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'c_inventory'),
|
||||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_inventory' AND COLUMN_NAME = 'FrozenQty'
|
'c_inventory',
|
||||||
|
IF(
|
||||||
|
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_inventory'),
|
||||||
|
'C_inventory',
|
||||||
|
NULL
|
||||||
|
)
|
||||||
);
|
);
|
||||||
SET @sql := IF(
|
SET @col_exists := IF(@inv_table IS NULL, 1,
|
||||||
@col_exists = 0,
|
(SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
'ALTER TABLE `C_inventory` ADD COLUMN `FrozenQty` INT NOT NULL DEFAULT 0 COMMENT ''冻结数量'' AFTER `Qty`',
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @inv_table AND COLUMN_NAME = 'FrozenQty')
|
||||||
'SELECT ''C_inventory.FrozenQty already exists'' AS info'
|
);
|
||||||
|
SET @sql := IF(@inv_table IS NULL OR @col_exists > 0,
|
||||||
|
'SELECT ''c_inventory.FrozenQty already exists or table missing'' AS info',
|
||||||
|
CONCAT('ALTER TABLE `', @inv_table, '` ADD COLUMN `FrozenQty` INT NOT NULL DEFAULT 0 COMMENT ''冻结数量'' AFTER `Qty`')
|
||||||
);
|
);
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
-- C_inventory.AvailableQty
|
SET @col_exists := IF(@inv_table IS NULL, 1,
|
||||||
SET @col_exists := (
|
(SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @inv_table AND COLUMN_NAME = 'AvailableQty')
|
||||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_inventory' AND COLUMN_NAME = 'AvailableQty'
|
|
||||||
);
|
);
|
||||||
SET @sql := IF(
|
SET @sql := IF(@inv_table IS NULL OR @col_exists > 0,
|
||||||
@col_exists = 0,
|
'SELECT ''c_inventory.AvailableQty already exists or table missing'' AS info',
|
||||||
'ALTER TABLE `C_inventory` ADD COLUMN `AvailableQty` INT NOT NULL DEFAULT 0 COMMENT ''可用=Qty-FrozenQty'' AFTER `FrozenQty`',
|
CONCAT('ALTER TABLE `', @inv_table, '` ADD COLUMN `AvailableQty` INT NOT NULL DEFAULT 0 COMMENT ''可用=Qty-FrozenQty'' AFTER `FrozenQty`')
|
||||||
'SELECT ''C_inventory.AvailableQty already exists'' AS info'
|
|
||||||
);
|
);
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
UPDATE `C_inventory`
|
SET @sql := IF(@inv_table IS NULL,
|
||||||
SET `AvailableQty` = GREATEST(0, `Qty` - IFNULL(`FrozenQty`, 0))
|
'SELECT ''c_inventory table missing'' AS info',
|
||||||
WHERE `AvailableQty` <> GREATEST(0, `Qty` - IFNULL(`FrozenQty`, 0))
|
CONCAT('UPDATE `', @inv_table, '` SET `AvailableQty` = GREATEST(0, `Qty` - IFNULL(`FrozenQty`, 0)) WHERE `AvailableQty` <> GREATEST(0, `Qty` - IFNULL(`FrozenQty`, 0)) OR (`AvailableQty` = 0 AND `Qty` > 0 AND IFNULL(`FrozenQty`, 0) = 0)')
|
||||||
OR (`AvailableQty` = 0 AND `Qty` > 0 AND IFNULL(`FrozenQty`, 0) = 0);
|
|
||||||
|
|
||||||
-- C_parcel_item.FrozenQty
|
|
||||||
SET @col_exists := (
|
|
||||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
|
||||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_parcel_item' AND COLUMN_NAME = 'FrozenQty'
|
|
||||||
);
|
|
||||||
SET @sql := IF(
|
|
||||||
@col_exists = 0,
|
|
||||||
'ALTER TABLE `C_parcel_item` ADD COLUMN `FrozenQty` INT NOT NULL DEFAULT 0 COMMENT ''冻结数量'' AFTER `Quantity`',
|
|
||||||
'SELECT ''C_parcel_item.FrozenQty already exists'' AS info'
|
|
||||||
);
|
);
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
-- C_parcel_item.AvailableQty
|
-- c_parcel_item.FrozenQty
|
||||||
SET @col_exists := (
|
SET @pi_table := IF(
|
||||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'c_parcel_item'),
|
||||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_parcel_item' AND COLUMN_NAME = 'AvailableQty'
|
'c_parcel_item',
|
||||||
|
IF(
|
||||||
|
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_parcel_item'),
|
||||||
|
'C_parcel_item',
|
||||||
|
NULL
|
||||||
|
)
|
||||||
);
|
);
|
||||||
SET @sql := IF(
|
SET @col_exists := IF(@pi_table IS NULL, 1,
|
||||||
@col_exists = 0,
|
(SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
'ALTER TABLE `C_parcel_item` ADD COLUMN `AvailableQty` INT NOT NULL DEFAULT 0 COMMENT ''可用=Quantity-FrozenQty'' AFTER `FrozenQty`',
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @pi_table AND COLUMN_NAME = 'FrozenQty')
|
||||||
'SELECT ''C_parcel_item.AvailableQty already exists'' AS info'
|
);
|
||||||
|
SET @sql := IF(@pi_table IS NULL OR @col_exists > 0,
|
||||||
|
'SELECT ''c_parcel_item.FrozenQty already exists or table missing'' AS info',
|
||||||
|
CONCAT('ALTER TABLE `', @pi_table, '` ADD COLUMN `FrozenQty` INT NOT NULL DEFAULT 0 COMMENT ''冻结数量'' AFTER `Quantity`')
|
||||||
);
|
);
|
||||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
UPDATE `C_parcel_item`
|
SET @col_exists := IF(@pi_table IS NULL, 1,
|
||||||
SET `AvailableQty` = GREATEST(0, `Quantity` - IFNULL(`FrozenQty`, 0))
|
(SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
WHERE `AvailableQty` <> GREATEST(0, `Quantity` - IFNULL(`FrozenQty`, 0))
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @pi_table AND COLUMN_NAME = 'AvailableQty')
|
||||||
OR (`AvailableQty` = 0 AND `Quantity` > 0 AND IFNULL(`FrozenQty`, 0) = 0);
|
);
|
||||||
|
SET @sql := IF(@pi_table IS NULL OR @col_exists > 0,
|
||||||
|
'SELECT ''c_parcel_item.AvailableQty already exists or table missing'' AS info',
|
||||||
|
CONCAT('ALTER TABLE `', @pi_table, '` ADD COLUMN `AvailableQty` INT NOT NULL DEFAULT 0 COMMENT ''可用=Quantity-FrozenQty'' AFTER `FrozenQty`')
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
SET @sql := IF(@pi_table IS NULL,
|
||||||
|
'SELECT ''c_parcel_item table missing'' AS info',
|
||||||
|
CONCAT('UPDATE `', @pi_table, '` SET `AvailableQty` = GREATEST(0, `Quantity` - IFNULL(`FrozenQty`, 0)) WHERE `AvailableQty` <> GREATEST(0, `Quantity` - IFNULL(`FrozenQty`, 0)) OR (`AvailableQty` = 0 AND `Quantity` > 0 AND IFNULL(`FrozenQty`, 0) = 0)')
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||||
|
|||||||
@ -40,6 +40,8 @@ public class OrderBatchImportRowPayload
|
|||||||
|
|
||||||
public int TemplateId { get; set; }
|
public int TemplateId { get; set; }
|
||||||
|
|
||||||
|
public int? CustomerSenderAddressId { get; set; }
|
||||||
|
|
||||||
public string RowDataJson { get; set; } = string.Empty;
|
public string RowDataJson { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,4 +55,9 @@ public class OrderBatchImportJobPayload
|
|||||||
public int TemplateId { get; set; }
|
public int TemplateId { get; set; }
|
||||||
|
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量导入统一使用的默认发件地址。
|
||||||
|
/// </summary>
|
||||||
|
public int? CustomerSenderAddressId { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,8 @@ public class OrderTemplateFieldSchemaItemOutput
|
|||||||
public string Group { get; set; } = string.Empty;
|
public string Group { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string Example { get; set; } = string.Empty;
|
public string Example { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Hint { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OrderTemplateDictOptionsOutput
|
public class OrderTemplateDictOptionsOutput
|
||||||
|
|||||||
@ -16,4 +16,9 @@ public class OrderUploadInput
|
|||||||
/// 模板主键。
|
/// 模板主键。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TemplateId { get; set; }
|
public int TemplateId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认发件地址 ID(地址管理中的发件人地址)。
|
||||||
|
/// </summary>
|
||||||
|
public int? SenderAddressId { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,21 @@ public partial class OrderService
|
|||||||
?? throw new BusinessException("行数据无效");
|
?? throw new BusinessException("行数据无效");
|
||||||
|
|
||||||
var input = OrderTemplateRowMapper.MapToParcelCreateInput(sourceValues, mapping, payload.CustomerId);
|
var input = OrderTemplateRowMapper.MapToParcelCreateInput(sourceValues, mapping, payload.CustomerId);
|
||||||
return await CreateParcelForBatchAsync(input, operatorUserId, cancellationToken);
|
if (payload.CustomerSenderAddressId is > 0)
|
||||||
|
{
|
||||||
|
await ApplyCustomerSenderAddressToParcelInputAsync(
|
||||||
|
input,
|
||||||
|
payload.CustomerId,
|
||||||
|
payload.CustomerSenderAddressId.Value,
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await CreateParcelForBatchAsync(
|
||||||
|
input,
|
||||||
|
operatorUserId,
|
||||||
|
orderSource: null,
|
||||||
|
customerSenderAddressId: payload.CustomerSenderAddressId,
|
||||||
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int?> TryResolveImportOrderIdAsync(
|
public async Task<int?> TryResolveImportOrderIdAsync(
|
||||||
@ -78,24 +92,42 @@ public partial class OrderService
|
|||||||
int operatorUserId,
|
int operatorUserId,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await CreateParcelForBatchAsync(input, operatorUserId, orderSource: null, cancellationToken);
|
return await CreateParcelForBatchAsync(input, operatorUserId, orderSource: null, customerSenderAddressId: null, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量 Worker 创建小包订单(可指定 <paramref name="orderSource"/> 与默认发件地址)。
|
||||||
|
/// </summary>
|
||||||
|
public async Task<OrderParcelCreateOutput> CreateParcelForBatchAsync(
|
||||||
|
OrderParcelCreateInput input,
|
||||||
|
int operatorUserId,
|
||||||
|
string? orderSource,
|
||||||
|
int? customerSenderAddressId,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
ParcelCreateContext? createContext = null;
|
||||||
|
if (!string.IsNullOrWhiteSpace(orderSource) || customerSenderAddressId is > 0)
|
||||||
|
{
|
||||||
|
createContext = new ParcelCreateContext
|
||||||
|
{
|
||||||
|
OrderSource = string.IsNullOrWhiteSpace(orderSource) ? null : orderSource.Trim(),
|
||||||
|
CustomerSenderAddressId = customerSenderAddressId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return await CreateParcelCoreAsync(input, operatorUserId, createContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 批量 Worker 创建小包订单(可指定 <paramref name="orderSource"/>)。
|
/// 批量 Worker 创建小包订单(可指定 <paramref name="orderSource"/>)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Use CreateParcelForBatchAsync with customerSenderAddressId when importing.")]
|
||||||
public async Task<OrderParcelCreateOutput> CreateParcelForBatchAsync(
|
public async Task<OrderParcelCreateOutput> CreateParcelForBatchAsync(
|
||||||
OrderParcelCreateInput input,
|
OrderParcelCreateInput input,
|
||||||
int operatorUserId,
|
int operatorUserId,
|
||||||
string? orderSource,
|
string? orderSource,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
ParcelCreateContext? createContext = null;
|
return await CreateParcelForBatchAsync(input, operatorUserId, orderSource, null, cancellationToken);
|
||||||
if (!string.IsNullOrWhiteSpace(orderSource))
|
|
||||||
{
|
|
||||||
createContext = new ParcelCreateContext { OrderSource = orderSource.Trim() };
|
|
||||||
}
|
|
||||||
|
|
||||||
return await CreateParcelCoreAsync(input, operatorUserId, createContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -380,6 +380,11 @@ public partial class OrderService
|
|||||||
throw new BusinessException($"单次最多导入 {ParcelBatchMaxCount} 行");
|
throw new BusinessException($"单次最多导入 {ParcelBatchMaxCount} 行");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var senderAddressId = await ResolveImportSenderAddressIdAsync(
|
||||||
|
effectiveCustomer.Id,
|
||||||
|
input.SenderAddressId,
|
||||||
|
cancellationToken: default);
|
||||||
|
|
||||||
var taskName = $"批量下单_{DateTime.Now:yyyyMMddHHmmss}";
|
var taskName = $"批量下单_{DateTime.Now:yyyyMMddHHmmss}";
|
||||||
var requestId = $"import-{effectiveCustomer.Id}-{template.Id}-{DateTime.Now:yyyyMMddHHmmssfff}";
|
var requestId = $"import-{effectiveCustomer.Id}-{template.Id}-{DateTime.Now:yyyyMMddHHmmssfff}";
|
||||||
|
|
||||||
@ -388,6 +393,7 @@ public partial class OrderService
|
|||||||
TaskName = taskName,
|
TaskName = taskName,
|
||||||
TemplateId = template.Id,
|
TemplateId = template.Id,
|
||||||
CustomerId = effectiveCustomer.Id,
|
CustomerId = effectiveCustomer.Id,
|
||||||
|
CustomerSenderAddressId = senderAddressId,
|
||||||
});
|
});
|
||||||
|
|
||||||
var payloadItems = parsedRows.Select(row =>
|
var payloadItems = parsedRows.Select(row =>
|
||||||
@ -404,6 +410,7 @@ public partial class OrderService
|
|||||||
RowNumber = row.RowNumber,
|
RowNumber = row.RowNumber,
|
||||||
CustomerId = effectiveCustomer.Id,
|
CustomerId = effectiveCustomer.Id,
|
||||||
TemplateId = template.Id,
|
TemplateId = template.Id,
|
||||||
|
CustomerSenderAddressId = senderAddressId,
|
||||||
RowDataJson = JsonConvert.SerializeObject(row.SourceValues),
|
RowDataJson = JsonConvert.SerializeObject(row.SourceValues),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -298,4 +298,76 @@ public partial class OrderService
|
|||||||
{
|
{
|
||||||
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<int> ResolveImportSenderAddressIdAsync(
|
||||||
|
int customerId,
|
||||||
|
int? senderAddressId,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (senderAddressId is > 0)
|
||||||
|
{
|
||||||
|
var specified = await CustomerSenderAddressRepository.GetOwnedAsync(senderAddressId.Value, customerId, cancellationToken)
|
||||||
|
?? throw new BusinessException("发件地址不存在");
|
||||||
|
EnsureSenderAddressType(specified);
|
||||||
|
return specified.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultAddress = await CustomerSenderAddressRepository.FirstOrDefaultAsync(
|
||||||
|
x => x.CustomerId == customerId
|
||||||
|
&& x.AddressType == CustomerAddressTypeCodes.Sender
|
||||||
|
&& x.IsDefault > 0,
|
||||||
|
cancellationToken);
|
||||||
|
if (defaultAddress != null)
|
||||||
|
{
|
||||||
|
return defaultAddress.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new BusinessException("请先在批量下单页选择默认发件地址,或在地址管理中设置默认发件地址");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureSenderAddressType(CustomerSenderAddress address)
|
||||||
|
{
|
||||||
|
var addressType = string.IsNullOrWhiteSpace(address.AddressType)
|
||||||
|
? CustomerAddressTypeCodes.Sender
|
||||||
|
: address.AddressType;
|
||||||
|
if (!string.Equals(addressType, CustomerAddressTypeCodes.Sender, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
throw new BusinessException("请选择发件类型地址");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ApplyCustomerSenderAddressToParcelInputAsync(
|
||||||
|
OrderParcelCreateInput input,
|
||||||
|
int customerId,
|
||||||
|
int senderAddressId,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var address = await CustomerSenderAddressRepository.GetOwnedAsync(senderAddressId, customerId, cancellationToken)
|
||||||
|
?? throw new BusinessException("发件地址不存在");
|
||||||
|
EnsureSenderAddressType(address);
|
||||||
|
|
||||||
|
string? countryCode = null;
|
||||||
|
if (address.Country.HasValue)
|
||||||
|
{
|
||||||
|
var country = await CountryRepository.FirstOrDefaultAsync(x => x.Id == address.Country.Value, cancellationToken);
|
||||||
|
countryCode = country?.CountryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.Sender = new OrderParcelSenderInput
|
||||||
|
{
|
||||||
|
SenderName = address.SenderName,
|
||||||
|
Company = address.Company,
|
||||||
|
Phone = address.Phone,
|
||||||
|
TelePhone = address.TelePhone,
|
||||||
|
Email = address.Email,
|
||||||
|
CountryCode = countryCode ?? "CN",
|
||||||
|
Province = address.Province,
|
||||||
|
City = address.City,
|
||||||
|
ZipCode = address.ZipCode,
|
||||||
|
StreetAddress1 = address.StreetAddress1,
|
||||||
|
StreetAddress2 = address.StreetAddress2,
|
||||||
|
StreetAddress3 = address.StreetAddress3,
|
||||||
|
HouseNumber = address.HouseNumber,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,12 +17,12 @@ public partial class OrderService
|
|||||||
[HttpGet("/order/template/field-schema")]
|
[HttpGet("/order/template/field-schema")]
|
||||||
public Task<OrderTemplateFieldSchemaOutput> GetTemplateFieldSchemaAsync([FromQuery] string? templateKey)
|
public Task<OrderTemplateFieldSchemaOutput> GetTemplateFieldSchemaAsync([FromQuery] string? templateKey)
|
||||||
{
|
{
|
||||||
var key = string.IsNullOrWhiteSpace(templateKey) ? OrderTemplateKeys.DedicatedSmallParcel : templateKey.Trim();
|
var key = string.IsNullOrWhiteSpace(templateKey) ? OrderTemplateKeys.DedicatedSmallParcelStandard : templateKey.Trim();
|
||||||
var fields = OrderTemplateFieldRegistry.GetFields(key);
|
var fields = OrderTemplateFieldRegistry.GetFields(key);
|
||||||
return Task.FromResult(new OrderTemplateFieldSchemaOutput
|
return Task.FromResult(new OrderTemplateFieldSchemaOutput
|
||||||
{
|
{
|
||||||
TemplateKey = key,
|
TemplateKey = key,
|
||||||
TemplateName = key == OrderTemplateKeys.DedicatedSmallParcel ? "专线小包模板" : key,
|
TemplateName = OrderTemplateFieldRegistry.GetTemplateDisplayName(key),
|
||||||
Fields = fields.Select(MapFieldSchemaItem).ToList()
|
Fields = fields.Select(MapFieldSchemaItem).ToList()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -79,13 +79,13 @@ public partial class OrderService
|
|||||||
customerId,
|
customerId,
|
||||||
WebHostEnvironment);
|
WebHostEnvironment);
|
||||||
|
|
||||||
var suggested = OrderTemplateHeaderMatcher.BuildSuggestedMapping(OrderTemplateKeys.DedicatedSmallParcel, headers);
|
var suggested = OrderTemplateHeaderMatcher.BuildSuggestedMapping(OrderTemplateKeys.DedicatedSmallParcelStandard, headers);
|
||||||
var entity = new OrderTemplate
|
var entity = new OrderTemplate
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
Type = "custom",
|
Type = "custom",
|
||||||
TemplateKey = $"custom_{Guid.NewGuid():N}".Substring(0, 24),
|
TemplateKey = $"custom_{Guid.NewGuid():N}".Substring(0, 24),
|
||||||
StandardTemplateKey = OrderTemplateKeys.DedicatedSmallParcel,
|
StandardTemplateKey = OrderTemplateKeys.DedicatedSmallParcelStandard,
|
||||||
MappingStatus = OrderTemplateMappingStatus.Draft,
|
MappingStatus = OrderTemplateMappingStatus.Draft,
|
||||||
CustomerId = customerId,
|
CustomerId = customerId,
|
||||||
SourceFileName = originalName,
|
SourceFileName = originalName,
|
||||||
@ -236,23 +236,39 @@ public partial class OrderService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 列表查询前确保标准「专线小包模板」存在(未执行种子脚本时自动补齐)。
|
/// 列表查询前确保标准「专线小包」精简版与标准版模板存在。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task EnsureDedicatedSmallParcelStandardTemplateAsync()
|
private async Task EnsureDedicatedSmallParcelStandardTemplateAsync()
|
||||||
|
{
|
||||||
|
await EnsureBuiltinStandardTemplateAsync(
|
||||||
|
OrderTemplateKeys.DedicatedSmallParcelStandard,
|
||||||
|
"专线小包模板(标准版)");
|
||||||
|
await EnsureBuiltinStandardTemplateAsync(
|
||||||
|
OrderTemplateKeys.DedicatedSmallParcelSimple,
|
||||||
|
"专线小包模板(精简版)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EnsureBuiltinStandardTemplateAsync(string templateKey, string name)
|
||||||
{
|
{
|
||||||
var existing = await OrderTemplateRepository.FirstOrDefaultAsync(x =>
|
var existing = await OrderTemplateRepository.FirstOrDefaultAsync(x =>
|
||||||
x.Type == "standard" && x.TemplateKey == OrderTemplateKeys.DedicatedSmallParcel);
|
x.Type == "standard" && x.TemplateKey == templateKey);
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
|
if (!string.Equals(existing.Name, name, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
existing.Name = name;
|
||||||
|
await OrderTemplateRepository.UpdateAsync(existing);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await OrderTemplateRepository.InsertAsync(new OrderTemplate
|
await OrderTemplateRepository.InsertAsync(new OrderTemplate
|
||||||
{
|
{
|
||||||
Name = "专线小包模板",
|
Name = name,
|
||||||
Type = "standard",
|
Type = "standard",
|
||||||
TemplateKey = OrderTemplateKeys.DedicatedSmallParcel,
|
TemplateKey = templateKey,
|
||||||
StandardTemplateKey = OrderTemplateKeys.DedicatedSmallParcel,
|
StandardTemplateKey = templateKey,
|
||||||
MappingStatus = OrderTemplateMappingStatus.Ready,
|
MappingStatus = OrderTemplateMappingStatus.Ready,
|
||||||
CustomerId = null,
|
CustomerId = null,
|
||||||
});
|
});
|
||||||
@ -283,7 +299,8 @@ public partial class OrderService
|
|||||||
DataType = field.DataType,
|
DataType = field.DataType,
|
||||||
DictType = field.DictType,
|
DictType = field.DictType,
|
||||||
Group = field.Group,
|
Group = field.Group,
|
||||||
Example = field.Example
|
Example = field.Example,
|
||||||
|
Hint = field.Hint,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static List<string> DeserializeStringList(string? json)
|
private static List<string> DeserializeStringList(string? json)
|
||||||
|
|||||||
@ -26,7 +26,21 @@ public static class OrderTemplateExcelGenerator
|
|||||||
emptyDataRow[field.Label] = string.Empty;
|
emptyDataRow[field.Label] = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
var guideRows = fields.Select(f => new Dictionary<string, object?>
|
var guideIntro = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["列名"] = "【填写说明】",
|
||||||
|
["字段Key"] = string.Empty,
|
||||||
|
["是否必填"] = string.Empty,
|
||||||
|
["数据类型"] = string.Empty,
|
||||||
|
["字典类型"] = string.Empty,
|
||||||
|
["可选值"] = string.Empty,
|
||||||
|
["分组"] = string.Empty,
|
||||||
|
["示例"] = string.Empty,
|
||||||
|
["填写说明"] = BuildGuideIntroText(templateKey),
|
||||||
|
};
|
||||||
|
|
||||||
|
var guideRows = new List<Dictionary<string, object?>> { guideIntro };
|
||||||
|
guideRows.AddRange(fields.Select(f => new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["列名"] = f.Label,
|
["列名"] = f.Label,
|
||||||
["字段Key"] = f.FieldKey,
|
["字段Key"] = f.FieldKey,
|
||||||
@ -34,9 +48,10 @@ public static class OrderTemplateExcelGenerator
|
|||||||
["数据类型"] = f.DataType,
|
["数据类型"] = f.DataType,
|
||||||
["字典类型"] = f.DictType ?? string.Empty,
|
["字典类型"] = f.DictType ?? string.Empty,
|
||||||
["可选值"] = BuildGuideOptionText(f, dictOptions ?? []),
|
["可选值"] = BuildGuideOptionText(f, dictOptions ?? []),
|
||||||
["分组"] = f.Group,
|
["分组"] = MapGroupLabel(f.Group),
|
||||||
["示例"] = f.Example
|
["示例"] = f.Example,
|
||||||
}).ToList();
|
["填写说明"] = string.IsNullOrWhiteSpace(f.Hint) ? f.Example : f.Hint,
|
||||||
|
}));
|
||||||
|
|
||||||
var dictRows = (dictOptions ?? [])
|
var dictRows = (dictOptions ?? [])
|
||||||
.Select(x => new Dictionary<string, object?>
|
.Select(x => new Dictionary<string, object?>
|
||||||
@ -91,4 +106,24 @@ public static class OrderTemplateExcelGenerator
|
|||||||
|
|
||||||
return options.Count == 0 ? string.Empty : string.Join(";", options);
|
return options.Count == 0 ? string.Empty : string.Join(";", options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string MapGroupLabel(string group) =>
|
||||||
|
group switch
|
||||||
|
{
|
||||||
|
"basic" => "订单信息",
|
||||||
|
"receiver" => "收件人",
|
||||||
|
"declaration" => "申报",
|
||||||
|
_ => group,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string BuildGuideIntroText(string templateKey)
|
||||||
|
{
|
||||||
|
var common = "红色表头为必填;带下拉的列请点选编码;发件人请在网页批量下单页选择默认地址,无需在 Excel 填写。";
|
||||||
|
if (OrderTemplateFieldRegistry.IsSimpleTemplate(templateKey))
|
||||||
|
{
|
||||||
|
return $"【精简版】仅含日常批量所需核心列,推荐大多数客户使用。{common}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"【标准版】含 COD、税号、申报扩展字段等不常用列,有特殊清关/平台要求时使用。{common}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,8 @@ internal static class OrderTemplateExcelOpenXmlEnhancer
|
|||||||
{
|
{
|
||||||
private const uint DataValidationStartRow = 2;
|
private const uint DataValidationStartRow = 2;
|
||||||
private const uint DataValidationEndRow = 5000;
|
private const uint DataValidationEndRow = 5000;
|
||||||
private const string YellowHeaderRgb = "FFFFFF00";
|
private const string RequiredHeaderFillRgb = "FFFFE5E5";
|
||||||
|
private const string RequiredHeaderFontRgb = "FFC00000";
|
||||||
|
|
||||||
public static byte[] Enhance(
|
public static byte[] Enhance(
|
||||||
byte[] workbookBytes,
|
byte[] workbookBytes,
|
||||||
@ -96,6 +97,10 @@ internal static class OrderTemplateExcelOpenXmlEnhancer
|
|||||||
AllowBlank = !field.Required,
|
AllowBlank = !field.Required,
|
||||||
ShowInputMessage = true,
|
ShowInputMessage = true,
|
||||||
ShowErrorMessage = true,
|
ShowErrorMessage = true,
|
||||||
|
ErrorTitle = "输入无效",
|
||||||
|
Error = field.Required ? "请从下拉列表选择或填写有效值" : "请填写有效值",
|
||||||
|
PromptTitle = field.Label,
|
||||||
|
Prompt = BuildValidationPrompt(field),
|
||||||
SequenceOfReferences = new ListValue<StringValue>
|
SequenceOfReferences = new ListValue<StringValue>
|
||||||
{
|
{
|
||||||
InnerText = $"{columnName}{DataValidationStartRow}:{columnName}{DataValidationEndRow}"
|
InnerText = $"{columnName}{DataValidationStartRow}:{columnName}{DataValidationEndRow}"
|
||||||
@ -130,6 +135,21 @@ internal static class OrderTemplateExcelOpenXmlEnhancer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string BuildValidationPrompt(OrderTemplateFieldDefinition field)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(field.Hint))
|
||||||
|
{
|
||||||
|
return field.Hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(field.DataType, "boolean", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return "填写 true 或 false";
|
||||||
|
}
|
||||||
|
|
||||||
|
return field.Required ? "必填" : "选填";
|
||||||
|
}
|
||||||
|
|
||||||
private static Dictionary<string, string> BuildDictTypeRanges(
|
private static Dictionary<string, string> BuildDictTypeRanges(
|
||||||
WorkbookPart workbookPart,
|
WorkbookPart workbookPart,
|
||||||
IReadOnlyList<OrderTemplateDictOption> dictOptions)
|
IReadOnlyList<OrderTemplateDictOption> dictOptions)
|
||||||
@ -255,20 +275,22 @@ internal static class OrderTemplateExcelOpenXmlEnhancer
|
|||||||
cellFormats.Count = 1;
|
cellFormats.Count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var yellowFill = new Fill
|
var requiredFill = new Fill
|
||||||
{
|
{
|
||||||
PatternFill = new PatternFill
|
PatternFill = new PatternFill
|
||||||
{
|
{
|
||||||
PatternType = PatternValues.Solid,
|
PatternType = PatternValues.Solid,
|
||||||
ForegroundColor = new ForegroundColor { Rgb = YellowHeaderRgb },
|
ForegroundColor = new ForegroundColor { Rgb = RequiredHeaderFillRgb },
|
||||||
BackgroundColor = new BackgroundColor { Indexed = 64 }
|
BackgroundColor = new BackgroundColor { Indexed = 64 }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fills.Append(yellowFill);
|
fills.Append(requiredFill);
|
||||||
var yellowFillId = (uint)fills.ChildElements.Count - 1;
|
var requiredFillId = (uint)fills.ChildElements.Count - 1;
|
||||||
fills.Count = (uint)fills.ChildElements.Count;
|
fills.Count = (uint)fills.ChildElements.Count;
|
||||||
|
|
||||||
var headerFont = new Font(new Bold());
|
var headerFont = new Font(
|
||||||
|
new Bold(),
|
||||||
|
new Color { Rgb = RequiredHeaderFontRgb });
|
||||||
fonts.Append(headerFont);
|
fonts.Append(headerFont);
|
||||||
var headerFontId = (uint)fonts.ChildElements.Count - 1;
|
var headerFontId = (uint)fonts.ChildElements.Count - 1;
|
||||||
fonts.Count = (uint)fonts.ChildElements.Count;
|
fonts.Count = (uint)fonts.ChildElements.Count;
|
||||||
@ -276,7 +298,7 @@ internal static class OrderTemplateExcelOpenXmlEnhancer
|
|||||||
var headerFormat = new CellFormat
|
var headerFormat = new CellFormat
|
||||||
{
|
{
|
||||||
FontId = headerFontId,
|
FontId = headerFontId,
|
||||||
FillId = yellowFillId,
|
FillId = requiredFillId,
|
||||||
BorderId = 0,
|
BorderId = 0,
|
||||||
ApplyFont = true,
|
ApplyFont = true,
|
||||||
ApplyFill = true
|
ApplyFill = true
|
||||||
|
|||||||
@ -2,7 +2,14 @@ namespace Oms.Application.Services.Orders.Templates;
|
|||||||
|
|
||||||
public static class OrderTemplateKeys
|
public static class OrderTemplateKeys
|
||||||
{
|
{
|
||||||
public const string DedicatedSmallParcel = "dedicated_small_parcel_v1";
|
/// <summary>专线小包标准版(含扩展字段)。</summary>
|
||||||
|
public const string DedicatedSmallParcelStandard = "dedicated_small_parcel_v1";
|
||||||
|
|
||||||
|
/// <summary>专线小包精简版(日常批量推荐)。</summary>
|
||||||
|
public const string DedicatedSmallParcelSimple = "dedicated_small_parcel_simple_v1";
|
||||||
|
|
||||||
|
/// <summary>自定义模板字段映射默认对齐标准版字段集。</summary>
|
||||||
|
public const string DedicatedSmallParcel = DedicatedSmallParcelStandard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OrderTemplateMappingStatus
|
public static class OrderTemplateMappingStatus
|
||||||
@ -20,20 +27,37 @@ public sealed class OrderTemplateFieldDefinition
|
|||||||
public string? DictType { get; init; }
|
public string? DictType { get; init; }
|
||||||
public string Group { get; init; } = string.Empty;
|
public string Group { get; init; } = string.Empty;
|
||||||
public string Example { get; init; } = string.Empty;
|
public string Example { get; init; } = string.Empty;
|
||||||
|
public string Hint { get; init; } = string.Empty;
|
||||||
public int Sort { get; init; }
|
public int Sort { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OrderTemplateFieldRegistry
|
public static class OrderTemplateFieldRegistry
|
||||||
{
|
{
|
||||||
private static readonly IReadOnlyList<OrderTemplateFieldDefinition> DedicatedSmallParcelFields = BuildDedicatedSmallParcelFields();
|
private static readonly IReadOnlyList<OrderTemplateFieldDefinition> SimpleFields = BuildDedicatedSmallParcelSimpleFields();
|
||||||
|
private static readonly IReadOnlyList<OrderTemplateFieldDefinition> StandardFields = BuildDedicatedSmallParcelStandardFields();
|
||||||
|
|
||||||
|
public static string GetTemplateDisplayName(string? templateKey)
|
||||||
|
{
|
||||||
|
var key = NormalizeTemplateKey(templateKey);
|
||||||
|
return key switch
|
||||||
|
{
|
||||||
|
OrderTemplateKeys.DedicatedSmallParcelSimple => "专线小包模板(精简版)",
|
||||||
|
OrderTemplateKeys.DedicatedSmallParcelStandard => "专线小包模板(标准版)",
|
||||||
|
_ => key,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsSimpleTemplate(string? templateKey) =>
|
||||||
|
string.Equals(NormalizeTemplateKey(templateKey), OrderTemplateKeys.DedicatedSmallParcelSimple, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public static IReadOnlyList<OrderTemplateFieldDefinition> GetFields(string? templateKey)
|
public static IReadOnlyList<OrderTemplateFieldDefinition> GetFields(string? templateKey)
|
||||||
{
|
{
|
||||||
var key = string.IsNullOrWhiteSpace(templateKey) ? OrderTemplateKeys.DedicatedSmallParcel : templateKey.Trim();
|
var key = NormalizeTemplateKey(templateKey);
|
||||||
return key switch
|
return key switch
|
||||||
{
|
{
|
||||||
OrderTemplateKeys.DedicatedSmallParcel => DedicatedSmallParcelFields,
|
OrderTemplateKeys.DedicatedSmallParcelSimple => SimpleFields,
|
||||||
_ => DedicatedSmallParcelFields
|
OrderTemplateKeys.DedicatedSmallParcelStandard => StandardFields,
|
||||||
|
_ => StandardFields,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +72,22 @@ public static class OrderTemplateFieldRegistry
|
|||||||
string.Equals(x.FieldKey, fieldKey.Trim(), StringComparison.OrdinalIgnoreCase));
|
string.Equals(x.FieldKey, fieldKey.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IReadOnlyList<OrderTemplateFieldDefinition> BuildDedicatedSmallParcelFields()
|
private static string NormalizeTemplateKey(string? templateKey) =>
|
||||||
|
string.IsNullOrWhiteSpace(templateKey) ? OrderTemplateKeys.DedicatedSmallParcelStandard : templateKey.Trim();
|
||||||
|
|
||||||
|
private static IReadOnlyList<OrderTemplateFieldDefinition> BuildDedicatedSmallParcelSimpleFields()
|
||||||
{
|
{
|
||||||
var list = new List<OrderTemplateFieldDefinition>();
|
var list = new List<OrderTemplateFieldDefinition>();
|
||||||
var sort = 0;
|
var sort = 0;
|
||||||
void Add(string key, string label, bool required, string dataType = "string", string? dictType = null, string group = "basic", string example = "")
|
void Add(
|
||||||
|
string key,
|
||||||
|
string label,
|
||||||
|
bool required,
|
||||||
|
string dataType = "string",
|
||||||
|
string? dictType = null,
|
||||||
|
string group = "basic",
|
||||||
|
string example = "",
|
||||||
|
string hint = "")
|
||||||
{
|
{
|
||||||
sort += 10;
|
sort += 10;
|
||||||
list.Add(new OrderTemplateFieldDefinition
|
list.Add(new OrderTemplateFieldDefinition
|
||||||
@ -64,87 +99,133 @@ public static class OrderTemplateFieldRegistry
|
|||||||
DictType = dictType,
|
DictType = dictType,
|
||||||
Group = group,
|
Group = group,
|
||||||
Example = example,
|
Example = example,
|
||||||
Sort = sort
|
Hint = hint,
|
||||||
|
Sort = sort,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Add("requestId", "幂等请求ID", false);
|
Add("clientNo", "客户单号", true, example: "C202604230001", hint: "您自己的订单编号,同一客户不可重复");
|
||||||
Add("clientNo", "客户单号", true, example: "C202604230001");
|
Add("productCode", "运输方式", true, "select", "sales_product", "basic", "PROD001", hint: "从下拉选择产品编码(与查价一致)");
|
||||||
Add("productCode", "运输方式", true, "select", "sales_product", "basic", "PROD001");
|
Add("cargoAttribute", "货物属性", true, "select", "cargo_attribute", "basic", "general", hint: "普货选 general,带电/敏感品选对应用编码");
|
||||||
Add("cargoAttribute", "货物属性", true, "select", "cargo_attribute", "basic", "general");
|
Add("warehouseId", "发货仓库", true, "select", "warehouse", "basic", "1", hint: "从下拉选择发货仓库 ID");
|
||||||
Add("exportCustomsMode", "出口报关方式", false, "select", "export_customs_mode", "basic", "9610Simple");
|
Add("actualWeight", "实重(kg)", true, "number", example: "1.2", hint: "包裹实际重量,单位千克");
|
||||||
Add("warehouseId", "仓库", true, "select", "warehouse", "basic", "1");
|
Add("quantity", "包裹件数", true, "number", example: "1", hint: "一般为 1");
|
||||||
Add("length", "长(cm)", false, "number", example: "10");
|
Add("length", "长(cm)", false, "number", example: "10", hint: "选填,用于材积计费");
|
||||||
Add("width", "宽(cm)", false, "number", example: "10");
|
Add("width", "宽(cm)", false, "number", example: "10", hint: "选填,用于材积计费");
|
||||||
Add("height", "高(cm)", false, "number", example: "10");
|
Add("height", "高(cm)", false, "number", example: "10", hint: "选填,用于材积计费");
|
||||||
Add("actualWeight", "实重(kg)", true, "number", example: "1.2");
|
Add("exportCustomsMode", "出口报关", false, "select", "export_customs_mode", "basic", "9610Simple", hint: "不选则按简易申报");
|
||||||
Add("isCod", "是否COD", false, "boolean", example: "false");
|
|
||||||
Add("codCurrency", "COD币种", false, "select", "currency", example: "USD");
|
|
||||||
Add("codSum", "COD金额", false, "number", example: "0");
|
|
||||||
Add("quantity", "包裹数量", true, "number", example: "1");
|
|
||||||
|
|
||||||
Add("receiver.recipientsName", "收件人名称", true, group: "receiver", example: "Demo Receiver");
|
Add("receiver.recipientsName", "收件人姓名", true, group: "receiver", example: "John Smith", hint: "必填");
|
||||||
Add("receiver.companyName", "收件人公司", false, group: "receiver", example: "Demo Receiver LLC");
|
Add("receiver.phone", "收件人手机", true, group: "receiver", example: "13900139000", hint: "必填");
|
||||||
Add("receiver.phone", "收件人手机", true, group: "receiver", example: "13900139000");
|
Add("receiver.countryCode", "目的国代码", true, group: "receiver", example: "US", hint: "二字码,如 US、GB");
|
||||||
Add("receiver.telePhone", "收件人电话", false, group: "receiver");
|
Add("receiver.province", "省/州", false, group: "receiver", example: "California", hint: "建议填写");
|
||||||
Add("receiver.email", "收件人邮箱", false, group: "receiver", example: "receiver@example.com");
|
Add("receiver.city", "城市", false, group: "receiver", example: "Los Angeles", hint: "建议填写");
|
||||||
Add("receiver.countryCode", "收件国家代码", true, group: "receiver", example: "US");
|
Add("receiver.streetAddress1", "详细地址", true, group: "receiver", example: "100 Main St", hint: "街道门牌等主地址");
|
||||||
Add("receiver.province", "收件省/州", false, group: "receiver", example: "California");
|
Add("receiver.zipCode", "邮编", true, group: "receiver", example: "90001", hint: "必填");
|
||||||
Add("receiver.city", "收件城市", false, group: "receiver", example: "Los Angeles");
|
Add("receiver.companyName", "收件公司", false, group: "receiver", example: "Demo LLC", hint: "选填");
|
||||||
Add("receiver.streetNumber", "收件人门牌号", false, group: "receiver", example: "1001");
|
|
||||||
Add("receiver.streetAddress1", "收件地址1", true, group: "receiver", example: "Sunset Blvd");
|
|
||||||
Add("receiver.streetAddress2", "收件地址2", false, group: "receiver");
|
|
||||||
Add("receiver.streetAddress3", "收件地址3", false, group: "receiver");
|
|
||||||
Add("receiver.zipCode", "收件邮编", true, group: "receiver", example: "90001");
|
|
||||||
Add("receiver.taxType", "税号类型", false, group: "receiver", example: "0");
|
|
||||||
Add("receiver.taxNo", "税号", false, group: "receiver");
|
|
||||||
Add("receiver.certificateType", "证件类型", false, group: "receiver", example: "0");
|
|
||||||
Add("receiver.certificateNo", "证件号码", false, group: "receiver");
|
|
||||||
Add("receiver.eori", "EORI", false, group: "receiver");
|
|
||||||
Add("receiver.vat", "VAT", false, group: "receiver");
|
|
||||||
|
|
||||||
Add("sender.senderName", "发件人姓名", false, group: "sender", example: "Demo Sender");
|
Add("declaredCurrency", "申报币种", true, "select", "currency", "declaration", "USD", hint: "默认 USD");
|
||||||
Add("sender.company", "发件人公司", false, group: "sender", example: "Demo Sender Co.,Ltd");
|
Add("items[0].cnName", "申报品名(中文)", false, group: "declaration", example: "手机壳", hint: "选填");
|
||||||
Add("sender.phone", "发件人手机", false, group: "sender", example: "13800138000");
|
Add("items[0].enName", "申报品名(英文)", true, group: "declaration", example: "Phone Case", hint: "必填,用于清关");
|
||||||
Add("sender.telePhone", "发件人电话", false, group: "sender");
|
Add("items[0].unitPrice", "申报单价", true, "number", group: "declaration", example: "12.5", hint: "与申报币种一致");
|
||||||
Add("sender.email", "发件人邮箱", false, group: "sender", example: "sender@example.com");
|
Add("items[0].unitWeight", "单品重量(kg)", true, "number", group: "declaration", example: "0.3", hint: "单个 SKU 重量");
|
||||||
Add("sender.countryCode", "发件国家代码", false, group: "sender", example: "CN");
|
Add("items[0].quantity", "申报数量", true, "number", group: "declaration", example: "1", hint: "必填");
|
||||||
Add("sender.province", "发件省/州", false, group: "sender", example: "Guangdong");
|
|
||||||
Add("sender.city", "发件城市", false, group: "sender", example: "Shenzhen");
|
|
||||||
Add("sender.zipCode", "发件邮编", false, group: "sender", example: "518000");
|
|
||||||
Add("sender.streetAddress1", "发件地址1", false, group: "sender", example: "Nanshan District");
|
|
||||||
Add("sender.streetAddress2", "发件地址2", false, group: "sender");
|
|
||||||
Add("sender.streetAddress3", "发件地址3", false, group: "sender");
|
|
||||||
Add("sender.houseNumber", "发件门牌号", false, group: "sender", example: "88");
|
|
||||||
|
|
||||||
Add("declaredCurrency", "申报币种", true, "select", "currency", "declaration", "USD");
|
return list;
|
||||||
Add("declaredSum", "申报总金额", false, "number", group: "declaration", example: "可选,不填自动汇总");
|
}
|
||||||
Add("items[0].cnName", "申报品名(中)", false, group: "declaration", example: "手机壳");
|
|
||||||
Add("items[0].enName", "申报品名(英)", true, group: "declaration", example: "Phone Case");
|
private static IReadOnlyList<OrderTemplateFieldDefinition> BuildDedicatedSmallParcelStandardFields()
|
||||||
Add("items[0].sku", "SKU", false, group: "declaration", example: "SKU001");
|
{
|
||||||
Add("items[0].unit", "单位", false, group: "declaration", example: "pcs");
|
var list = new List<OrderTemplateFieldDefinition>();
|
||||||
Add("items[0].unitPrice", "单价(元)", true, "number", group: "declaration", example: "12.5");
|
var sort = 0;
|
||||||
Add("items[0].unitWeight", "单重(kg)", true, "number", group: "declaration", example: "0.3");
|
void Add(
|
||||||
Add("items[0].quantity", "申报数量", true, "number", group: "declaration", example: "1");
|
string key,
|
||||||
Add("items[0].amount", "总金额(元)", false, "number", group: "declaration", example: "自动计算=单价×数量");
|
string label,
|
||||||
Add("items[0].weight", "总重量(kg)", false, "number", group: "declaration", example: "自动计算=单重×数量");
|
bool required,
|
||||||
Add("items[0].imHsCode", "进口HsCode", false, group: "declaration");
|
string dataType = "string",
|
||||||
Add("items[0].exHsCode", "出口HsCode", false, group: "declaration");
|
string? dictType = null,
|
||||||
Add("items[0].skuImage", "商品图片URL", false, group: "declaration");
|
string group = "basic",
|
||||||
Add("items[0].category", "类别", false, group: "declaration", example: "Accessories");
|
string example = "",
|
||||||
Add("items[0].brand", "品牌", false, group: "declaration", example: "DemoBrand");
|
string hint = "")
|
||||||
Add("items[0].brandType", "品牌类型", false, group: "declaration");
|
{
|
||||||
Add("items[0].isMagnetic", "是否带磁带电", false, "boolean", group: "declaration", example: "false");
|
sort += 10;
|
||||||
Add("items[0].distribution", "配货信息", false, group: "declaration");
|
list.Add(new OrderTemplateFieldDefinition
|
||||||
Add("items[0].material", "材质", false, group: "declaration", example: "plastic");
|
{
|
||||||
Add("items[0].enMaterial", "英文材质", false, group: "declaration", example: "plastic");
|
FieldKey = key,
|
||||||
Add("items[0].purpose", "用途", false, group: "declaration", example: "protection");
|
Label = label,
|
||||||
Add("items[0].attributes", "属性", false, group: "declaration");
|
Required = required,
|
||||||
Add("items[0].originCountry", "原产国", false, group: "declaration", example: "CN");
|
DataType = dataType,
|
||||||
Add("items[0].salesLink", "销售链接", false, group: "declaration");
|
DictType = dictType,
|
||||||
Add("items[0].model", "型号", false, group: "declaration", example: "Model-X");
|
Group = group,
|
||||||
Add("items[0].specifications", "规格", false, group: "declaration", example: "Standard");
|
Example = example,
|
||||||
Add("items[0].comment", "备注", false, group: "declaration", example: "示例订单数据");
|
Hint = hint,
|
||||||
|
Sort = sort,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Add("requestId", "幂等请求ID", false, example: "可选", hint: "防重复提交,一般留空");
|
||||||
|
Add("clientNo", "客户单号", true, example: "C202604230001", hint: "您自己的订单编号,同一客户不可重复");
|
||||||
|
Add("productCode", "运输方式", true, "select", "sales_product", "basic", "PROD001", hint: "从下拉选择产品编码");
|
||||||
|
Add("cargoAttribute", "货物属性", true, "select", "cargo_attribute", "basic", "general", hint: "普货选 general");
|
||||||
|
Add("exportCustomsMode", "出口报关方式", false, "select", "export_customs_mode", "basic", "9610Simple", hint: "不选则简易申报");
|
||||||
|
Add("warehouseId", "发货仓库", true, "select", "warehouse", "basic", "1", hint: "从下拉选择仓库 ID");
|
||||||
|
Add("length", "长(cm)", false, "number", example: "10", hint: "材积计费用");
|
||||||
|
Add("width", "宽(cm)", false, "number", example: "10", hint: "材积计费用");
|
||||||
|
Add("height", "高(cm)", false, "number", example: "10", hint: "材积计费用");
|
||||||
|
Add("actualWeight", "实重(kg)", true, "number", example: "1.2", hint: "必填");
|
||||||
|
Add("isCod", "是否COD", false, "boolean", example: "false", hint: "货到付款填 true");
|
||||||
|
Add("codCurrency", "COD币种", false, "select", "currency", example: "USD", hint: "COD 订单填写");
|
||||||
|
Add("codSum", "COD金额", false, "number", example: "0", hint: "COD 订单填写");
|
||||||
|
Add("quantity", "包裹件数", true, "number", example: "1", hint: "一般为 1");
|
||||||
|
|
||||||
|
Add("receiver.recipientsName", "收件人姓名", true, group: "receiver", example: "Demo Receiver", hint: "必填");
|
||||||
|
Add("receiver.companyName", "收件公司", false, group: "receiver", example: "Demo LLC", hint: "选填");
|
||||||
|
Add("receiver.phone", "收件人手机", true, group: "receiver", example: "13900139000", hint: "必填");
|
||||||
|
Add("receiver.telePhone", "收件人电话", false, group: "receiver", hint: "选填");
|
||||||
|
Add("receiver.email", "收件人邮箱", false, group: "receiver", example: "receiver@example.com", hint: "选填");
|
||||||
|
Add("receiver.countryCode", "目的国代码", true, group: "receiver", example: "US", hint: "二字码");
|
||||||
|
Add("receiver.province", "省/州", false, group: "receiver", example: "California", hint: "建议填写");
|
||||||
|
Add("receiver.city", "城市", false, group: "receiver", example: "Los Angeles", hint: "建议填写");
|
||||||
|
Add("receiver.streetNumber", "门牌号", false, group: "receiver", example: "1001", hint: "选填");
|
||||||
|
Add("receiver.streetAddress1", "地址1", true, group: "receiver", example: "Sunset Blvd", hint: "主地址,必填");
|
||||||
|
Add("receiver.streetAddress2", "地址2", false, group: "receiver", hint: "选填");
|
||||||
|
Add("receiver.streetAddress3", "地址3", false, group: "receiver", hint: "选填");
|
||||||
|
Add("receiver.zipCode", "邮编", true, group: "receiver", example: "90001", hint: "必填");
|
||||||
|
Add("receiver.taxType", "税号类型", false, group: "receiver", example: "0", hint: "欧盟等场景选填");
|
||||||
|
Add("receiver.taxNo", "税号", false, group: "receiver", hint: "选填");
|
||||||
|
Add("receiver.certificateType", "证件类型", false, group: "receiver", example: "0", hint: "选填");
|
||||||
|
Add("receiver.certificateNo", "证件号码", false, group: "receiver", hint: "选填");
|
||||||
|
Add("receiver.eori", "EORI", false, group: "receiver", hint: "选填");
|
||||||
|
Add("receiver.vat", "VAT", false, group: "receiver", hint: "选填");
|
||||||
|
|
||||||
|
Add("declaredCurrency", "申报币种", true, "select", "currency", "declaration", "USD", hint: "默认 USD");
|
||||||
|
Add("declaredSum", "申报总金额", false, "number", group: "declaration", example: "可选", hint: "不填则按明细汇总");
|
||||||
|
Add("items[0].cnName", "申报品名(中)", false, group: "declaration", example: "手机壳", hint: "选填");
|
||||||
|
Add("items[0].enName", "申报品名(英)", true, group: "declaration", example: "Phone Case", hint: "必填");
|
||||||
|
Add("items[0].sku", "SKU", false, group: "declaration", example: "SKU001", hint: "选填");
|
||||||
|
Add("items[0].unit", "单位", false, group: "declaration", example: "pcs", hint: "选填");
|
||||||
|
Add("items[0].unitPrice", "单价", true, "number", group: "declaration", example: "12.5", hint: "与申报币种一致");
|
||||||
|
Add("items[0].unitWeight", "单重(kg)", true, "number", group: "declaration", example: "0.3", hint: "必填");
|
||||||
|
Add("items[0].quantity", "申报数量", true, "number", group: "declaration", example: "1", hint: "必填");
|
||||||
|
Add("items[0].amount", "总金额", false, "number", group: "declaration", example: "自动计算", hint: "不填=单价×数量");
|
||||||
|
Add("items[0].weight", "总重量(kg)", false, "number", group: "declaration", example: "自动计算", hint: "不填=单重×数量");
|
||||||
|
Add("items[0].imHsCode", "进口HsCode", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].exHsCode", "出口HsCode", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].skuImage", "商品图片URL", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].category", "类别", false, group: "declaration", example: "Accessories", hint: "选填");
|
||||||
|
Add("items[0].brand", "品牌", false, group: "declaration", example: "DemoBrand", hint: "选填");
|
||||||
|
Add("items[0].brandType", "品牌类型", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].isMagnetic", "是否带磁带电", false, "boolean", group: "declaration", example: "false", hint: "选填");
|
||||||
|
Add("items[0].distribution", "配货信息", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].material", "材质", false, group: "declaration", example: "plastic", hint: "选填");
|
||||||
|
Add("items[0].enMaterial", "英文材质", false, group: "declaration", example: "plastic", hint: "选填");
|
||||||
|
Add("items[0].purpose", "用途", false, group: "declaration", example: "protection", hint: "选填");
|
||||||
|
Add("items[0].attributes", "属性", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].originCountry", "原产国", false, group: "declaration", example: "CN", hint: "选填");
|
||||||
|
Add("items[0].salesLink", "销售链接", false, group: "declaration", hint: "选填");
|
||||||
|
Add("items[0].model", "型号", false, group: "declaration", example: "Model-X", hint: "选填");
|
||||||
|
Add("items[0].specifications", "规格", false, group: "declaration", example: "Standard", hint: "选填");
|
||||||
|
Add("items[0].comment", "备注", false, group: "declaration", example: "示例", hint: "选填");
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_bin_location")]
|
[SugarTable(WarehouseTableNames.BinLocation)]
|
||||||
public class CBinLocation : OmsAuditedAggregateRoot
|
public class CBinLocation : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int WarehouseId { get; set; }
|
public int WarehouseId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_inbound_box")]
|
[SugarTable(WarehouseTableNames.InboundBox)]
|
||||||
public class CInboundBox : OmsAuditedAggregateRoot
|
public class CInboundBox : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int InboundNoticeId { get; set; }
|
public int InboundNoticeId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_inbound_box_line")]
|
[SugarTable(WarehouseTableNames.InboundBoxLine)]
|
||||||
public class CInboundBoxLine : OmsAuditedAggregateRoot
|
public class CInboundBoxLine : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int InboundBoxId { get; set; }
|
public int InboundBoxId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_inbound_notice")]
|
[SugarTable(WarehouseTableNames.InboundNotice)]
|
||||||
public class CInboundNotice : OmsAuditedAggregateRoot
|
public class CInboundNotice : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_inventory")]
|
[SugarTable(WarehouseTableNames.Inventory)]
|
||||||
public class CInventory : OmsAuditedAggregateRoot
|
public class CInventory : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_parcel")]
|
[SugarTable(WarehouseTableNames.Parcel)]
|
||||||
public class CParcel : OmsAuditedAggregateRoot
|
public class CParcel : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Oms.Domain.WarehouseAggregate.Entities;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 快递到仓扫描记录。
|
/// 快递到仓扫描记录。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarTable("C_parcel_arrival")]
|
[SugarTable(WarehouseTableNames.ParcelArrival)]
|
||||||
public class CParcelArrival : OmsAuditedAggregateRoot
|
public class CParcelArrival : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_parcel_item")]
|
[SugarTable(WarehouseTableNames.ParcelItem)]
|
||||||
public class CParcelItem : OmsAuditedAggregateRoot
|
public class CParcelItem : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int ParcelId { get; set; }
|
public int ParcelId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_sku")]
|
[SugarTable(WarehouseTableNames.Sku)]
|
||||||
public class CSku : OmsAuditedAggregateRoot
|
public class CSku : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using SqlSugar;
|
|||||||
|
|
||||||
namespace Oms.Domain.WarehouseAggregate.Entities;
|
namespace Oms.Domain.WarehouseAggregate.Entities;
|
||||||
|
|
||||||
[SugarTable("C_sku_platform_map")]
|
[SugarTable(WarehouseTableNames.SkuPlatformMap)]
|
||||||
public class CSkuPlatformMap : OmsAuditedAggregateRoot
|
public class CSkuPlatformMap : OmsAuditedAggregateRoot
|
||||||
{
|
{
|
||||||
public int CustomerId { get; set; }
|
public int CustomerId { get; set; }
|
||||||
|
|||||||
18
src/Oms.Domain/WarehouseAggregate/WarehouseTableNames.cs
Normal file
18
src/Oms.Domain/WarehouseAggregate/WarehouseTableNames.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
namespace Oms.Domain.WarehouseAggregate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仓储模块表名(<c>c_</c> 前缀 + 小写 snake_case,与 <c>t_order</c> 等命名风格对齐)。
|
||||||
|
/// </summary>
|
||||||
|
public static class WarehouseTableNames
|
||||||
|
{
|
||||||
|
public const string Sku = "c_sku";
|
||||||
|
public const string BinLocation = "c_bin_location";
|
||||||
|
public const string Inventory = "c_inventory";
|
||||||
|
public const string InboundNotice = "c_inbound_notice";
|
||||||
|
public const string InboundBox = "c_inbound_box";
|
||||||
|
public const string InboundBoxLine = "c_inbound_box_line";
|
||||||
|
public const string Parcel = "c_parcel";
|
||||||
|
public const string ParcelArrival = "c_parcel_arrival";
|
||||||
|
public const string ParcelItem = "c_parcel_item";
|
||||||
|
public const string SkuPlatformMap = "c_sku_platform_map";
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user