积分与余额账务系统硬切重构
This commit is contained in:
@@ -20,43 +20,55 @@ trait DBMigratorPart2 {
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
$prefix = $wpdb->prefix;
|
||||
|
||||
// ---------- 1. 积分流水 ----------
|
||||
$sql_credit_log = "CREATE TABLE {$prefix}aksrt_credit_log (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
// ---------- 1. 统一资产账户与不可变账本 ----------
|
||||
$sql_asset_account = "CREATE TABLE {$prefix}aksrt_asset_account (
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
delta INT NOT NULL,
|
||||
balance_after INT NOT NULL,
|
||||
reason VARCHAR(64) NOT NULL,
|
||||
remark VARCHAR(255) DEFAULT NULL,
|
||||
ref_type VARCHAR(32) DEFAULT NULL,
|
||||
ref_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
ip VARCHAR(64) DEFAULT NULL,
|
||||
ua VARCHAR(255) DEFAULT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user_time (user_id, created_at),
|
||||
KEY idx_reason (reason)
|
||||
) {$charset_collate};";
|
||||
dbDelta($sql_credit_log);
|
||||
asset VARCHAR(16) NOT NULL,
|
||||
balance_minor BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
version BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
updated_at DATETIME(6) NOT NULL,
|
||||
PRIMARY KEY (user_id, asset),
|
||||
KEY idx_asset_balance (asset, balance_minor)
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_asset_account);
|
||||
|
||||
// ---------- 1b. 现金余额流水(站内钱包,与积分分离) ----------
|
||||
$sql_balance_log = "CREATE TABLE {$prefix}aksrt_balance_log (
|
||||
$sql_asset_transaction = "CREATE TABLE {$prefix}aksrt_asset_transaction (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
delta DECIMAL(18,2) NOT NULL,
|
||||
balance_after DECIMAL(18,2) NOT NULL,
|
||||
operation_key VARCHAR(191) NOT NULL,
|
||||
payload_hash CHAR(64) NOT NULL,
|
||||
reason VARCHAR(64) NOT NULL,
|
||||
remark VARCHAR(255) DEFAULT NULL,
|
||||
ref_type VARCHAR(32) DEFAULT NULL,
|
||||
ref_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
ref_key VARCHAR(191) DEFAULT NULL,
|
||||
actor_user_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
metadata LONGTEXT DEFAULT NULL,
|
||||
ip VARCHAR(64) DEFAULT NULL,
|
||||
ua VARCHAR(255) DEFAULT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
created_at DATETIME(6) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user_time (user_id, created_at),
|
||||
KEY idx_reason (reason)
|
||||
) {$charset_collate};";
|
||||
dbDelta($sql_balance_log);
|
||||
UNIQUE KEY uniq_operation_key (operation_key),
|
||||
KEY idx_reason_time (reason, created_at),
|
||||
KEY idx_reference (ref_type, ref_key)
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_asset_transaction);
|
||||
|
||||
$sql_asset_entry = "CREATE TABLE {$prefix}aksrt_asset_entry (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
transaction_id BIGINT UNSIGNED NOT NULL,
|
||||
line_no SMALLINT UNSIGNED NOT NULL,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
asset VARCHAR(16) NOT NULL,
|
||||
entry_type VARCHAR(32) NOT NULL,
|
||||
delta_minor BIGINT NOT NULL,
|
||||
balance_after_minor BIGINT UNSIGNED NOT NULL,
|
||||
counterparty_user_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
remark VARCHAR(255) DEFAULT NULL,
|
||||
created_at DATETIME(6) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uniq_transaction_line (transaction_id, line_no),
|
||||
KEY idx_user_asset_time (user_id, asset, created_at, id),
|
||||
KEY idx_transaction (transaction_id)
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_asset_entry);
|
||||
|
||||
// ---------- 2. 签到 ----------
|
||||
$sql_signin = "CREATE TABLE {$prefix}aksrt_signin_log (
|
||||
@@ -68,7 +80,7 @@ trait DBMigratorPart2 {
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uniq_user_date (user_id, signin_date),
|
||||
KEY idx_user (user_id)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_signin);
|
||||
|
||||
// ---------- 3. 下载 token ----------
|
||||
@@ -88,7 +100,7 @@ trait DBMigratorPart2 {
|
||||
KEY idx_expires (expires_at),
|
||||
KEY idx_user (user_id),
|
||||
KEY idx_post (post_id)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_dl_token);
|
||||
|
||||
// ---------- 5. 用户通知收件箱 ----------
|
||||
@@ -105,13 +117,14 @@ trait DBMigratorPart2 {
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user_created (user_id, created_at),
|
||||
KEY idx_user_read (user_id, is_read)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_notification);
|
||||
|
||||
// ---------- 8. 订单表 ----------
|
||||
$sql_order = "CREATE TABLE {$prefix}aksrt_order (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
order_number VARCHAR(32) NOT NULL,
|
||||
request_key VARCHAR(191) DEFAULT NULL,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
product_type VARCHAR(32) NOT NULL DEFAULT '',
|
||||
product_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
@@ -131,12 +144,13 @@ trait DBMigratorPart2 {
|
||||
note TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uniq_order_number (order_number),
|
||||
UNIQUE KEY uniq_request_key (request_key),
|
||||
KEY idx_user (user_id),
|
||||
KEY idx_user_status_created (user_id, status, created_at),
|
||||
KEY idx_status (status),
|
||||
KEY idx_created (created_at),
|
||||
KEY idx_product (product_type, product_id)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_order);
|
||||
|
||||
// ---------- 9. 作者收益台账 ----------
|
||||
@@ -168,7 +182,7 @@ trait DBMigratorPart2 {
|
||||
KEY idx_currency (currency),
|
||||
KEY idx_status (status),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_revenue);
|
||||
|
||||
// ---------- 10. 提现台账 ----------
|
||||
@@ -180,15 +194,17 @@ trait DBMigratorPart2 {
|
||||
method VARCHAR(32) NOT NULL DEFAULT '',
|
||||
account_info TEXT DEFAULT NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
ledger_transaction_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
processed_at DATETIME DEFAULT NULL,
|
||||
note TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uniq_ledger_transaction (ledger_transaction_id),
|
||||
KEY idx_user (user_id),
|
||||
KEY idx_user_created (user_id, created_at),
|
||||
KEY idx_status (status),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_withdrawal);
|
||||
|
||||
// ---------- 11. 举报工单 ----------
|
||||
@@ -208,7 +224,7 @@ trait DBMigratorPart2 {
|
||||
KEY idx_target (target_type, target_id),
|
||||
KEY idx_reporter (reporter_id),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_report);
|
||||
|
||||
// ---------- 12. 用户限制/封禁 ----------
|
||||
@@ -227,7 +243,7 @@ trait DBMigratorPart2 {
|
||||
KEY idx_scope (scope),
|
||||
KEY idx_expires (expires_at),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_restriction);
|
||||
|
||||
// ── follow ──
|
||||
@@ -240,7 +256,7 @@ trait DBMigratorPart2 {
|
||||
UNIQUE KEY idx_pair (follower_id, following_id),
|
||||
KEY idx_following (following_id),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_follow);
|
||||
|
||||
// ── coupon ──
|
||||
@@ -262,7 +278,7 @@ trait DBMigratorPart2 {
|
||||
UNIQUE KEY idx_code (code),
|
||||
KEY idx_status (status),
|
||||
KEY idx_expires (expires_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_coupon);
|
||||
|
||||
// ── coupon_usage (R68) ──
|
||||
@@ -276,11 +292,11 @@ trait DBMigratorPart2 {
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_coupon (coupon_id),
|
||||
KEY idx_user (user_id),
|
||||
KEY idx_order (order_number)
|
||||
) {$charset_collate};";
|
||||
UNIQUE KEY uniq_coupon_usage_order (order_number)
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_coupon_usage);
|
||||
|
||||
// ── charge_card (legacy-style typed card_pass) ──
|
||||
// ── typed charge cards ──
|
||||
$sql_charge_card = "CREATE TABLE {$prefix}aksrt_charge_card (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
card VARCHAR(60) NOT NULL DEFAULT '',
|
||||
@@ -304,31 +320,9 @@ trait DBMigratorPart2 {
|
||||
KEY idx_used_by (used_by),
|
||||
KEY idx_order_number (order_number),
|
||||
KEY idx_expires (expires_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_charge_card);
|
||||
|
||||
// ── rebate_log ──
|
||||
$sql_rebate_log = "CREATE TABLE {$prefix}aksrt_rebate_log (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
user_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
order_number VARCHAR(32) NOT NULL DEFAULT '',
|
||||
source_user_id BIGINT UNSIGNED DEFAULT NULL,
|
||||
amount DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||||
type VARCHAR(32) NOT NULL DEFAULT 'order',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
settled_at DATETIME DEFAULT NULL,
|
||||
note TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user (user_id),
|
||||
KEY idx_order (order_number),
|
||||
KEY idx_source (source_user_id),
|
||||
KEY idx_status (status),
|
||||
KEY idx_type (type),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
dbDelta($sql_rebate_log);
|
||||
|
||||
// ── canonical Ref attribution and permanent user binding ──
|
||||
$sql_affiliate_relation = "CREATE TABLE {$prefix}aksrt_affiliate_relation (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
@@ -349,7 +343,7 @@ trait DBMigratorPart2 {
|
||||
KEY idx_status_touch (status, first_touch_at),
|
||||
KEY idx_reward_status (reward_status),
|
||||
KEY idx_reward_ip (registration_ip, rewarded_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_affiliate_relation);
|
||||
|
||||
// ── immutable commission ledger ──
|
||||
@@ -365,17 +359,20 @@ trait DBMigratorPart2 {
|
||||
adjustment_total DECIMAL(18,2) NOT NULL DEFAULT 0,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
idempotency_key VARCHAR(128) NOT NULL,
|
||||
cancel_operation_key VARCHAR(191) DEFAULT NULL,
|
||||
cancel_payload_hash CHAR(64) DEFAULT NULL,
|
||||
available_at DATETIME NOT NULL,
|
||||
settled_at DATETIME DEFAULT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
note TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uniq_commission_idempotency (idempotency_key),
|
||||
UNIQUE KEY uniq_commission_cancel_operation (cancel_operation_key),
|
||||
KEY idx_promoter_status (promoter_id, status),
|
||||
KEY idx_order_type (order_number, order_type),
|
||||
KEY idx_available (status, available_at),
|
||||
KEY idx_created (created_at)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_commission_ledger);
|
||||
|
||||
// ── immutable commission adjustments (refund/debt/manual) ──
|
||||
@@ -393,7 +390,7 @@ trait DBMigratorPart2 {
|
||||
UNIQUE KEY uniq_adjustment_source (source_key),
|
||||
KEY idx_ledger (ledger_id),
|
||||
KEY idx_promoter (promoter_id)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_commission_adjustment);
|
||||
|
||||
// ── payout account snapshots ──
|
||||
@@ -409,7 +406,7 @@ trait DBMigratorPart2 {
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uniq_user_channel (user_id, channel),
|
||||
KEY idx_user_status (user_id, status)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_payout_account);
|
||||
|
||||
// ── order_items (§6.5 多商品多商家) ──
|
||||
@@ -434,7 +431,7 @@ trait DBMigratorPart2 {
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_order (order_number),
|
||||
KEY idx_product (product_id)
|
||||
) {$charset_collate};";
|
||||
) ENGINE=InnoDB {$charset_collate};";
|
||||
dbDelta($sql_order_items);
|
||||
|
||||
self::migrate_identity_tables($prefix, $charset_collate);
|
||||
|
||||
Reference in New Issue
Block a user