admin/sql/migrate_t_order_stock_bind.sql
zzh a1daea6b35 refactor: 仓储表 C_* 改为 c_*,优化专线小包批量模板
- 仓储实体与 db.sql 统一为小写 c_ 前缀,新增 migrate_rename_warehouse_C_to_c.sql
- 专线小包批量模板精简版/标准版双模板,Excel 必填标红与发件地址上传参数

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 16:18:59 +08:00

121 lines
5.9 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 物流单绑定包裹/库存:t_order_stock_bind + c_inventory/c_parcel_item 冻结与可用字段
-- 见 oms系统设计-050801.md §4.2.11 / §4.4.6 / §3.1.2
-- ConcurrencyStamp 默认用固定 GUID,避免 DEFAULT (UUID()) 触发复制 1674
-- 可重复执行
CREATE TABLE IF NOT EXISTS `t_order_stock_bind` (
`Id` INT NOT NULL AUTO_INCREMENT,
`OrderId` INT NOT NULL COMMENT '物流单 t_order.Id',
`CustomerId` INT NOT NULL COMMENT '客户隔离键',
`WarehouseId` INT NOT NULL COMMENT '仓库',
`BindType` VARCHAR(20) NOT NULL COMMENT 'inventory / parcelItem',
`SkuId` INT NULL COMMENT 'SKU',
`InventoryId` INT NULL COMMENT 'c_inventory.Id,可空=按SKU分摊',
`BinLocationId` INT NULL COMMENT '库位快照',
`ParcelId` INT NULL COMMENT 'c_parcel.Id',
`ParcelItemId` INT NULL COMMENT 'c_parcel_item.Id',
`BindQty` INT NOT NULL COMMENT '绑定数量',
`Status` VARCHAR(20) NOT NULL DEFAULT 'bound' COMMENT 'bound/deducted/released',
`SkuCode` VARCHAR(64) NULL,
`SkuName` VARCHAR(128) NULL,
`TrackingNo` VARCHAR(64) NULL,
`ProductName` VARCHAR(256) NULL,
`ImageUrl` VARCHAR(512) NULL,
`AttributeText` VARCHAR(256) NULL,
`Remark` VARCHAR(512) NULL,
`IsDeleted` TINYINT NOT NULL DEFAULT 0,
`ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000' COMMENT '并发戳',
`CreateUserId` INT NOT NULL,
`CreateTime` DATETIME NOT NULL,
`UpdateUserId` INT NULL,
`UpdateTime` DATETIME NULL,
PRIMARY KEY (`Id`),
KEY `idx_osb_order` (`OrderId`, `IsDeleted`, `Status`),
KEY `idx_osb_parcel_item` (`ParcelItemId`, `Status`, `IsDeleted`),
KEY `idx_osb_sku` (`CustomerId`, `WarehouseId`, `SkuId`, `Status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流单仓储绑定明细';
-- 已建表但缺 ConcurrencyStamp 时补列(可重复执行)
SET @col_exists := (
SELECT COUNT(1) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 't_order_stock_bind' AND COLUMN_NAME = 'ConcurrencyStamp'
);
SET @sql := IF(
@col_exists = 0,
'ALTER TABLE `t_order_stock_bind` ADD COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT ''00000000-0000-0000-0000-000000000000'' COMMENT ''并发戳'' AFTER `IsDeleted`',
'SELECT ''t_order_stock_bind.ConcurrencyStamp already exists'' AS info'
);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- c_inventory.FrozenQty(兼容尚未 rename 的旧表名 C_inventory)
SET @inv_table := IF(
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'c_inventory'),
'c_inventory',
IF(
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'C_inventory'),
'C_inventory',
NULL
)
);
SET @col_exists := IF(@inv_table IS NULL, 1,
(SELECT COUNT(1) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @inv_table AND COLUMN_NAME = 'FrozenQty')
);
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;
SET @col_exists := IF(@inv_table IS NULL, 1,
(SELECT COUNT(1) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @inv_table AND COLUMN_NAME = 'AvailableQty')
);
SET @sql := IF(@inv_table IS NULL OR @col_exists > 0,
'SELECT ''c_inventory.AvailableQty already exists or table missing'' AS info',
CONCAT('ALTER TABLE `', @inv_table, '` ADD COLUMN `AvailableQty` INT NOT NULL DEFAULT 0 COMMENT ''可用=Qty-FrozenQty'' AFTER `FrozenQty`')
);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql := IF(@inv_table IS NULL,
'SELECT ''c_inventory table missing'' AS info',
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)')
);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- c_parcel_item.FrozenQty
SET @pi_table := IF(
EXISTS (SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'c_parcel_item'),
'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 @col_exists := IF(@pi_table IS NULL, 1,
(SELECT COUNT(1) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @pi_table AND COLUMN_NAME = 'FrozenQty')
);
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;
SET @col_exists := IF(@pi_table IS NULL, 1,
(SELECT COUNT(1) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @pi_table AND COLUMN_NAME = 'AvailableQty')
);
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;