Files
junhong_cmp_fiber/migrations/000171_add_agent_main_wallet_credit.up.sql
2026-07-24 16:07:18 +08:00

113 lines
5.3 KiB
PL/PgSQL
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.
BEGIN;
LOCK TABLE tb_agent_wallet IN ACCESS EXCLUSIVE MODE;
ALTER TABLE tb_agent_wallet
ADD COLUMN IF NOT EXISTS credit_enabled boolean NOT NULL DEFAULT false,
ADD COLUMN IF NOT EXISTS credit_limit bigint NOT NULL DEFAULT 0;
COMMENT ON COLUMN tb_agent_wallet.credit_enabled IS '是否启用代理主钱包信用额度;分佣钱包固定关闭';
COMMENT ON COLUMN tb_agent_wallet.credit_limit IS '代理主钱包信用额度单位为分关闭信用时固定为0';
-- 迁移在目标库读取真实约束定义,不依赖归档迁移中的约束名称。
DO $$
DECLARE
balance_attnum smallint;
constraint_row record;
normalized_definition text;
BEGIN
SELECT attnum
INTO balance_attnum
FROM pg_attribute
WHERE attrelid = 'tb_agent_wallet'::regclass
AND attname = 'balance'
AND NOT attisdropped;
FOR constraint_row IN
SELECT conname, conkey, pg_get_constraintdef(oid) AS definition
FROM pg_constraint
WHERE conrelid = 'tb_agent_wallet'::regclass
AND contype = 'c'
LOOP
normalized_definition := regexp_replace(lower(constraint_row.definition), '[[:space:]()]', '', 'g');
IF (array_length(constraint_row.conkey, 1) = 1
AND constraint_row.conkey[1] = balance_attnum
AND normalized_definition LIKE 'check%balance%>=%0%')
OR normalized_definition LIKE '%frozen_balance%<=%balance%' THEN
RAISE NOTICE '移除代理钱包历史约束 %%', constraint_row.conname, constraint_row.definition;
EXECUTE format('ALTER TABLE tb_agent_wallet DROP CONSTRAINT %I', constraint_row.conname);
END IF;
END LOOP;
END
$$;
ALTER TABLE tb_agent_wallet
DROP CONSTRAINT IF EXISTS chk_agent_wallet_credit_config,
DROP CONSTRAINT IF EXISTS chk_agent_wallet_credit_scope,
DROP CONSTRAINT IF EXISTS chk_agent_wallet_frozen_nonnegative,
DROP CONSTRAINT IF EXISTS chk_agent_wallet_arithmetic_range,
DROP CONSTRAINT IF EXISTS chk_agent_wallet_available_balance,
DROP CONSTRAINT IF EXISTS chk_agent_wallet_version_nonnegative;
-- 历史钱包默认关闭信用;任何既有异常都必须先形成清单并修复,禁止迁移静默改账。
DO $$
DECLARE
abnormal_count bigint;
BEGIN
SELECT COUNT(*)
INTO abnormal_count
FROM tb_agent_wallet
WHERE wallet_type NOT IN ('main', 'commission')
OR frozen_balance < 0
OR version < 0
OR credit_enabled
OR credit_limit <> 0
OR (wallet_type = 'main' AND balance::numeric - frozen_balance::numeric < 0)
OR (wallet_type = 'commission' AND (balance < 0 OR frozen_balance > balance));
IF abnormal_count > 0 THEN
RAISE EXCEPTION '代理钱包信用迁移发现 % 条异常数据请先导出钱包ID、约束定义并修复后重试', abnormal_count;
END IF;
END
$$;
ALTER TABLE tb_agent_wallet
ADD CONSTRAINT chk_agent_wallet_credit_config CHECK (
(credit_enabled = false AND credit_limit = 0) OR
(credit_enabled = true AND credit_limit > 0)
),
ADD CONSTRAINT chk_agent_wallet_credit_scope CHECK (
wallet_type = 'main' OR (credit_enabled = false AND credit_limit = 0)
),
ADD CONSTRAINT chk_agent_wallet_frozen_nonnegative CHECK (frozen_balance >= 0),
ADD CONSTRAINT chk_agent_wallet_arithmetic_range CHECK (
wallet_type <> 'main' OR (
balance > -9223372036854775808::numeric AND
balance::numeric - frozen_balance::numeric BETWEEN -9223372036854775808::numeric AND 9223372036854775807::numeric AND
balance::numeric - frozen_balance::numeric +
CASE WHEN credit_enabled THEN credit_limit::numeric ELSE 0::numeric END
BETWEEN -9223372036854775808::numeric AND 9223372036854775807::numeric
)
),
ADD CONSTRAINT chk_agent_wallet_available_balance CHECK (
(wallet_type = 'main' AND
balance::numeric - frozen_balance::numeric +
CASE WHEN credit_enabled THEN credit_limit::numeric ELSE 0::numeric END >= 0) OR
(wallet_type = 'commission' AND balance >= 0 AND frozen_balance <= balance)
),
ADD CONSTRAINT chk_agent_wallet_version_nonnegative CHECK (version >= 0);
CREATE INDEX IF NOT EXISTS idx_agent_wallet_main_credit_enabled
ON tb_agent_wallet (shop_id)
WHERE wallet_type = 'main' AND credit_enabled = true AND deleted_at IS NULL;
COMMENT ON CONSTRAINT chk_agent_wallet_credit_config ON tb_agent_wallet IS '保证信用开关与额度组合一致';
COMMENT ON CONSTRAINT chk_agent_wallet_credit_scope ON tb_agent_wallet IS '保证只有代理主钱包可以启用信用额度';
COMMENT ON CONSTRAINT chk_agent_wallet_frozen_nonnegative ON tb_agent_wallet IS '保证冻结金额不为负数';
COMMENT ON CONSTRAINT chk_agent_wallet_arithmetic_range ON tb_agent_wallet IS '保证现金可用、总可用和欠款金额均可在int64范围内安全计算';
COMMENT ON CONSTRAINT chk_agent_wallet_available_balance ON tb_agent_wallet IS '保证主钱包总可用金额和分佣钱包现金可用金额不为负数';
COMMENT ON CONSTRAINT chk_agent_wallet_version_nonnegative ON tb_agent_wallet IS '保证钱包乐观锁版本不为负数';
COMMENT ON INDEX idx_agent_wallet_main_credit_enabled IS '启用信用额度的有效代理主钱包索引';
COMMIT;