Files
biz-api-cloud-zax/db/20260914_add_mch_auto_verify.sql
T
dzc 3b9ad6580a feat:大量导入用户创建钱包死锁问题
feat:自动核销
feat:订单页面修改、订单地图
2026-09-14 18:34:16 +08:00

194 lines
12 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.
-- 每日菜谱预约订单过期未核销自动核销。
-- 幂等迁移脚本:可反复执行。每个字段/索引先查 information_schema,已存在则跳过(执行 SELECT 1 占位),
-- 不存在才执行 DDL;部分应用过的库重跑不会报 Duplicate column / Duplicate key。
-- 前置条件:20260822(wallet 配置列、订单列)与 20260823(订单核销时间列)的锚点列需已存在,
-- 否则对应语句会因 AFTER 锚点缺失报错——这是有意的失败提示,请先补齐前置迁移。
-- 任务表部分兼容 20260822 任务表语句未成功落库(scene_biz_id 缺失)的环境,会自动补齐。
-- 权限复用 wallet_mchManage_setting、hard_hardAfterSale_view、hard_hardAfterSale_adminRefund,无需新增 sys_menu 记录。
-- 【可选诊断】任务表当前列与索引,执行后可对照确认脚本将补齐的内容。
SELECT COLUMN_NAME, COLUMN_TYPE, IFNULL(GENERATION_EXPRESSION, '') AS generation
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware'
AND TABLE_NAME = 'hard_auto_refund_task'
AND COLUMN_NAME IN ('task_type', 'trigger_time', 'restore_inventory', 'scene_biz_id')
ORDER BY ORDINAL_POSITION;
SELECT INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX SEPARATOR ',') AS index_columns
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware'
AND TABLE_NAME = 'hard_auto_refund_task'
GROUP BY INDEX_NAME
ORDER BY INDEX_NAME;
-- 一、Wallet 配置列(三列各自独立判断)。
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_wallet`.`mch_auto_refund_config` ADD COLUMN `auto_verify_enabled` char(1) NOT NULL DEFAULT ''0'' COMMENT ''过期未核销自动核销开关,0关闭,1开启'' AFTER `expired_reserve_refund_restore_inventory`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_wallet' AND TABLE_NAME = 'mch_auto_refund_config' AND COLUMN_NAME = 'auto_verify_enabled');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_wallet`.`mch_auto_refund_config` ADD COLUMN `auto_verify_days` int(11) DEFAULT NULL COMMENT ''支付后自动核销天数,允许1至365,开关开启时必填'' AFTER `auto_verify_enabled`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_wallet' AND TABLE_NAME = 'mch_auto_refund_config' AND COLUMN_NAME = 'auto_verify_days');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_wallet`.`mch_auto_refund_config` ADD COLUMN `auto_verify_restore_inventory` char(1) NOT NULL DEFAULT ''1'' COMMENT ''自动核销是否恢复线上池库存,0不恢复,1恢复'' AFTER `auto_verify_days`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_wallet' AND TABLE_NAME = 'mch_auto_refund_config' AND COLUMN_NAME = 'auto_verify_restore_inventory');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 二、订单快照与核销方式列(四列各自独立判断)。
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_order` ADD COLUMN `auto_verify_config_id` bigint(20) DEFAULT NULL COMMENT ''支付成功时命中的自动核销配置ID快照,为空表示不参与自动核销'' AFTER `expired_refund_restore_inventory`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_order' AND COLUMN_NAME = 'auto_verify_config_id');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_order` ADD COLUMN `auto_verify_deadline` datetime DEFAULT NULL COMMENT ''支付时间加配置天数后的自动核销触发时间'' AFTER `auto_verify_config_id`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_order' AND COLUMN_NAME = 'auto_verify_deadline');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_order` ADD COLUMN `auto_verify_restore_inventory` char(1) DEFAULT NULL COMMENT ''自动核销退库存快照,0不恢复,1恢复线上池库存'' AFTER `auto_verify_deadline`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_order' AND COLUMN_NAME = 'auto_verify_restore_inventory');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_order` ADD COLUMN `verification_type` char(1) DEFAULT NULL COMMENT ''核销方式,1人工核销,2自动核销;历史已核销订单为空视为人工'' AFTER `verification_time`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_order' AND COLUMN_NAME = 'verification_type');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 三、任务表:兼容 20260822 任务表语句未落库的环境,先确保任务场景列存在(幂等 MODIFY 注释与空值语义)。
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` ADD COLUMN `task_type` char(10) NOT NULL DEFAULT ''10'' COMMENT ''任务场景,10用户免审售后,20过期预约退款,30过期未核销自动核销'' AFTER `after_sale_id`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND COLUMN_NAME = 'task_type');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` ADD COLUMN `trigger_time` datetime DEFAULT NULL COMMENT ''过期退款和自动核销任务按订单快照触发时间,旧售后任务为空'' AFTER `eligibility_deadline`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND COLUMN_NAME = 'trigger_time');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` ADD COLUMN `restore_inventory` char(1) DEFAULT NULL COMMENT ''任务退库存快照,0不恢复,1恢复'' AFTER `trigger_time`',
'SELECT 1')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND COLUMN_NAME = 'restore_inventory');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 幂等注释与空值语义修正(重复执行无副作用,兼为 20260822 未落库环境补齐)。
ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task`
MODIFY COLUMN `after_sale_id` bigint(20) DEFAULT NULL COMMENT '售后单ID,过期退款和自动核销任务为空',
MODIFY COLUMN `rule_type` varchar(32) DEFAULT NULL COMMENT '普通售后任务规则快照,过期预约任务为空',
MODIFY COLUMN `eligibility_deadline` datetime DEFAULT NULL COMMENT '普通售后免审资格截止时间,过期预约任务为空',
MODIFY COLUMN `task_type` char(10) NOT NULL DEFAULT '10'
COMMENT '任务场景,10用户免审售后,20过期预约退款,30过期未核销自动核销',
MODIFY COLUMN `status` char(10) NOT NULL
COMMENT '任务状态,10待执行,20等待重试,30开关关闭暂停,31配置不可用暂停,40重试耗尽,50成功,60订单已终态跳过';
-- scene_biz_id 生成列:缺失则新增(表达式含自动核销场景 30),已存在则 MODIFY 刷新表达式。
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` ADD COLUMN `scene_biz_id` bigint(20) GENERATED ALWAYS AS (CASE WHEN `task_type` IN (''20'', ''30'') THEN `order_id` ELSE `after_sale_id` END) STORED COMMENT ''任务场景业务唯一值,系统生成,禁止业务代码写入'' AFTER `restore_inventory`',
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` MODIFY COLUMN `scene_biz_id` bigint(20) GENERATED ALWAYS AS (CASE WHEN `task_type` IN (''20'', ''30'') THEN `order_id` ELSE `after_sale_id` END) STORED COMMENT ''任务场景业务唯一值,系统生成,禁止业务代码写入''')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND COLUMN_NAME = 'scene_biz_id');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 新建场景唯一键前应确认本查询返回 0 行;存在重复说明历史任务数据冲突,必须先人工核对,禁止自动清理。
SELECT tenant_id, task_type, del_flag,
CASE WHEN task_type = '20' THEN order_id ELSE after_sale_id END AS scene_biz_id,
COUNT(*) AS duplicate_count
FROM pjcloudx_hardware.hard_auto_refund_task
GROUP BY tenant_id, task_type, del_flag,
CASE WHEN task_type = '20' THEN order_id ELSE after_sale_id END
HAVING COUNT(*) > 1;
-- 旧售后单唯一键:存在才删除,给场景唯一键让位。
SET @ddl = (SELECT IF(COUNT(*) > 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` DROP INDEX `uk_hard_auto_refund_task_after_sale`',
'SELECT 1')
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND INDEX_NAME = 'uk_hard_auto_refund_task_after_sale');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 场景唯一键:缺失才创建(存在重复数据时本语句会失败,先处理上方诊断结果)。
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` ADD UNIQUE KEY `uk_hard_auto_refund_task_scene_biz` (`tenant_id`, `task_type`, `scene_biz_id`, `del_flag`)',
'SELECT 1')
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND INDEX_NAME = 'uk_hard_auto_refund_task_scene_biz');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 扫描索引:缺失才创建。
SET @ddl = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_task` ADD KEY `idx_hard_auto_refund_task_scan_type` (`tenant_id`, `task_type`, `status`, `next_retry_time`, `del_flag`)',
'SELECT 1')
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND INDEX_NAME = 'idx_hard_auto_refund_task_scan_type');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 四、尝试日志注释更新。幂等,任何状态都可执行。
ALTER TABLE `pjcloudx_hardware`.`hard_auto_refund_attempt_log`
MODIFY COLUMN `result_status` char(10) NOT NULL
COMMENT '尝试结果,10执行中,20成功,30失败,40因开关关闭跳过,50订单已终态跳过',
MODIFY COLUMN `after_sale_id` bigint(20) DEFAULT NULL
COMMENT '售后单ID,过期退款和自动核销任务为空';
-- 【验收】生成列表达式应包含 '20' 和 '30',且三张表的新列均已存在。
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, IFNULL(GENERATION_EXPRESSION, '') AS generation
FROM information_schema.COLUMNS
WHERE (TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_auto_refund_task' AND COLUMN_NAME = 'scene_biz_id')
OR (TABLE_SCHEMA = 'pjcloudx_wallet' AND TABLE_NAME = 'mch_auto_refund_config' AND COLUMN_NAME LIKE 'auto_verify_%')
OR (TABLE_SCHEMA = 'pjcloudx_hardware' AND TABLE_NAME = 'hard_order' AND COLUMN_NAME = 'verification_type');
SET @ddl = NULL;