777 lines
44 KiB
SQL
777 lines
44 KiB
SQL
-- 一期回归测试环境增量迁移汇总
|
||
-- 适用版本:MySQL 8.0
|
||
-- 涉及数据库:baiyue_iam、baiyue_warehouse、baiyue_order、baiyue_firstleg、baiyue_file
|
||
-- 安全边界:不创建数据库、不清表、不删除业务数据、不写入演示租户及演示业务数据。
|
||
-- 可重复执行:所有新增字段、表、索引和权限均带存在性判断或幂等写入。
|
||
-- 重要说明:MySQL DDL 会隐式提交,本脚本不能作为一个跨库事务整体回滚。
|
||
|
||
SET NAMES utf8mb4;
|
||
|
||
-- ============================================================================
|
||
-- 1. IAM:权限资源结构、平台/商户按钮权限及管理员授权
|
||
-- ============================================================================
|
||
USE baiyue_iam;
|
||
|
||
DROP PROCEDURE IF EXISTS regression_assert_table;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_assert_table(IN p_table_name VARCHAR(64))
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1
|
||
FROM information_schema.tables
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = p_table_name
|
||
) THEN
|
||
SIGNAL SQLSTATE '45000'
|
||
SET MESSAGE_TEXT = 'baiyue_iam 缺少基础表,请先执行 IAM 基线建表脚本';
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
|
||
CALL regression_assert_table('iam_permission');
|
||
CALL regression_assert_table('iam_role');
|
||
CALL regression_assert_table('iam_role_permission');
|
||
CALL regression_assert_table('iam_tenant');
|
||
DROP PROCEDURE regression_assert_table;
|
||
|
||
SET @iam_permission_built_in_sql = IF(
|
||
EXISTS(
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 'iam_permission'
|
||
AND column_name = 'built_in'
|
||
),
|
||
'SELECT 1',
|
||
'ALTER TABLE iam_permission ADD COLUMN built_in TINYINT NOT NULL DEFAULT 0 COMMENT ''是否为系统预置权限;预置资源不可通过管理接口修改'' AFTER status'
|
||
);
|
||
PREPARE iam_permission_built_in_stmt FROM @iam_permission_built_in_sql;
|
||
EXECUTE iam_permission_built_in_stmt;
|
||
DEALLOCATE PREPARE iam_permission_built_in_stmt;
|
||
|
||
-- 一期客户档案字段;与 iam/db/phase1-customer-profile.sql 保持一致。
|
||
DROP PROCEDURE IF EXISTS regression_add_iam_column;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_add_iam_column(
|
||
IN p_column_name VARCHAR(64),
|
||
IN p_definition VARCHAR(1000)
|
||
)
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 'iam_tenant'
|
||
AND column_name = p_column_name
|
||
) THEN
|
||
SET @regression_iam_sql = CONCAT(
|
||
'ALTER TABLE iam_tenant ADD COLUMN `', p_column_name, '` ', p_definition
|
||
);
|
||
PREPARE regression_iam_stmt FROM @regression_iam_sql;
|
||
EXECUTE regression_iam_stmt;
|
||
DEALLOCATE PREPARE regression_iam_stmt;
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
|
||
CALL regression_add_iam_column('contact_wechat', 'VARCHAR(64) NULL COMMENT ''联系微信'' AFTER contact_email');
|
||
CALL regression_add_iam_column('sales_owner_name', 'VARCHAR(64) NULL COMMENT ''销售负责人姓名'' AFTER contact_wechat');
|
||
CALL regression_add_iam_column('payment_term_days', 'SMALLINT UNSIGNED NULL COMMENT ''账期天数'' AFTER sales_owner_name');
|
||
CALL regression_add_iam_column('enterprise_type', 'VARCHAR(64) NULL COMMENT ''企业类型'' AFTER payment_term_days');
|
||
CALL regression_add_iam_column('established_date', 'DATE NULL COMMENT ''成立日期'' AFTER enterprise_type');
|
||
CALL regression_add_iam_column('registered_capital', 'DECIMAL(18,2) NULL COMMENT ''注册资本'' AFTER established_date');
|
||
CALL regression_add_iam_column('registered_capital_currency', 'CHAR(3) NULL COMMENT ''注册资本币种 ISO 4217'' AFTER registered_capital');
|
||
CALL regression_add_iam_column('registered_address', 'VARCHAR(500) NULL COMMENT ''注册地址文本'' AFTER registered_capital_currency');
|
||
CALL regression_add_iam_column('internal_remark', 'VARCHAR(1000) NULL COMMENT ''平台内部备注'' AFTER registered_address');
|
||
DROP PROCEDURE regression_add_iam_column;
|
||
|
||
-- 先写入父菜单,再写入按钮,避免新增环境出现悬空父节点。
|
||
INSERT INTO iam_permission
|
||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
|
||
VALUES
|
||
(5100000, 0, 'PLATFORM', 'MENU', 0, 'platform:customer', '客户管理', '/customers', NULL, 10, 'ACTIVE', 1, 0),
|
||
(5101000, 0, 'PLATFORM', 'MENU', 0, 'platform:system', '系统管理', '/system', NULL, 20, 'ACTIVE', 1, 0),
|
||
(5102000, 0, 'PLATFORM', 'MENU', 0, 'platform:order', '头程订单', '/first-leg-orders', NULL, 30, 'ACTIVE', 1, 0),
|
||
(5103000, 0, 'PLATFORM', 'MENU', 0, 'platform:master-data', '基础资料', '/master-data', NULL, 40, 'ACTIVE', 1, 0),
|
||
(5100010, 0, 'PLATFORM', 'MENU', 5100000, 'platform:customer:list', '企业客户', '/customers/list', NULL, 10, 'ACTIVE', 1, 0),
|
||
(5101010, 0, 'PLATFORM', 'MENU', 5101000, 'platform:user:list', '内部用户', '/system/users', NULL, 10, 'ACTIVE', 1, 0),
|
||
(5101020, 0, 'PLATFORM', 'MENU', 5101000, 'platform:role:list', '角色管理', '/system/roles', NULL, 20, 'ACTIVE', 1, 0),
|
||
(5101030, 0, 'PLATFORM', 'MENU', 5101000, 'platform:permission:list', '菜单按钮', '/system/permissions', NULL, 30, 'ACTIVE', 1, 0),
|
||
(5101040, 0, 'PLATFORM', 'MENU', 5101000, 'platform:member:list', '平台成员', '/system/members', NULL, 40, 'ACTIVE', 1, 0),
|
||
(5102010, 0, 'PLATFORM', 'MENU', 5102000, 'platform:order:list', '订单列表', '/first-leg-orders/list', NULL, 10, 'ACTIVE', 1, 0),
|
||
(5102020, 0, 'PLATFORM', 'MENU', 5102000, 'platform:firstleg:task:list', '履约任务', '/first-leg-tasks/list', NULL, 20, 'ACTIVE', 1, 0),
|
||
(5103020, 0, 'PLATFORM', 'MENU', 5103000, 'platform:express:list', '快递公司', '/master-data/express', NULL, 20, 'ACTIVE', 1, 0),
|
||
(5103030, 0, 'PLATFORM', 'MENU', 5103000, 'platform:counterparty:list', '往来单位', '/master-data/counterparties', NULL, 30, 'ACTIVE', 1, 0),
|
||
(5103040, 0, 'PLATFORM', 'MENU', 5103000, 'platform:download:list', '下载中心', '/downloads', NULL, 40, 'ACTIVE', 1, 0)
|
||
ON DUPLICATE KEY UPDATE
|
||
permission_type = VALUES(permission_type),
|
||
parent_id = VALUES(parent_id),
|
||
permission_name = VALUES(permission_name),
|
||
route_path = VALUES(route_path),
|
||
http_method = VALUES(http_method),
|
||
sort_no = VALUES(sort_no),
|
||
status = 'ACTIVE',
|
||
built_in = 1,
|
||
deleted = 0;
|
||
|
||
INSERT INTO iam_permission
|
||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
|
||
VALUES
|
||
(5100011, 0, 'PLATFORM', 'BUTTON', 5100010, 'platform:customer:create', '新增企业客户', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5100014, 0, 'PLATFORM', 'BUTTON', 5100010, 'platform:customer:view', '查看企业客户档案', NULL, NULL, 15, 'ACTIVE', 1, 0),
|
||
(5100012, 0, 'PLATFORM', 'BUTTON', 5100010, 'platform:customer:edit', '编辑企业客户', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5100013, 0, 'PLATFORM', 'BUTTON', 5100010, 'platform:customer:status', '启停企业客户', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5100015, 0, 'PLATFORM', 'BUTTON', 5100010, 'platform:customer:export', '导出企业客户', NULL, NULL, 40, 'ACTIVE', 1, 0),
|
||
(5101011, 0, 'PLATFORM', 'BUTTON', 5101010, 'platform:user:create', '新增内部用户', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5101012, 0, 'PLATFORM', 'BUTTON', 5101010, 'platform:user:edit', '编辑内部用户', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5101013, 0, 'PLATFORM', 'BUTTON', 5101010, 'platform:user:status', '启停内部用户', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5101014, 0, 'PLATFORM', 'BUTTON', 5101010, 'platform:user:reset-password', '重置内部用户密码', NULL, NULL, 40, 'ACTIVE', 1, 0),
|
||
(5101015, 0, 'PLATFORM', 'BUTTON', 5101010, 'platform:user:grant-role', '分配内部用户角色', NULL, NULL, 50, 'ACTIVE', 1, 0),
|
||
(5101021, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:create', '新增角色', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5101022, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:grant', '角色授权', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5101023, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:edit', '编辑角色', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5101024, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:status', '启停角色', NULL, NULL, 40, 'ACTIVE', 1, 0),
|
||
(5101025, 0, 'PLATFORM', 'BUTTON', 5101020, 'platform:role:delete', '删除角色', NULL, NULL, 50, 'ACTIVE', 1, 0),
|
||
(5101031, 0, 'PLATFORM', 'BUTTON', 5101030, 'platform:permission:create', '新增菜单按钮', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5101032, 0, 'PLATFORM', 'BUTTON', 5101030, 'platform:permission:edit', '编辑权限资源', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5101033, 0, 'PLATFORM', 'BUTTON', 5101030, 'platform:permission:status', '启停权限资源', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5101034, 0, 'PLATFORM', 'BUTTON', 5101030, 'platform:permission:delete', '删除权限资源', NULL, NULL, 40, 'ACTIVE', 1, 0),
|
||
(5101041, 0, 'PLATFORM', 'BUTTON', 5101040, 'platform:member:grant-role', '分配平台成员角色', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5102019, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:create', '平台代客创建订单', NULL, NULL, 90, 'ACTIVE', 1, 0),
|
||
(5102024, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:edit', '平台编辑订单草稿', NULL, NULL, 100, 'ACTIVE', 1, 0),
|
||
(5102025, 0, 'PLATFORM', 'BUTTON', 5102010, 'platform:order:submit', '平台代客提交订单', NULL, NULL, 110, 'ACTIVE', 1, 0),
|
||
(5102021, 0, 'PLATFORM', 'BUTTON', 5102020, 'platform:firstleg:task:view', '查看履约任务', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5102022, 0, 'PLATFORM', 'BUTTON', 5102020, 'platform:firstleg:assignment:history', '查看分配历史', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5102023, 0, 'PLATFORM', 'BUTTON', 5102020, 'platform:firstleg:assignment:assign', '分配履约任务', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5103021, 0, 'PLATFORM', 'BUTTON', 5103020, 'platform:express:create', '新增快递公司', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5103022, 0, 'PLATFORM', 'BUTTON', 5103020, 'platform:express:edit', '编辑快递公司', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5103023, 0, 'PLATFORM', 'BUTTON', 5103020, 'platform:express:status', '启停快递公司', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5103031, 0, 'PLATFORM', 'BUTTON', 5103030, 'platform:counterparty:create', '新增往来单位', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||
(5103032, 0, 'PLATFORM', 'BUTTON', 5103030, 'platform:counterparty:edit', '编辑往来单位', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||
(5103033, 0, 'PLATFORM', 'BUTTON', 5103030, 'platform:counterparty:status', '启停往来单位', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||
(5103041, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:download:all', '查看全部下载任务', NULL, NULL, 10, 'ACTIVE', 1, 0)
|
||
ON DUPLICATE KEY UPDATE
|
||
permission_type = VALUES(permission_type),
|
||
parent_id = VALUES(parent_id),
|
||
permission_name = VALUES(permission_name),
|
||
sort_no = VALUES(sort_no),
|
||
status = 'ACTIVE',
|
||
built_in = 1,
|
||
deleted = 0;
|
||
|
||
-- 商户角色维护权限仅在对应父菜单已存在时补齐,不创建演示租户或角色。
|
||
INSERT INTO iam_permission
|
||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||
permission_name, sort_no, status, built_in, deleted)
|
||
SELECT 5200033, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:edit', '编辑角色', 30, 'ACTIVE', 1, 0
|
||
WHERE EXISTS (SELECT 1 FROM iam_permission WHERE id = 5200030 AND tenant_id = 10001)
|
||
UNION ALL
|
||
SELECT 5200034, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:status', '启停角色', 40, 'ACTIVE', 1, 0
|
||
WHERE EXISTS (SELECT 1 FROM iam_permission WHERE id = 5200030 AND tenant_id = 10001)
|
||
UNION ALL
|
||
SELECT 5200035, 10001, 'MERCHANT', 'BUTTON', 5200030, 'merchant:role:delete', '删除角色', 50, 'ACTIVE', 1, 0
|
||
WHERE EXISTS (SELECT 1 FROM iam_permission WHERE id = 5200030 AND tenant_id = 10001)
|
||
UNION ALL
|
||
SELECT 5300033, 0, 'MERCHANT', 'BUTTON', 5300030, 'merchant:role:edit', '编辑角色', 30, 'ACTIVE', 1, 0
|
||
WHERE EXISTS (SELECT 1 FROM iam_permission WHERE id = 5300030 AND tenant_id = 0)
|
||
UNION ALL
|
||
SELECT 5300034, 0, 'MERCHANT', 'BUTTON', 5300030, 'merchant:role:status', '启停角色', 40, 'ACTIVE', 1, 0
|
||
WHERE EXISTS (SELECT 1 FROM iam_permission WHERE id = 5300030 AND tenant_id = 0)
|
||
UNION ALL
|
||
SELECT 5300035, 0, 'MERCHANT', 'BUTTON', 5300030, 'merchant:role:delete', '删除角色', 50, 'ACTIVE', 1, 0
|
||
WHERE EXISTS (SELECT 1 FROM iam_permission WHERE id = 5300030 AND tenant_id = 0)
|
||
ON DUPLICATE KEY UPDATE
|
||
permission_name = VALUES(permission_name),
|
||
parent_id = VALUES(parent_id),
|
||
sort_no = VALUES(sort_no),
|
||
status = 'ACTIVE',
|
||
built_in = 1,
|
||
deleted = 0;
|
||
|
||
UPDATE iam_permission
|
||
SET built_in = 1
|
||
WHERE id BETWEEN 5000000 AND 5399999
|
||
AND built_in = 0;
|
||
|
||
-- 平台超级管理员自动获得本轮新增权限;不存在该角色时不插入任何授权记录。
|
||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||
SELECT r.id, p.id, 0
|
||
FROM iam_role r
|
||
JOIN iam_permission p
|
||
ON p.tenant_id = 0
|
||
AND p.app_code = 'PLATFORM'
|
||
WHERE r.tenant_id = 0
|
||
AND r.app_code = 'PLATFORM'
|
||
AND r.role_code = 'PLATFORM_ADMIN'
|
||
AND r.deleted = 0
|
||
AND p.permission_code IN (
|
||
'platform:customer', 'platform:customer:list', 'platform:customer:create',
|
||
'platform:customer:view', 'platform:customer:edit', 'platform:customer:status', 'platform:customer:export',
|
||
'platform:system', 'platform:user:list', 'platform:user:create', 'platform:user:edit',
|
||
'platform:user:status', 'platform:user:reset-password', 'platform:user:grant-role',
|
||
'platform:role:list', 'platform:role:create', 'platform:role:grant',
|
||
'platform:role:edit', 'platform:role:status', 'platform:role:delete',
|
||
'platform:member:list', 'platform:member:grant-role',
|
||
'platform:permission:list', 'platform:permission:create', 'platform:permission:edit',
|
||
'platform:permission:status', 'platform:permission:delete',
|
||
'platform:order', 'platform:order:list', 'platform:order:create',
|
||
'platform:order:edit', 'platform:order:submit',
|
||
'platform:firstleg:task:list', 'platform:firstleg:task:view',
|
||
'platform:firstleg:assignment:history', 'platform:firstleg:assignment:assign',
|
||
'platform:master-data', 'platform:express:list', 'platform:express:create',
|
||
'platform:express:edit', 'platform:express:status',
|
||
'platform:counterparty:list', 'platform:counterparty:create',
|
||
'platform:counterparty:edit', 'platform:counterparty:status',
|
||
'platform:download:list', 'platform:download:all'
|
||
)
|
||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||
|
||
-- 既有客户列表或审核角色继承详情查看权限,避免升级后丢失原查询能力。
|
||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||
SELECT DISTINCT existing_grant.role_id, view_permission.id, existing_grant.tenant_id
|
||
FROM iam_role_permission existing_grant
|
||
JOIN iam_permission existing_permission
|
||
ON existing_permission.id = existing_grant.permission_id
|
||
JOIN iam_permission view_permission
|
||
ON view_permission.tenant_id = 0
|
||
AND view_permission.app_code = 'PLATFORM'
|
||
AND view_permission.permission_code = 'platform:customer:view'
|
||
WHERE existing_permission.tenant_id = 0
|
||
AND existing_permission.app_code = 'PLATFORM'
|
||
AND existing_permission.permission_code IN ('platform:customer:list', 'platform:customer:review')
|
||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||
|
||
-- 已有客户列表或审核角色获得客户导出及本人下载任务查询,不继承查看全部任务权限。
|
||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||
SELECT DISTINCT existing_grant.role_id, added_permission.id, existing_grant.tenant_id
|
||
FROM iam_role_permission existing_grant
|
||
JOIN iam_permission existing_permission ON existing_permission.id = existing_grant.permission_id
|
||
JOIN iam_permission added_permission
|
||
ON added_permission.tenant_id = 0
|
||
AND added_permission.app_code = 'PLATFORM'
|
||
AND added_permission.permission_code IN ('platform:customer:export', 'platform:download:list')
|
||
WHERE existing_permission.tenant_id = 0
|
||
AND existing_permission.app_code = 'PLATFORM'
|
||
AND existing_permission.permission_code IN ('platform:customer:list', 'platform:customer:review')
|
||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||
|
||
-- 已存在的商户超级管理员/企业管理员获得对应租户的角色维护权限。
|
||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||
SELECT r.id, p.id, r.tenant_id
|
||
FROM iam_role r
|
||
JOIN iam_permission p
|
||
ON p.tenant_id = r.tenant_id
|
||
AND p.app_code = 'MERCHANT'
|
||
WHERE r.app_code = 'MERCHANT'
|
||
AND r.role_code IN ('MERCHANT_OWNER', 'MERCHANT_ADMIN')
|
||
AND r.deleted = 0
|
||
AND p.permission_code IN ('merchant:role:edit', 'merchant:role:status', 'merchant:role:delete')
|
||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||
|
||
-- ============================================================================
|
||
-- 2. Warehouse:仓库、地址、能力、往来单位、快递公司结构兼容迁移
|
||
-- ============================================================================
|
||
USE baiyue_warehouse;
|
||
|
||
CREATE TABLE IF NOT EXISTS wh_partner (
|
||
id BIGINT UNSIGNED NOT NULL,
|
||
tenant_id BIGINT UNSIGNED NOT NULL,
|
||
partner_code VARCHAR(50) NOT NULL,
|
||
partner_name VARCHAR(128) NOT NULL,
|
||
partner_type VARCHAR(20) NOT NULL COMMENT 'CUSTOMER、SUPPLIER或BOTH',
|
||
contact_name VARCHAR(64) NOT NULL,
|
||
contact_phone VARCHAR(32) NOT NULL,
|
||
contact_email VARCHAR(128) NULL,
|
||
country_code CHAR(2) NOT NULL,
|
||
province VARCHAR(64) NULL,
|
||
city VARCHAR(64) NOT NULL,
|
||
district VARCHAR(64) NULL,
|
||
address_line VARCHAR(255) NOT NULL,
|
||
postal_code VARCHAR(20) NULL,
|
||
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||
created_by BIGINT UNSIGNED NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_by BIGINT UNSIGNED 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),
|
||
UNIQUE KEY uk_wh_partner_tenant_code (tenant_id, partner_code, deleted),
|
||
KEY idx_wh_partner_tenant_status (tenant_id, status, deleted)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='仓储域内的租户往来单位配置';
|
||
|
||
CREATE TABLE IF NOT EXISTS wh_express_company (
|
||
id BIGINT UNSIGNED NOT NULL COMMENT '快递公司记录ID',
|
||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '所属租户ID',
|
||
company_code VARCHAR(50) NOT NULL COMMENT '租户内唯一快递公司编码',
|
||
company_name VARCHAR(128) NOT NULL COMMENT '快递公司名称',
|
||
service_phone VARCHAR(32) NULL COMMENT '客服电话',
|
||
website VARCHAR(255) NULL COMMENT '官方网站',
|
||
tracking_url_template VARCHAR(500) NULL COMMENT '轨迹查询地址模板,可包含{trackingNo}',
|
||
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '状态',
|
||
remark VARCHAR(500) NULL COMMENT '备注',
|
||
created_by BIGINT UNSIGNED NULL COMMENT '创建人ID',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||
updated_by BIGINT UNSIGNED NULL COMMENT '最后修改人ID',
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记',
|
||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_wh_express_tenant_code (tenant_id, company_code, deleted),
|
||
KEY idx_wh_express_tenant_status (tenant_id, status, deleted)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户维度快递公司主数据';
|
||
|
||
DROP PROCEDURE IF EXISTS regression_assert_warehouse_table;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_assert_warehouse_table(IN p_table_name VARCHAR(64))
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.tables
|
||
WHERE table_schema = DATABASE() AND table_name = p_table_name
|
||
) THEN
|
||
SIGNAL SQLSTATE '45000'
|
||
SET MESSAGE_TEXT = 'baiyue_warehouse 缺少仓库基础表,请先执行 warehouse.sql';
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
CALL regression_assert_warehouse_table('wh_warehouse');
|
||
CALL regression_assert_warehouse_table('wh_warehouse_address');
|
||
CALL regression_assert_warehouse_table('wh_service_capability');
|
||
DROP PROCEDURE regression_assert_warehouse_table;
|
||
|
||
DROP PROCEDURE IF EXISTS regression_add_column;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_add_column(
|
||
IN p_table_name VARCHAR(64),
|
||
IN p_column_name VARCHAR(64),
|
||
IN p_column_definition TEXT
|
||
)
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = p_table_name
|
||
AND column_name = p_column_name
|
||
) THEN
|
||
SET @regression_column_sql = CONCAT(
|
||
'ALTER TABLE `', REPLACE(p_table_name, '`', '``'),
|
||
'` ADD COLUMN `', REPLACE(p_column_name, '`', '``'),
|
||
'` ', p_column_definition
|
||
);
|
||
PREPARE regression_column_stmt FROM @regression_column_sql;
|
||
EXECUTE regression_column_stmt;
|
||
DEALLOCATE PREPARE regression_column_stmt;
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
|
||
CALL regression_add_column('wh_warehouse', 'warehouse_type', 'VARCHAR(32) NOT NULL DEFAULT ''DOMESTIC'' COMMENT ''仓库类型'' AFTER warehouse_name');
|
||
CALL regression_add_column('wh_warehouse', 'country_code', 'CHAR(2) NOT NULL DEFAULT ''CN'' COMMENT ''所在国家二字码'' AFTER warehouse_type');
|
||
CALL regression_add_column('wh_warehouse', 'timezone', 'VARCHAR(64) NOT NULL DEFAULT ''Asia/Shanghai'' COMMENT ''IANA时区'' AFTER country_code');
|
||
CALL regression_add_column('wh_warehouse', 'contact_name', 'VARCHAR(64) NULL AFTER timezone');
|
||
CALL regression_add_column('wh_warehouse', 'contact_phone', 'VARCHAR(32) NULL AFTER contact_name');
|
||
CALL regression_add_column('wh_warehouse', 'contact_email', 'VARCHAR(128) NULL AFTER contact_phone');
|
||
CALL regression_add_column('wh_warehouse', 'status', 'VARCHAR(20) NOT NULL DEFAULT ''ACTIVE'' AFTER contact_email');
|
||
CALL regression_add_column('wh_warehouse', 'remark', 'VARCHAR(500) NULL AFTER status');
|
||
CALL regression_add_column('wh_warehouse', 'created_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_warehouse', 'created_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_warehouse', 'updated_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_warehouse', 'updated_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_warehouse', 'deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
|
||
CALL regression_add_column('wh_warehouse', 'version', 'INT NOT NULL DEFAULT 0');
|
||
|
||
CALL regression_add_column('wh_warehouse_address', 'tenant_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER id');
|
||
CALL regression_add_column('wh_warehouse_address', 'warehouse_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER tenant_id');
|
||
CALL regression_add_column('wh_warehouse_address', 'address_type', 'VARCHAR(20) NOT NULL DEFAULT ''OPERATING'' AFTER warehouse_id');
|
||
CALL regression_add_column('wh_warehouse_address', 'country_code', 'CHAR(2) NOT NULL DEFAULT ''CN'' AFTER address_type');
|
||
CALL regression_add_column('wh_warehouse_address', 'state_province', 'VARCHAR(100) NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'city', 'VARCHAR(100) NOT NULL DEFAULT '''' AFTER state_province');
|
||
CALL regression_add_column('wh_warehouse_address', 'district', 'VARCHAR(100) NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'postal_code', 'VARCHAR(20) NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'address_line1', 'VARCHAR(255) NOT NULL DEFAULT '''' AFTER postal_code');
|
||
CALL regression_add_column('wh_warehouse_address', 'address_line2', 'VARCHAR(255) NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'latitude', 'DECIMAL(10,7) NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'longitude', 'DECIMAL(10,7) NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'created_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'created_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_warehouse_address', 'updated_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_warehouse_address', 'updated_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_warehouse_address', 'deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
|
||
CALL regression_add_column('wh_warehouse_address', 'version', 'INT NOT NULL DEFAULT 0');
|
||
|
||
CALL regression_add_column('wh_service_capability', 'tenant_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER id');
|
||
CALL regression_add_column('wh_service_capability', 'warehouse_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER tenant_id');
|
||
CALL regression_add_column('wh_service_capability', 'capability_code', 'VARCHAR(50) NOT NULL DEFAULT '''' AFTER warehouse_id');
|
||
CALL regression_add_column('wh_service_capability', 'capability_name', 'VARCHAR(100) NOT NULL DEFAULT '''' AFTER capability_code');
|
||
CALL regression_add_column('wh_service_capability', 'enabled', 'TINYINT(1) NOT NULL DEFAULT 1');
|
||
CALL regression_add_column('wh_service_capability', 'cutoff_time', 'TIME NULL');
|
||
CALL regression_add_column('wh_service_capability', 'description', 'VARCHAR(500) NULL');
|
||
CALL regression_add_column('wh_service_capability', 'created_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_service_capability', 'created_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_service_capability', 'updated_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_service_capability', 'updated_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_service_capability', 'deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
|
||
CALL regression_add_column('wh_service_capability', 'version', 'INT NOT NULL DEFAULT 0');
|
||
|
||
CALL regression_add_column('wh_partner', 'tenant_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER id');
|
||
CALL regression_add_column('wh_partner', 'partner_code', 'VARCHAR(50) NOT NULL DEFAULT '''' AFTER tenant_id');
|
||
CALL regression_add_column('wh_partner', 'partner_name', 'VARCHAR(128) NOT NULL DEFAULT '''' AFTER partner_code');
|
||
CALL regression_add_column('wh_partner', 'partner_type', 'VARCHAR(20) NOT NULL DEFAULT ''CUSTOMER'' AFTER partner_name');
|
||
CALL regression_add_column('wh_partner', 'contact_name', 'VARCHAR(64) NOT NULL DEFAULT '''' AFTER partner_type');
|
||
CALL regression_add_column('wh_partner', 'contact_phone', 'VARCHAR(32) NOT NULL DEFAULT '''' AFTER contact_name');
|
||
CALL regression_add_column('wh_partner', 'contact_email', 'VARCHAR(128) NULL');
|
||
CALL regression_add_column('wh_partner', 'country_code', 'CHAR(2) NOT NULL DEFAULT ''CN'' AFTER contact_email');
|
||
CALL regression_add_column('wh_partner', 'province', 'VARCHAR(64) NULL');
|
||
CALL regression_add_column('wh_partner', 'city', 'VARCHAR(64) NOT NULL DEFAULT '''' AFTER province');
|
||
CALL regression_add_column('wh_partner', 'district', 'VARCHAR(64) NULL');
|
||
CALL regression_add_column('wh_partner', 'address_line', 'VARCHAR(255) NOT NULL DEFAULT '''' AFTER district');
|
||
CALL regression_add_column('wh_partner', 'postal_code', 'VARCHAR(20) NULL');
|
||
CALL regression_add_column('wh_partner', 'status', 'VARCHAR(20) NOT NULL DEFAULT ''ACTIVE'' AFTER postal_code');
|
||
CALL regression_add_column('wh_partner', 'created_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_partner', 'created_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_partner', 'updated_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_partner', 'updated_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_partner', 'deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
|
||
CALL regression_add_column('wh_partner', 'version', 'INT NOT NULL DEFAULT 0');
|
||
|
||
CALL regression_add_column('wh_express_company', 'tenant_id', 'BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER id');
|
||
CALL regression_add_column('wh_express_company', 'company_code', 'VARCHAR(50) NOT NULL DEFAULT '''' AFTER tenant_id');
|
||
CALL regression_add_column('wh_express_company', 'company_name', 'VARCHAR(128) NOT NULL DEFAULT '''' AFTER company_code');
|
||
CALL regression_add_column('wh_express_company', 'service_phone', 'VARCHAR(32) NULL');
|
||
CALL regression_add_column('wh_express_company', 'website', 'VARCHAR(255) NULL');
|
||
CALL regression_add_column('wh_express_company', 'tracking_url_template', 'VARCHAR(500) NULL');
|
||
CALL regression_add_column('wh_express_company', 'status', 'VARCHAR(20) NOT NULL DEFAULT ''ACTIVE'' AFTER tracking_url_template');
|
||
CALL regression_add_column('wh_express_company', 'remark', 'VARCHAR(500) NULL');
|
||
CALL regression_add_column('wh_express_company', 'created_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_express_company', 'created_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_express_company', 'updated_by', 'BIGINT UNSIGNED NULL');
|
||
CALL regression_add_column('wh_express_company', 'updated_at', 'DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)');
|
||
CALL regression_add_column('wh_express_company', 'deleted', 'TINYINT(1) NOT NULL DEFAULT 0');
|
||
CALL regression_add_column('wh_express_company', 'version', 'INT NOT NULL DEFAULT 0');
|
||
|
||
DROP PROCEDURE regression_add_column;
|
||
|
||
DROP PROCEDURE IF EXISTS regression_add_index;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_add_index(
|
||
IN p_table_name VARCHAR(64),
|
||
IN p_index_name VARCHAR(64),
|
||
IN p_index_definition TEXT
|
||
)
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.statistics
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = p_table_name
|
||
AND index_name = p_index_name
|
||
) THEN
|
||
SET @regression_index_sql = CONCAT(
|
||
'ALTER TABLE `', REPLACE(p_table_name, '`', '``'),
|
||
'` ADD ', p_index_definition
|
||
);
|
||
PREPARE regression_index_stmt FROM @regression_index_sql;
|
||
EXECUTE regression_index_stmt;
|
||
DEALLOCATE PREPARE regression_index_stmt;
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
|
||
CALL regression_add_index('wh_warehouse', 'idx_wh_tenant_status', 'KEY idx_wh_tenant_status (tenant_id, status, deleted)');
|
||
CALL regression_add_index('wh_warehouse_address', 'idx_address_warehouse', 'KEY idx_address_warehouse (tenant_id, warehouse_id, deleted)');
|
||
CALL regression_add_index('wh_service_capability', 'idx_capability_query', 'KEY idx_capability_query (tenant_id, warehouse_id, enabled, deleted)');
|
||
CALL regression_add_index('wh_partner', 'idx_wh_partner_tenant_status', 'KEY idx_wh_partner_tenant_status (tenant_id, status, deleted)');
|
||
CALL regression_add_index('wh_partner', 'uk_wh_partner_tenant_code', 'UNIQUE KEY uk_wh_partner_tenant_code (tenant_id, partner_code, deleted)');
|
||
CALL regression_add_index('wh_express_company', 'idx_wh_express_tenant_status', 'KEY idx_wh_express_tenant_status (tenant_id, status, deleted)');
|
||
CALL regression_add_index('wh_express_company', 'uk_wh_express_tenant_code', 'UNIQUE KEY uk_wh_express_tenant_code (tenant_id, company_code, deleted)');
|
||
DROP PROCEDURE regression_add_index;
|
||
|
||
-- ============================================================================
|
||
-- 3. Order:一期订单快照字段、货物字段和持久化幂等记录
|
||
-- ============================================================================
|
||
USE baiyue_order;
|
||
|
||
DROP PROCEDURE IF EXISTS regression_assert_order_table;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_assert_order_table(IN p_table_name VARCHAR(64))
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.tables
|
||
WHERE table_schema = DATABASE() AND table_name = p_table_name
|
||
) THEN
|
||
SIGNAL SQLSTATE '45000'
|
||
SET MESSAGE_TEXT = 'baiyue_order 缺少订单基础表,请先执行 order.sql';
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
CALL regression_assert_order_table('ord_order');
|
||
CALL regression_assert_order_table('ord_order_cargo');
|
||
DROP PROCEDURE regression_assert_order_table;
|
||
|
||
DROP PROCEDURE IF EXISTS regression_add_order_column;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_add_order_column(
|
||
IN p_table_name VARCHAR(64),
|
||
IN p_column_name VARCHAR(64),
|
||
IN p_definition VARCHAR(1000)
|
||
)
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = p_table_name
|
||
AND column_name = p_column_name
|
||
) THEN
|
||
SET @regression_order_sql = CONCAT(
|
||
'ALTER TABLE `', p_table_name, '` ADD COLUMN `', p_column_name, '` ', p_definition
|
||
);
|
||
PREPARE regression_order_stmt FROM @regression_order_sql;
|
||
EXECUTE regression_order_stmt;
|
||
DEALLOCATE PREPARE regression_order_stmt;
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
|
||
CALL regression_add_order_column('ord_order', 'pickup_method', 'VARCHAR(24) NULL COMMENT ''提货方式''');
|
||
CALL regression_add_order_column('ord_order', 'receiving_warehouse_id', 'BIGINT UNSIGNED NULL COMMENT ''国内收货仓ID''');
|
||
CALL regression_add_order_column('ord_order', 'receiving_warehouse_name', 'VARCHAR(128) NULL COMMENT ''国内收货仓名称快照''');
|
||
CALL regression_add_order_column('ord_order', 'receiving_warehouse_address', 'VARCHAR(512) NULL COMMENT ''国内收货仓完整地址快照''');
|
||
CALL regression_add_order_column('ord_order', 'receiving_time', 'VARCHAR(128) NULL COMMENT ''国内收货仓收货时间快照''');
|
||
CALL regression_add_order_column('ord_order', 'channel_code', 'VARCHAR(64) NULL COMMENT ''运输渠道编码''');
|
||
CALL regression_add_order_column('ord_order', 'channel_name', 'VARCHAR(128) NULL COMMENT ''运输渠道名称快照''');
|
||
CALL regression_add_order_column('ord_order', 'tax_mode', 'VARCHAR(24) NULL COMMENT ''报关买单或退税模式''');
|
||
CALL regression_add_order_column('ord_order', 'container_mode', 'VARCHAR(24) NULL COMMENT ''整柜或散货模式''');
|
||
CALL regression_add_order_column('ord_order', 'customs_inspection', 'TINYINT(1) NULL COMMENT ''是否需要海关查验''');
|
||
CALL regression_add_order_column('ord_order', 'destination_type', 'VARCHAR(24) NULL COMMENT ''FBA、海外仓或私人地址''');
|
||
CALL regression_add_order_column('ord_order', 'amazon_warehouse_code', 'VARCHAR(32) NULL COMMENT ''亚马逊仓库编码''');
|
||
CALL regression_add_order_column('ord_order', 'shipment_id', 'VARCHAR(64) NULL COMMENT ''亚马逊Shipment ID''');
|
||
CALL regression_add_order_column('ord_order', 'reference_id', 'VARCHAR(64) NULL COMMENT ''亚马逊Reference ID''');
|
||
CALL regression_add_order_column('ord_order', 'express_company', 'VARCHAR(64) NULL COMMENT ''履约快递公司名称快照''');
|
||
CALL regression_add_order_column('ord_order', 'express_tracking_no', 'VARCHAR(128) NULL COMMENT ''履约快递单号''');
|
||
|
||
CALL regression_add_order_column('ord_order_cargo', 'sku_no', 'VARCHAR(64) NULL COMMENT ''SKU编号''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'upc_no', 'VARCHAR(64) NULL COMMENT ''UPC编号''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'cargo_name_en', 'VARCHAR(128) NULL COMMENT ''货物英文名称''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'customs_hs_code', 'VARCHAR(20) NULL COMMENT ''目的国海关HS编码''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'units_per_package', 'INT UNSIGNED NULL COMMENT ''每箱件数''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'total_quantity', 'INT UNSIGNED NULL COMMENT ''总件数''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'net_weight_kg', 'DECIMAL(18,3) NULL COMMENT ''净重千克''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'unit_declared_value', 'DECIMAL(18,2) NULL COMMENT ''单件申报价值''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'material', 'VARCHAR(128) NULL COMMENT ''材质''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'product_usage', 'VARCHAR(128) NULL COMMENT ''用途''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'model', 'VARCHAR(64) NULL COMMENT ''型号''');
|
||
CALL regression_add_order_column('ord_order_cargo', 'brand', 'VARCHAR(64) NULL COMMENT ''品牌''');
|
||
DROP PROCEDURE regression_add_order_column;
|
||
|
||
CREATE TABLE IF NOT EXISTS ord_idempotency_record (
|
||
id BIGINT UNSIGNED NOT NULL COMMENT '幂等记录ID',
|
||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
|
||
operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID',
|
||
operation VARCHAR(32) NOT NULL COMMENT '操作类型',
|
||
resource_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '资源ID',
|
||
idempotency_key VARCHAR(128) NOT NULL COMMENT '客户端幂等键',
|
||
request_hash CHAR(64) NOT NULL COMMENT '请求内容摘要',
|
||
status VARCHAR(16) NOT NULL COMMENT '处理状态',
|
||
result_order_id BIGINT UNSIGNED NULL COMMENT '重放结果订单ID',
|
||
completed_at DATETIME(3) NULL COMMENT '完成时间',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_order_idempotency_scope (tenant_id, operator_id, operation, idempotency_key),
|
||
KEY idx_order_idempotency_created (created_at)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单写接口持久化幂等记录';
|
||
|
||
-- 兼容曾经只建表但未建立完整索引的测试库。
|
||
SET @order_idempotency_unique_sql = IF(
|
||
EXISTS(
|
||
SELECT 1 FROM information_schema.statistics
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 'ord_idempotency_record'
|
||
AND index_name = 'uk_order_idempotency_scope'
|
||
),
|
||
'SELECT 1',
|
||
'ALTER TABLE ord_idempotency_record ADD UNIQUE KEY uk_order_idempotency_scope (tenant_id, operator_id, operation, idempotency_key)'
|
||
);
|
||
PREPARE order_idempotency_unique_stmt FROM @order_idempotency_unique_sql;
|
||
EXECUTE order_idempotency_unique_stmt;
|
||
DEALLOCATE PREPARE order_idempotency_unique_stmt;
|
||
|
||
SET @order_idempotency_created_sql = IF(
|
||
EXISTS(
|
||
SELECT 1 FROM information_schema.statistics
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 'ord_idempotency_record'
|
||
AND index_name = 'idx_order_idempotency_created'
|
||
),
|
||
'SELECT 1',
|
||
'ALTER TABLE ord_idempotency_record ADD KEY idx_order_idempotency_created (created_at)'
|
||
);
|
||
PREPARE order_idempotency_created_stmt FROM @order_idempotency_created_sql;
|
||
EXECUTE order_idempotency_created_stmt;
|
||
DEALLOCATE PREPARE order_idempotency_created_stmt;
|
||
|
||
-- ============================================================================
|
||
-- 4. Firstleg:履约任务分页索引
|
||
-- ============================================================================
|
||
USE baiyue_firstleg;
|
||
|
||
DROP PROCEDURE IF EXISTS regression_assert_firstleg_table;
|
||
DELIMITER $$
|
||
CREATE PROCEDURE regression_assert_firstleg_table()
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.tables
|
||
WHERE table_schema = DATABASE() AND table_name = 'fl_fulfillment_task'
|
||
) THEN
|
||
SIGNAL SQLSTATE '45000'
|
||
SET MESSAGE_TEXT = 'baiyue_firstleg 缺少履约任务基础表,请先执行 firstleg.sql';
|
||
END IF;
|
||
END$$
|
||
DELIMITER ;
|
||
CALL regression_assert_firstleg_table();
|
||
DROP PROCEDURE regression_assert_firstleg_table;
|
||
|
||
SET @firstleg_task_list_index_sql = IF(
|
||
EXISTS(
|
||
SELECT 1 FROM information_schema.statistics
|
||
WHERE table_schema = DATABASE()
|
||
AND table_name = 'fl_fulfillment_task'
|
||
AND index_name = 'idx_task_tenant_created'
|
||
),
|
||
'SELECT 1',
|
||
'CREATE INDEX idx_task_tenant_created ON fl_fulfillment_task (tenant_id, created_at)'
|
||
);
|
||
PREPARE firstleg_task_list_index_stmt FROM @firstleg_task_list_index_sql;
|
||
EXECUTE firstleg_task_list_index_stmt;
|
||
DEALLOCATE PREPARE firstleg_task_list_index_stmt;
|
||
|
||
-- ============================================================================
|
||
-- 5. File:公共导出与下载中心任务表
|
||
-- ============================================================================
|
||
USE baiyue_file;
|
||
|
||
CREATE TABLE IF NOT EXISTS file_export_task (
|
||
id BIGINT UNSIGNED NOT NULL COMMENT '导出任务ID(雪花ID)',
|
||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '申请人所属租户ID,平台任务为0',
|
||
app_code VARCHAR(24) NOT NULL COMMENT '申请端',
|
||
task_no VARCHAR(40) NOT NULL COMMENT '导出任务编号',
|
||
export_type VARCHAR(64) NOT NULL COMMENT '导出类型',
|
||
format VARCHAR(16) NOT NULL DEFAULT 'XLSX' COMMENT '导出格式',
|
||
task_name VARCHAR(128) NOT NULL COMMENT '任务名称',
|
||
parameters_json JSON NOT NULL COMMENT '筛选条件快照',
|
||
status VARCHAR(24) NOT NULL DEFAULT 'PENDING' COMMENT '任务状态',
|
||
total_rows BIGINT UNSIGNED NULL,
|
||
processed_rows BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||
file_name VARCHAR(255) NULL,
|
||
object_key VARCHAR(512) NULL,
|
||
content_type VARCHAR(128) NULL,
|
||
size_bytes BIGINT UNSIGNED NULL,
|
||
failure_message VARCHAR(1000) NULL,
|
||
requested_by BIGINT UNSIGNED NOT NULL,
|
||
requested_username VARCHAR(128) NULL,
|
||
requested_at DATETIME(3) NOT NULL,
|
||
started_at DATETIME(3) NULL,
|
||
completed_at DATETIME(3) NULL,
|
||
expires_at DATETIME(3) NULL,
|
||
created_by BIGINT UNSIGNED NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_by BIGINT UNSIGNED 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),
|
||
UNIQUE KEY uk_file_export_task_no (task_no),
|
||
KEY idx_file_export_owner (tenant_id, app_code, requested_by, requested_at),
|
||
KEY idx_file_export_status (status, requested_at),
|
||
KEY idx_file_export_expiry (status, expires_at)
|
||
) ENGINE=InnoDB COMMENT='公共异步导出任务表';
|
||
|
||
-- ============================================================================
|
||
-- 6. 执行后只读核验
|
||
-- ============================================================================
|
||
SELECT
|
||
'IAM权限资源' AS check_item,
|
||
COUNT(*) AS actual_count,
|
||
47 AS expected_count,
|
||
IF(COUNT(*) = 47, '通过', '请检查缺失权限') AS check_result
|
||
FROM baiyue_iam.iam_permission
|
||
WHERE deleted = 0
|
||
AND permission_code IN (
|
||
'platform:customer', 'platform:customer:list', 'platform:customer:create',
|
||
'platform:customer:view', 'platform:customer:edit', 'platform:customer:status', 'platform:customer:export',
|
||
'platform:system', 'platform:user:list', 'platform:user:create', 'platform:user:edit',
|
||
'platform:user:status', 'platform:user:reset-password', 'platform:user:grant-role',
|
||
'platform:role:list', 'platform:role:create', 'platform:role:grant',
|
||
'platform:role:edit', 'platform:role:status', 'platform:role:delete',
|
||
'platform:member:list', 'platform:member:grant-role',
|
||
'platform:permission:list', 'platform:permission:create', 'platform:permission:edit',
|
||
'platform:permission:status', 'platform:permission:delete',
|
||
'platform:order', 'platform:order:list', 'platform:order:create',
|
||
'platform:order:edit', 'platform:order:submit',
|
||
'platform:firstleg:task:list', 'platform:firstleg:task:view',
|
||
'platform:firstleg:assignment:history', 'platform:firstleg:assignment:assign',
|
||
'platform:master-data', 'platform:express:list', 'platform:express:create',
|
||
'platform:express:edit', 'platform:express:status',
|
||
'platform:counterparty:list', 'platform:counterparty:create',
|
||
'platform:counterparty:edit', 'platform:counterparty:status',
|
||
'platform:download:list', 'platform:download:all'
|
||
);
|
||
|
||
SELECT
|
||
'IAM客户档案字段' AS check_item,
|
||
COUNT(*) AS actual_count,
|
||
9 AS expected_count,
|
||
IF(COUNT(*) = 9, '通过', '请检查客户档案字段迁移') AS check_result
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'baiyue_iam'
|
||
AND table_name = 'iam_tenant'
|
||
AND column_name IN (
|
||
'contact_wechat', 'sales_owner_name', 'payment_term_days', 'enterprise_type',
|
||
'established_date', 'registered_capital', 'registered_capital_currency',
|
||
'registered_address', 'internal_remark'
|
||
);
|
||
|
||
SELECT
|
||
table_name,
|
||
COUNT(*) AS column_count
|
||
FROM information_schema.columns
|
||
WHERE table_schema = 'baiyue_warehouse'
|
||
AND table_name IN (
|
||
'wh_warehouse', 'wh_warehouse_address', 'wh_service_capability',
|
||
'wh_partner', 'wh_express_company'
|
||
)
|
||
GROUP BY table_name
|
||
ORDER BY table_name;
|
||
|
||
SELECT
|
||
IF(COUNT(*) = 1, '通过', '缺失') AS idempotency_table,
|
||
'baiyue_order.ord_idempotency_record' AS object_name
|
||
FROM information_schema.tables
|
||
WHERE table_schema = 'baiyue_order'
|
||
AND table_name = 'ord_idempotency_record';
|
||
|
||
SELECT
|
||
IF(COUNT(*) > 0, '通过', '缺失') AS idempotency_unique_index,
|
||
'uk_order_idempotency_scope' AS object_name
|
||
FROM information_schema.statistics
|
||
WHERE table_schema = 'baiyue_order'
|
||
AND table_name = 'ord_idempotency_record'
|
||
AND index_name = 'uk_order_idempotency_scope';
|
||
|
||
SELECT
|
||
IF(COUNT(*) > 0, '通过', '缺失') AS firstleg_task_index,
|
||
'idx_task_tenant_created' AS object_name
|
||
FROM information_schema.statistics
|
||
WHERE table_schema = 'baiyue_firstleg'
|
||
AND table_name = 'fl_fulfillment_task'
|
||
AND index_name = 'idx_task_tenant_created';
|
||
|
||
SELECT
|
||
IF(COUNT(*) = 1, '通过', '缺失') AS export_task_table,
|
||
'baiyue_file.file_export_task' AS object_name
|
||
FROM information_schema.tables
|
||
WHERE table_schema = 'baiyue_file'
|
||
AND table_name = 'file_export_task';
|
||
|
||
SELECT 'MIGRATION_COMPLETED' AS migration_status,
|
||
'请确认上方所有核验结果均为通过后再启动服务回归' AS message;
|