统一金额分制重构

This commit is contained in:
yml
2026-06-09 19:04:11 +08:00
parent 87673288ef
commit 5cd3ead4bd
69 changed files with 886 additions and 1277 deletions
+1 -26
View File
@@ -22,7 +22,6 @@ CREATE TABLE IF NOT EXISTS users (
realname_status VARCHAR(32) NOT NULL DEFAULT 'unverified' COMMENT '实名状态: unverified未实名, pending审核中, verified已实名, failed失败',
risk_status VARCHAR(32) NOT NULL DEFAULT 'normal' COMMENT '风控状态: normal正常, warning警告, frozen冻结',
credit_score INT NOT NULL DEFAULT 100 COMMENT '信用分',
deposit_free_quota DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '免押总额度',
deposit_free_quota_cent BIGINT NOT NULL DEFAULT 0 COMMENT '免押总额度(分)',
status VARCHAR(32) NOT NULL DEFAULT 'active' COMMENT '账号状态: active活跃, inactive停用, banned封禁',
last_login_at DATETIME NULL COMMENT '最后登录时间',
@@ -82,9 +81,7 @@ CREATE TABLE IF NOT EXISTS rental_listings (
listing_no VARCHAR(20) NOT NULL COMMENT '商品编号,格式yyyyMMddNNNN',
account_id BIGINT UNSIGNED NOT NULL COMMENT '关联的游戏账号ID',
owner_id BIGINT UNSIGNED NOT NULL COMMENT '号主ID',
price DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '租金(元/小时)',
price_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租金(分/小时)',
deposit_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '押金金额',
deposit_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '押金金额(分)',
in_transaction TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否正在交易中: 0否, 1是',
status VARCHAR(32) NOT NULL DEFAULT 'draft' COMMENT '商品状态: draft草稿, active上架, offline下架, deleted删除',
@@ -96,7 +93,7 @@ CREATE TABLE IF NOT EXISTS rental_listings (
UNIQUE KEY uk_rental_listings_listing_no (listing_no),
KEY idx_rental_listings_account_id (account_id),
KEY idx_rental_listings_owner_id (owner_id),
KEY idx_rental_listings_filter (status, review_status, in_transaction, price),
KEY idx_rental_listings_filter (status, review_status, in_transaction, price_cent),
KEY idx_rental_listings_published (status, review_status, published_at DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='租号商品列表';
@@ -122,17 +119,11 @@ CREATE TABLE IF NOT EXISTS rental_orders (
renter_id BIGINT UNSIGNED NOT NULL COMMENT '租客ID',
rented_at DATETIME NULL COMMENT '租用开始时间',
estimated_duration_hours INT NOT NULL DEFAULT 24 COMMENT '预计租用时长(小时)',
rent_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '租金总额',
rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租金总额(分)',
owner_rent_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '号主实得租金',
owner_rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '号主实得租金(分)',
deposit_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '实际收取押金金额',
deposit_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '实际收取押金(分)',
deposit_original_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '商品原始押金金额',
deposit_original_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '商品原始押金(分)',
deposit_waived_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '本单免押抵扣金额',
deposit_waived_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '免押抵扣金额(分)',
platform_fee DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '平台手续费',
platform_fee_cent BIGINT NOT NULL DEFAULT 0 COMMENT '平台手续费(分)',
account_snapshot JSON NULL COMMENT '账号快照(下单时的账号状态)',
status VARCHAR(32) NOT NULL DEFAULT 'pending_payment' COMMENT '订单状态: pending_payment待支付, active进行中, completed已完成, cancelled已取消, closed已关闭',
@@ -161,24 +152,15 @@ CREATE TABLE IF NOT EXISTS order_checkouts (
order_id BIGINT UNSIGNED NOT NULL COMMENT '订单ID',
initiated_by BIGINT UNSIGNED NOT NULL COMMENT '发起者ID',
status VARCHAR(32) NOT NULL DEFAULT 'submitted' COMMENT '结算状态: submitted已提交, renter_confirmed租客确认, renter_rejected租客拒绝, completed完成',
rent_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '租金',
rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租金(分)',
owner_rent_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '号主实得租金',
owner_rent_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '号主实得租金(分)',
platform_fee DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '平台手续费',
platform_fee_cent BIGINT NOT NULL DEFAULT 0 COMMENT '平台手续费(分)',
deposit_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '押金',
deposit_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '押金(分)',
consumable_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '消耗品扣费',
consumable_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '消耗品扣费(分)',
coin_consumed_m DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '游戏币消耗(百万为单位)',
other_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '其他费用',
other_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '其他费用(分)',
deposit_deduct_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '押金扣除金额',
deposit_deduct_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '押金扣除金额(分)',
renter_refund_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '租客退款金额',
renter_refund_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '租客退款金额(分)',
owner_income_amount DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '号主收入金额',
owner_income_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '号主收入金额(分)',
content TEXT NULL COMMENT '结算说明',
evidence_urls JSON NULL COMMENT '证据截图URL列表',
@@ -215,9 +197,7 @@ CREATE TABLE IF NOT EXISTS handoff_records (
CREATE TABLE IF NOT EXISTS wallet_accounts (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
available_balance DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '可用余额',
available_balance_cent BIGINT NOT NULL DEFAULT 0 COMMENT '可用余额(分)',
frozen_balance DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '冻结余额',
frozen_balance_cent BIGINT NOT NULL DEFAULT 0 COMMENT '冻结余额(分)',
status VARCHAR(32) NOT NULL DEFAULT 'active' COMMENT '钱包状态: active正常, frozen冻结, closed关闭',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -232,9 +212,7 @@ CREATE TABLE IF NOT EXISTS wallet_ledger (
user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
order_id BIGINT UNSIGNED NULL COMMENT '关联订单ID',
direction VARCHAR(16) NOT NULL COMMENT '方向: in收入, out支出',
amount DECIMAL(12,2) NOT NULL COMMENT '金额',
amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '金额(分)',
balance_after DECIMAL(12,2) NOT NULL COMMENT '变动后余额',
balance_after_cent BIGINT NOT NULL DEFAULT 0 COMMENT '变动后余额(分)',
balance_type VARCHAR(32) NOT NULL COMMENT '余额类型: available可用, frozen冻结',
biz_type VARCHAR(32) NOT NULL COMMENT '业务类型: rent_payment租金支付, deposit_freeze押金冻结, settlement结算, refund退款等',
@@ -839,11 +817,8 @@ CREATE TABLE IF NOT EXISTS withdrawal_requests (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
withdraw_no VARCHAR(64) NOT NULL COMMENT '提现单号',
user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
amount DECIMAL(12,2) NOT NULL COMMENT '提现金额',
amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '提现金额(分)',
fee DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '手续费',
fee_cent BIGINT NOT NULL DEFAULT 0 COMMENT '手续费(分)',
actual_amount DECIMAL(12,2) NOT NULL COMMENT '实际到账金额',
actual_amount_cent BIGINT NOT NULL DEFAULT 0 COMMENT '实际到账(分)',
-- 收款账号信息(快照)
@@ -1,190 +0,0 @@
-- +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