153 lines
7.6 KiB
SQL
153 lines
7.6 KiB
SQL
-- 价格套餐版本中间表 + 版本附加费
|
|
-- 关系:
|
|
-- prc_price_set
|
|
-- -> prc_price_set_version (步骤2: 版本号自动生成, 生效时间)
|
|
-- -> prc_price_set_detail (步骤3: 产品价格, 通过 psv_id)
|
|
-- -> prc_price_set_version_surcharge (psd_id 关联明细)
|
|
-- 可重复执行
|
|
SET NAMES utf8mb4;
|
|
SET @db := DATABASE();
|
|
|
|
CREATE TABLE IF NOT EXISTS prc_price_set_version (
|
|
psv_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '套餐版本id',
|
|
price_set_id BIGINT(20) NOT NULL COMMENT '价格套餐id',
|
|
version_no VARCHAR(20) NOT NULL COMMENT '版本号 V1/V2,自动+1',
|
|
version_seq INT(11) NOT NULL COMMENT '版本序号,用于自动+1',
|
|
effective_time DATETIME DEFAULT NULL COMMENT 'version start time (null until activate)',
|
|
expire_time DATETIME DEFAULT NULL COMMENT '失效时间(空=长期;下一版本启动时写入该启动时间)',
|
|
status CHAR(1) NOT NULL DEFAULT '0' COMMENT '0草稿 1生效 2失效',
|
|
created_by VARCHAR(64) DEFAULT '' COMMENT '创建人',
|
|
create_time DATETIME DEFAULT NULL COMMENT '创建时间',
|
|
updated_by VARCHAR(64) DEFAULT '' COMMENT '更新人',
|
|
update_time DATETIME DEFAULT NULL COMMENT '更新时间',
|
|
PRIMARY KEY (psv_id),
|
|
UNIQUE KEY uk_psv_set_no (price_set_id, version_no),
|
|
UNIQUE KEY uk_psv_set_seq (price_set_id, version_seq),
|
|
INDEX idx_psv_set_eff (price_set_id, effective_time),
|
|
INDEX idx_psv_status (status),
|
|
CONSTRAINT fk_psv_set FOREIGN KEY (price_set_id) REFERENCES prc_price_set (price_set_id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='价格套餐版本';
|
|
|
|
CREATE TABLE IF NOT EXISTS prc_price_set_version_surcharge (
|
|
psvs_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '版本附加费id',
|
|
psv_id BIGINT(20) NOT NULL COMMENT '套餐版本id',
|
|
psd_id BIGINT(20) NOT NULL COMMENT '套餐明细id',
|
|
sc_id BIGINT(20) DEFAULT NULL COMMENT '来源附加费配置id',
|
|
product_code VARCHAR(20) DEFAULT NULL COMMENT '产品代码(与明细一致)',
|
|
sc_name VARCHAR(100) NOT NULL COMMENT '附加费名称快照',
|
|
fee_type VARCHAR(30) NOT NULL DEFAULT 'SURCHARGE' COMMENT '费用类型(字典bms_fee_type)',
|
|
charge_type VARCHAR(20) NOT NULL COMMENT '计费方式 FIXED固定金额/WEIGHT按重量/RATE按比例',
|
|
charge_value DECIMAL(18,6) NOT NULL COMMENT '计费数值快照',
|
|
currency CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种',
|
|
round_mode VARCHAR(20) NOT NULL DEFAULT 'HALF_UP' COMMENT '取值方式(字典bms_round_mode)',
|
|
country_code CHAR(2) DEFAULT NULL COMMENT '适用国家ISO2(空=全部)',
|
|
sc_note VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
|
created_by VARCHAR(64) DEFAULT '' COMMENT '创建人',
|
|
create_time DATETIME DEFAULT NULL COMMENT '创建时间',
|
|
updated_by VARCHAR(64) DEFAULT '' COMMENT '更新人',
|
|
update_time DATETIME DEFAULT NULL COMMENT '更新时间',
|
|
PRIMARY KEY (psvs_id),
|
|
INDEX idx_psvs_psv (psv_id),
|
|
INDEX idx_psvs_psd (psd_id),
|
|
INDEX idx_psvs_product (psv_id, product_code),
|
|
INDEX idx_psvs_sc (sc_id),
|
|
CONSTRAINT fk_psvs_psv FOREIGN KEY (psv_id) REFERENCES prc_price_set_version (psv_id) ON DELETE CASCADE,
|
|
CONSTRAINT fk_psvs_psd FOREIGN KEY (psd_id) REFERENCES prc_price_set_detail (psd_id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='价格套餐版本附加费快照';
|
|
|
|
|
|
-- expire_time: previous version expire = next version effective_time (start)
|
|
SET @has := (
|
|
SELECT COUNT(*) FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'prc_price_set_version' AND COLUMN_NAME = 'expire_time'
|
|
);
|
|
SET @sql := IF(@has = 0,
|
|
'ALTER TABLE prc_price_set_version ADD COLUMN expire_time DATETIME DEFAULT NULL COMMENT ''失效时间(空=长期;下一版本启动时写入该启动时间)'' AFTER effective_time',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
-- backfill: expire_time = next version start time (by version_seq)
|
|
UPDATE prc_price_set_version cur
|
|
INNER JOIN prc_price_set_version nxt
|
|
ON nxt.price_set_id = cur.price_set_id
|
|
AND nxt.version_seq = cur.version_seq + 1
|
|
SET cur.expire_time = nxt.effective_time;
|
|
|
|
-- prc_price_set_detail.psv_id
|
|
SET @has := (
|
|
SELECT COUNT(*) FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'prc_price_set_detail' AND COLUMN_NAME = 'psv_id'
|
|
);
|
|
SET @sql := IF(@has = 0,
|
|
'ALTER TABLE prc_price_set_detail ADD COLUMN psv_id BIGINT(20) DEFAULT NULL COMMENT ''套餐版本id'' AFTER price_set_id',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
SET @has := (
|
|
SELECT COUNT(*) FROM information_schema.STATISTICS
|
|
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'prc_price_set_detail' AND INDEX_NAME = 'idx_psd_psv'
|
|
);
|
|
SET @sql := IF(@has = 0,
|
|
'ALTER TABLE prc_price_set_detail ADD INDEX idx_psd_psv (psv_id)',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
SET @has := (
|
|
SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
|
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'prc_price_set_detail' AND CONSTRAINT_NAME = 'fk_psd_psv'
|
|
);
|
|
SET @sql := IF(@has = 0,
|
|
'ALTER TABLE prc_price_set_detail ADD CONSTRAINT fk_psd_psv FOREIGN KEY (psv_id) REFERENCES prc_price_set_version (psv_id) ON DELETE CASCADE',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
-- 已建表补关联: 附加费.psd_id -> 套餐明细
|
|
DELETE FROM prc_price_set_version_surcharge
|
|
WHERE psd_id IS NULL
|
|
OR NOT EXISTS (
|
|
SELECT 1 FROM prc_price_set_detail d WHERE d.psd_id = prc_price_set_version_surcharge.psd_id
|
|
);
|
|
|
|
SET @sql := CONCAT(
|
|
'ALTER TABLE prc_price_set_version_surcharge MODIFY COLUMN psd_id BIGINT(20) NOT NULL COMMENT ''套餐明细id'''
|
|
);
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
SET @has := (
|
|
SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
|
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'prc_price_set_version_surcharge' AND CONSTRAINT_NAME = 'fk_psvs_psd'
|
|
);
|
|
SET @sql := IF(@has = 0,
|
|
'ALTER TABLE prc_price_set_version_surcharge ADD CONSTRAINT fk_psvs_psd FOREIGN KEY (psd_id) REFERENCES prc_price_set_detail (psd_id) ON DELETE CASCADE',
|
|
'SELECT 1');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
-- 回填: 每个已有套餐生成一条 V1
|
|
INSERT INTO prc_price_set_version (
|
|
price_set_id, version_no, version_seq, effective_time, status, created_by, create_time
|
|
)
|
|
SELECT
|
|
s.price_set_id,
|
|
'V1',
|
|
1,
|
|
COALESCE(CAST(s.effective_date AS DATETIME), s.create_time, NOW()),
|
|
CASE
|
|
WHEN s.status = 'S' THEN '2'
|
|
WHEN s.expire_date IS NOT NULL AND s.expire_date <= CURDATE() THEN '2'
|
|
WHEN s.status = 'E' AND (s.effective_date IS NULL OR s.effective_date <= CURDATE()) THEN '1'
|
|
ELSE '0'
|
|
END,
|
|
IFNULL(s.created_by, ''),
|
|
NOW()
|
|
FROM prc_price_set s
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM prc_price_set_version v WHERE v.price_set_id = s.price_set_id
|
|
);
|
|
|
|
-- 将已有明细绑定到同一套餐的 V1
|
|
UPDATE prc_price_set_detail d
|
|
INNER JOIN prc_price_set_version v
|
|
ON v.price_set_id = d.price_set_id AND v.version_seq = 1
|
|
SET d.psv_id = v.psv_id
|
|
WHERE d.psv_id IS NULL;
|