-- +goose Up -- +goose StatementBegin -- ============================================ -- 金额统一重构:新增分字段(BIGINT) -- 目标:所有金额存储使用整数分,避免浮点精度问题 -- 展示:统一到角精度(0.1元) -- ============================================ -- 用户表:免押额度 ALTER TABLE users ADD COLUMN IF NOT EXISTS deposit_free_quota_cent BIGINT NOT NULL DEFAULT 0 COMMENT '免押总额度(分)' AFTER deposit_free_quota; -- 商品表:价格和押金 ALTER TABLE rental_listings ADD COLUMN IF NOT EXISTS price_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租金(分/小时)' AFTER price, ADD COLUMN IF NOT EXISTS deposit_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '押金金额(分)' AFTER deposit_amount; -- 订单表:租金、押金、平台费 ALTER TABLE rental_orders ADD COLUMN IF NOT EXISTS rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租金总额(分)' AFTER rent_amount, ADD COLUMN IF NOT EXISTS owner_rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '号主实得租金(分)' AFTER owner_rent_amount, ADD COLUMN IF NOT EXISTS deposit_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '实际收取押金(分)' AFTER deposit_amount, ADD COLUMN IF NOT EXISTS deposit_original_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '商品原始押金(分)' AFTER deposit_original_amount, ADD COLUMN IF NOT EXISTS deposit_waived_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '免押抵扣金额(分)' AFTER deposit_waived_amount, ADD COLUMN IF NOT EXISTS platform_fee_cent BIGINT NOT NULL DEFAULT 0 COMMENT '平台手续费(分)' AFTER platform_fee; -- 结算记录表:所有金额字段 ALTER TABLE order_checkouts ADD COLUMN IF NOT EXISTS rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租金(分)' AFTER rent_amount, ADD COLUMN IF NOT EXISTS owner_rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '号主实得租金(分)' AFTER owner_rent_amount, ADD COLUMN IF NOT EXISTS platform_fee_cent BIGINT NOT NULL DEFAULT 0 COMMENT '平台手续费(分)' AFTER platform_fee, ADD COLUMN IF NOT EXISTS deposit_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '押金(分)' AFTER deposit_amount, ADD COLUMN IF NOT EXISTS consumable_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '消耗品扣费(分)' AFTER consumable_amount, ADD COLUMN IF NOT EXISTS other_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '其他费用(分)' AFTER other_amount, ADD COLUMN IF NOT EXISTS deposit_deduct_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '押金扣除金额(分)' AFTER deposit_deduct_amount, ADD COLUMN IF NOT EXISTS renter_refund_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租客退款金额(分)' AFTER renter_refund_amount, ADD COLUMN IF NOT EXISTS owner_income_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '号主收入金额(分)' AFTER owner_income_amount; -- 钱包账户表:余额 ALTER TABLE wallet_accounts ADD COLUMN IF NOT EXISTS available_balance_cent BIGINT NOT NULL DEFAULT 0 COMMENT '可用余额(分)' AFTER available_balance, ADD COLUMN IF NOT EXISTS frozen_balance_cent BIGINT NOT NULL DEFAULT 0 COMMENT '冻结余额(分)' AFTER frozen_balance; -- 钱包流水表:金额和余额 ALTER TABLE wallet_ledger ADD COLUMN IF NOT EXISTS amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '金额(分)' AFTER amount, ADD COLUMN IF NOT EXISTS balance_after_cent BIGINT NOT NULL DEFAULT 0 COMMENT '变动后余额(分)' AFTER balance_after; -- 提现表是可选模块;仅在表存在时修改,避免缺表环境迁移失败。 SET @withdrawal_requests_exists := ( SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'withdrawal_requests' ); SET @sql := IF(@withdrawal_requests_exists > 0, 'ALTER TABLE withdrawal_requests ADD COLUMN IF NOT EXISTS amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT ''提现金额(分)'' AFTER amount, ADD COLUMN IF NOT EXISTS fee_cent BIGINT NOT NULL DEFAULT 0 COMMENT ''手续费(分)'' AFTER fee, ADD COLUMN IF NOT EXISTS actual_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT ''实际到账(分)'' AFTER actual_amount', 'SELECT 1' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- ============================================ -- 数据迁移:从 DECIMAL 复制到 BIGINT(分) -- 注意:ROUND(value * 100) 确保精度 -- ============================================ -- 用户免押额度 UPDATE users SET deposit_free_quota_cent = ROUND(deposit_free_quota * 100) WHERE deposit_free_quota > 0; -- 商品价格和押金 UPDATE rental_listings SET price_cent = ROUND(price * 100), deposit_amount_cent = ROUND(deposit_amount * 100) WHERE price > 0 OR deposit_amount > 0; -- 订单金额 UPDATE rental_orders SET rent_amount_cent = ROUND(rent_amount * 100), owner_rent_amount_cent = ROUND(owner_rent_amount * 100), deposit_amount_cent = ROUND(deposit_amount * 100), deposit_original_amount_cent = ROUND(deposit_original_amount * 100), deposit_waived_amount_cent = ROUND(deposit_waived_amount * 100), platform_fee_cent = ROUND(platform_fee * 100) WHERE rent_amount > 0 OR owner_rent_amount > 0 OR deposit_amount > 0 OR deposit_original_amount > 0 OR deposit_waived_amount > 0 OR platform_fee > 0; -- 结算记录 UPDATE order_checkouts SET rent_amount_cent = ROUND(rent_amount * 100), owner_rent_amount_cent = ROUND(owner_rent_amount * 100), platform_fee_cent = ROUND(platform_fee * 100), deposit_amount_cent = ROUND(deposit_amount * 100), consumable_amount_cent = ROUND(consumable_amount * 100), other_amount_cent = ROUND(other_amount * 100), deposit_deduct_amount_cent = ROUND(deposit_deduct_amount * 100), renter_refund_amount_cent = ROUND(renter_refund_amount * 100), owner_income_amount_cent = ROUND(owner_income_amount * 100) WHERE rent_amount > 0 OR owner_rent_amount > 0 OR platform_fee > 0 OR deposit_amount > 0 OR consumable_amount > 0 OR other_amount > 0 OR deposit_deduct_amount > 0 OR renter_refund_amount > 0 OR owner_income_amount > 0; -- 钱包余额 UPDATE wallet_accounts SET available_balance_cent = ROUND(available_balance * 100), frozen_balance_cent = ROUND(frozen_balance * 100) WHERE available_balance > 0 OR frozen_balance > 0; -- 钱包流水 UPDATE wallet_ledger SET amount_cent = ROUND(amount * 100), balance_after_cent = ROUND(balance_after * 100) WHERE amount != 0 OR balance_after != 0; -- 提现记录 SET @sql := IF(@withdrawal_requests_exists > 0, 'UPDATE withdrawal_requests SET amount_cent = ROUND(amount * 100), fee_cent = ROUND(fee * 100), actual_amount_cent = ROUND(actual_amount * 100) WHERE amount > 0 OR fee > 0 OR actual_amount > 0', 'SELECT 1' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- +goose StatementEnd -- +goose Down -- +goose StatementBegin -- ============================================ -- 回滚:删除所有新增的分字段 -- ============================================ ALTER TABLE users DROP COLUMN IF EXISTS deposit_free_quota_cent; ALTER TABLE rental_listings DROP COLUMN IF EXISTS price_cent, DROP COLUMN IF EXISTS deposit_amount_cent; ALTER TABLE rental_orders DROP COLUMN IF EXISTS rent_amount_cent, DROP COLUMN IF EXISTS owner_rent_amount_cent, DROP COLUMN IF EXISTS deposit_amount_cent, DROP COLUMN IF EXISTS deposit_original_amount_cent, DROP COLUMN IF EXISTS deposit_waived_amount_cent, DROP COLUMN IF EXISTS platform_fee_cent; ALTER TABLE order_checkouts DROP COLUMN IF EXISTS rent_amount_cent, DROP COLUMN IF EXISTS owner_rent_amount_cent, DROP COLUMN IF EXISTS platform_fee_cent, DROP COLUMN IF EXISTS deposit_amount_cent, DROP COLUMN IF EXISTS consumable_amount_cent, DROP COLUMN IF EXISTS other_amount_cent, DROP COLUMN IF EXISTS deposit_deduct_amount_cent, DROP COLUMN IF EXISTS renter_refund_amount_cent, DROP COLUMN IF EXISTS owner_income_amount_cent; ALTER TABLE wallet_accounts DROP COLUMN IF EXISTS available_balance_cent, DROP COLUMN IF EXISTS frozen_balance_cent; ALTER TABLE wallet_ledger DROP COLUMN IF EXISTS amount_cent, DROP COLUMN IF EXISTS balance_after_cent; SET @withdrawal_requests_exists := ( SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'withdrawal_requests' ); SET @sql := IF(@withdrawal_requests_exists > 0, 'ALTER TABLE withdrawal_requests DROP COLUMN IF EXISTS amount_cent, DROP COLUMN IF EXISTS fee_cent, DROP COLUMN IF EXISTS actual_amount_cent', 'SELECT 1' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- +goose StatementEnd