diff --git a/migrations/045_wheel_limits_probability_retry.sql b/migrations/045_wheel_limits_probability_retry.sql index d53f8d6..0d8df35 100644 --- a/migrations/045_wheel_limits_probability_retry.sql +++ b/migrations/045_wheel_limits_probability_retry.sql @@ -112,19 +112,45 @@ PREPARE add_wheel_draw_reward_user_idx_stmt FROM @add_wheel_draw_reward_user_idx EXECUTE add_wheel_draw_reward_user_idx_stmt; DEALLOCATE PREPARE add_wheel_draw_reward_user_idx_stmt; -SET @wheel_reward_probability_max := ( - SELECT COALESCE(MAX(`probability`), 0) FROM `wheel_reward_config` -); -SET @wheel_record_probability_max := ( - SELECT COALESCE(MAX(`probability`), 0) FROM `wheel_draw_record` -); +CREATE TABLE IF NOT EXISTS `schema_repair_marker` ( + `name` varchar(128) NOT NULL COMMENT '修复标记', + `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='可重复执行Schema修复标记'; + +INSERT IGNORE INTO `schema_repair_marker` (`name`) +SELECT '045_wheel_reward_probability_1000000_global' +WHERE (SELECT COALESCE(MAX(`probability`), 0) FROM `wheel_reward_config`) BETWEEN 1 AND 10000; +SET @convert_wheel_reward_probability_global := ROW_COUNT(); UPDATE `wheel_reward_config` SET `probability` = `probability` * 100 -WHERE @wheel_reward_probability_max > 0 - AND @wheel_reward_probability_max <= 10000; +WHERE @convert_wheel_reward_probability_global = 1; + +UPDATE `wheel_reward_config` reward +JOIN ( + SELECT `config_id`, `category` + FROM `wheel_reward_config` + GROUP BY `config_id`, `category` + HAVING SUM(CASE WHEN `enabled` = 1 THEN `probability` ELSE 0 END) = 10000 + AND MAX(`probability`) <= 10000 +) candidate + ON candidate.`config_id` = reward.`config_id` + AND candidate.`category` = reward.`category` +SET reward.`probability` = reward.`probability` * 100; + +INSERT IGNORE INTO `schema_repair_marker` (`name`) +SELECT '045_wheel_draw_record_probability_1000000_global' +WHERE (SELECT COALESCE(MAX(`probability`), 0) FROM `wheel_draw_record`) BETWEEN 1 AND 10000; +SET @convert_wheel_record_probability_global := ROW_COUNT(); UPDATE `wheel_draw_record` SET `probability` = `probability` * 100 -WHERE @wheel_record_probability_max > 0 - AND @wheel_record_probability_max <= 10000; +WHERE @convert_wheel_record_probability_global = 1; + +UPDATE `wheel_draw_record` record +JOIN `wheel_reward_config` reward + ON reward.`id` = record.`reward_config_id` +SET record.`probability` = reward.`probability` +WHERE record.`probability` BETWEEN 1 AND 10000 + AND reward.`probability` = record.`probability` * 100; diff --git a/migrations/047_wheel_probability_schema_repair.sql b/migrations/047_wheel_probability_schema_repair.sql new file mode 100644 index 0000000..ffd29e0 --- /dev/null +++ b/migrations/047_wheel_probability_schema_repair.sql @@ -0,0 +1,150 @@ +SET @current_schema := DATABASE(); + +CREATE TABLE IF NOT EXISTS `schema_repair_marker` ( + `name` varchar(128) NOT NULL COMMENT '修复标记', + `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='可重复执行Schema修复标记'; + +SET @add_wheel_reward_total_limit_sql := IF( + NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = @current_schema + AND table_name = 'wheel_reward_config' + AND column_name = 'total_limit' + ), + 'ALTER TABLE `wheel_reward_config` ADD COLUMN `total_limit` bigint NOT NULL DEFAULT 0 COMMENT ''奖品总发放上限,0表示不限'' AFTER `probability`', + 'SELECT 1' +); +PREPARE add_wheel_reward_total_limit_stmt FROM @add_wheel_reward_total_limit_sql; +EXECUTE add_wheel_reward_total_limit_stmt; +DEALLOCATE PREPARE add_wheel_reward_total_limit_stmt; + +SET @add_wheel_reward_user_limit_sql := IF( + NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = @current_schema + AND table_name = 'wheel_reward_config' + AND column_name = 'user_limit' + ), + 'ALTER TABLE `wheel_reward_config` ADD COLUMN `user_limit` bigint NOT NULL DEFAULT 0 COMMENT ''单用户发放上限,0表示不限'' AFTER `total_limit`', + 'SELECT 1' +); +PREPARE add_wheel_reward_user_limit_stmt FROM @add_wheel_reward_user_limit_sql; +EXECUTE add_wheel_reward_user_limit_stmt; +DEALLOCATE PREPARE add_wheel_reward_user_limit_stmt; + +SET @add_wheel_reward_issued_count_sql := IF( + NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = @current_schema + AND table_name = 'wheel_reward_config' + AND column_name = 'issued_count' + ), + 'ALTER TABLE `wheel_reward_config` ADD COLUMN `issued_count` bigint NOT NULL DEFAULT 0 COMMENT ''已占用发放数量,PENDING/SUCCESS/FAILED发奖占用'' AFTER `user_limit`', + 'SELECT 1' +); +PREPARE add_wheel_reward_issued_count_stmt FROM @add_wheel_reward_issued_count_sql; +EXECUTE add_wheel_reward_issued_count_stmt; +DEALLOCATE PREPARE add_wheel_reward_issued_count_stmt; + +SET @add_wheel_draw_reward_config_id_sql := IF( + NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = @current_schema + AND table_name = 'wheel_draw_record' + AND column_name = 'reward_config_id' + ), + 'ALTER TABLE `wheel_draw_record` ADD COLUMN `reward_config_id` bigint NOT NULL DEFAULT 0 COMMENT ''命中奖项配置ID'' AFTER `paid_gold`', + 'SELECT 1' +); +PREPARE add_wheel_draw_reward_config_id_stmt FROM @add_wheel_draw_reward_config_id_sql; +EXECUTE add_wheel_draw_reward_config_id_stmt; +DEALLOCATE PREPARE add_wheel_draw_reward_config_id_stmt; + +SET @add_wheel_draw_retry_count_sql := IF( + NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = @current_schema + AND table_name = 'wheel_draw_record' + AND column_name = 'retry_count' + ), + 'ALTER TABLE `wheel_draw_record` ADD COLUMN `retry_count` int NOT NULL DEFAULT 0 COMMENT ''发奖尝试次数'' AFTER `status`', + 'SELECT 1' +); +PREPARE add_wheel_draw_retry_count_stmt FROM @add_wheel_draw_retry_count_sql; +EXECUTE add_wheel_draw_retry_count_stmt; +DEALLOCATE PREPARE add_wheel_draw_retry_count_stmt; + +SET @add_wheel_draw_grant_time_sql := IF( + NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = @current_schema + AND table_name = 'wheel_draw_record' + AND column_name = 'grant_time' + ), + 'ALTER TABLE `wheel_draw_record` ADD COLUMN `grant_time` datetime(3) DEFAULT NULL COMMENT ''发奖成功时间'' AFTER `error_message`', + 'SELECT 1' +); +PREPARE add_wheel_draw_grant_time_stmt FROM @add_wheel_draw_grant_time_sql; +EXECUTE add_wheel_draw_grant_time_stmt; +DEALLOCATE PREPARE add_wheel_draw_grant_time_stmt; + +UPDATE `wheel_reward_config` +SET `probability` = COALESCE(`probability`, 0), + `total_limit` = COALESCE(`total_limit`, 0), + `user_limit` = COALESCE(`user_limit`, 0), + `issued_count` = COALESCE(`issued_count`, 0); + +UPDATE `wheel_draw_record` +SET `probability` = COALESCE(`probability`, 0), + `reward_config_id` = COALESCE(`reward_config_id`, 0), + `retry_count` = COALESCE(`retry_count`, 0); + +ALTER TABLE `wheel_reward_config` + MODIFY COLUMN `probability` int NOT NULL DEFAULT 0 COMMENT '中奖概率,百万分比,100%=1000000' AFTER `gold_amount`, + MODIFY COLUMN `total_limit` bigint NOT NULL DEFAULT 0 COMMENT '奖品总发放上限,0表示不限' AFTER `probability`, + MODIFY COLUMN `user_limit` bigint NOT NULL DEFAULT 0 COMMENT '单用户发放上限,0表示不限' AFTER `total_limit`, + MODIFY COLUMN `issued_count` bigint NOT NULL DEFAULT 0 COMMENT '已占用发放数量,PENDING/SUCCESS/FAILED发奖占用' AFTER `user_limit`; + +ALTER TABLE `wheel_draw_record` + MODIFY COLUMN `reward_config_id` bigint NOT NULL DEFAULT 0 COMMENT '命中奖项配置ID' AFTER `paid_gold`, + MODIFY COLUMN `probability` int NOT NULL DEFAULT 0 COMMENT '概率快照,百万分比,100%=1000000' AFTER `gold_amount`, + MODIFY COLUMN `retry_count` int NOT NULL DEFAULT 0 COMMENT '发奖尝试次数' AFTER `status`, + MODIFY COLUMN `grant_time` datetime(3) DEFAULT NULL COMMENT '发奖成功时间' AFTER `error_message`; + +UPDATE `wheel_reward_config` reward +JOIN ( + SELECT `config_id`, `category` + FROM `wheel_reward_config` + GROUP BY `config_id`, `category` + HAVING SUM(CASE WHEN `enabled` = 1 THEN `probability` ELSE 0 END) = 10000 + AND MAX(`probability`) <= 10000 +) candidate + ON candidate.`config_id` = reward.`config_id` + AND candidate.`category` = reward.`category` +SET reward.`probability` = reward.`probability` * 100; + +CREATE TEMPORARY TABLE `tmp_wheel_record_probability_sys_origin` AS +SELECT grouped.`sys_origin` +FROM ( + SELECT `sys_origin`, MAX(`probability`) AS `max_probability` + FROM `wheel_draw_record` + GROUP BY `sys_origin` +) grouped +WHERE grouped.`max_probability` BETWEEN 1 AND 10000 + AND NOT EXISTS ( + SELECT 1 FROM `schema_repair_marker` + WHERE `name` = CONCAT('047_wheel_draw_record_probability_1000000_', grouped.`sys_origin`) + ); + +INSERT IGNORE INTO `schema_repair_marker` (`name`) +SELECT CONCAT('047_wheel_draw_record_probability_1000000_', `sys_origin`) +FROM `tmp_wheel_record_probability_sys_origin`; + +UPDATE `wheel_draw_record` record +JOIN `tmp_wheel_record_probability_sys_origin` candidate + ON candidate.`sys_origin` = record.`sys_origin` +SET record.`probability` = record.`probability` * 100; + +DROP TEMPORARY TABLE `tmp_wheel_record_probability_sys_origin`;