get_charset_collate(); $prefix = $wpdb->prefix; // ---------- 1. 统一资产账户与不可变账本 ---------- $sql_asset_account = "CREATE TABLE {$prefix}aksrt_asset_account ( user_id BIGINT UNSIGNED NOT NULL, 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); $sql_asset_transaction = "CREATE TABLE {$prefix}aksrt_asset_transaction ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, operation_key VARCHAR(191) NOT NULL, payload_hash CHAR(64) NOT NULL, reason VARCHAR(64) NOT NULL, ref_type VARCHAR(32) 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(6) NOT NULL, PRIMARY KEY (id), 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); $sql_financial_flow = "CREATE TABLE {$prefix}aksrt_financial_flow ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, flow_number VARCHAR(32) NOT NULL, operation_key VARCHAR(191) NOT NULL, event_type VARCHAR(64) NOT NULL, ref_type VARCHAR(32) DEFAULT NULL, ref_key VARCHAR(191) DEFAULT NULL, order_number VARCHAR(32) DEFAULT NULL, withdrawal_number VARCHAR(32) DEFAULT NULL, ledger_transaction_id BIGINT UNSIGNED DEFAULT NULL, provider_transaction_id VARCHAR(128) DEFAULT NULL, metadata LONGTEXT DEFAULT NULL, created_at DATETIME(6) NOT NULL, PRIMARY KEY (id), UNIQUE KEY uniq_flow_number (flow_number), UNIQUE KEY uniq_flow_operation (operation_key), UNIQUE KEY uniq_flow_ledger_transaction (ledger_transaction_id), KEY idx_flow_event_time (event_type, created_at), KEY idx_flow_order (order_number), KEY idx_flow_withdrawal (withdrawal_number), KEY idx_flow_reference (ref_type, ref_key), KEY idx_flow_provider_transaction (provider_transaction_id) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_financial_flow); $sql_financial_flow_entry = "CREATE TABLE {$prefix}aksrt_financial_flow_entry ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, flow_id BIGINT UNSIGNED NOT NULL, line_no SMALLINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL DEFAULT 0, asset VARCHAR(16) NOT NULL, direction VARCHAR(8) NOT NULL, entry_type VARCHAR(32) NOT NULL, delta_minor BIGINT NOT NULL, balance_after_minor BIGINT UNSIGNED DEFAULT NULL, counterparty_user_id BIGINT UNSIGNED DEFAULT NULL, remark VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uniq_flow_line (flow_id, line_no), KEY idx_flow_entry_user (user_id, flow_id), KEY idx_flow_entry_asset (asset, flow_id), KEY idx_flow_entry_direction (direction, flow_id), KEY idx_flow_entry_counterparty (counterparty_user_id, flow_id) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_financial_flow_entry); // ---------- 2. 签到 ---------- $sql_signin = "CREATE TABLE {$prefix}aksrt_signin_log ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, signin_date DATE NOT NULL, streak INT NOT NULL DEFAULT 1, reward INT NOT NULL DEFAULT 0, PRIMARY KEY (id), UNIQUE KEY uniq_user_date (user_id, signin_date), KEY idx_user (user_id) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_signin); // ---------- 3. 下载 token ---------- $sql_dl_token = "CREATE TABLE {$prefix}aksrt_dl_token ( token CHAR(48) NOT NULL, user_id BIGINT UNSIGNED NOT NULL, post_id BIGINT UNSIGNED NOT NULL, source_index INT NOT NULL DEFAULT 0, cost INT NOT NULL DEFAULT 0, ip_bind VARCHAR(64) DEFAULT NULL, ua_hash CHAR(40) DEFAULT NULL, used_count INT NOT NULL DEFAULT 0, max_uses INT NOT NULL DEFAULT 1, expires_at DATETIME NOT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (token), KEY idx_expires (expires_at), KEY idx_user (user_id), KEY idx_post (post_id) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_dl_token); // ---------- 5. 用户通知收件箱 ---------- $sql_notification = "CREATE TABLE {$prefix}aksrt_notification ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, type VARCHAR(32) NOT NULL, title VARCHAR(191) NOT NULL, description TEXT DEFAULT NULL, target_url TEXT DEFAULT NULL, is_read TINYINT(1) NOT NULL DEFAULT 0, created_at DATETIME NOT NULL, read_at DATETIME DEFAULT NULL, PRIMARY KEY (id), KEY idx_user_created (user_id, created_at), KEY idx_user_read (user_id, is_read) ) 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, amount DECIMAL(10,2) NOT NULL DEFAULT 0, currency VARCHAR(8) NOT NULL DEFAULT 'CNY', status VARCHAR(20) NOT NULL DEFAULT 'pending', shipping_status TINYINT NOT NULL DEFAULT 0, payment_method VARCHAR(32) NOT NULL DEFAULT '', payment_transaction_id VARCHAR(128) NOT NULL DEFAULT '', created_at DATETIME NOT NULL, paid_at DATETIME DEFAULT NULL, delivered_at DATETIME DEFAULT NULL, completed_at DATETIME DEFAULT NULL, cancelled_at DATETIME DEFAULT NULL, refunded_at DATETIME DEFAULT NULL, expires_at DATETIME DEFAULT NULL, 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) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_order); // ---------- 9. 作者收益台账 ---------- $sql_revenue = "CREATE TABLE {$prefix}aksrt_revenue ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, author_id BIGINT UNSIGNED NOT NULL DEFAULT 0, order_number VARCHAR(32) NOT NULL DEFAULT '', post_id BIGINT UNSIGNED NOT NULL DEFAULT 0, buyer_id BIGINT UNSIGNED NOT NULL DEFAULT 0, currency VARCHAR(8) NOT NULL DEFAULT 'CNY', original_amount DECIMAL(18,2) NOT NULL DEFAULT 0, share_ratio DECIMAL(5,2) NOT NULL DEFAULT 0, author_level TINYINT UNSIGNED NOT NULL DEFAULT 0, amount DECIMAL(18,2) NOT NULL DEFAULT 0, type VARCHAR(32) NOT NULL DEFAULT 'order', status VARCHAR(20) NOT NULL DEFAULT 'pending', reversal_amount DECIMAL(18,2) NOT NULL DEFAULT 0, error_message TEXT DEFAULT NULL, audit_json LONGTEXT DEFAULT NULL, created_at DATETIME NOT NULL, settled_at DATETIME DEFAULT NULL, reversed_at DATETIME DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uniq_creator_order (author_id, order_number), KEY idx_author (author_id), KEY idx_order (order_number), KEY idx_post (post_id), KEY idx_buyer (buyer_id), KEY idx_currency (currency), KEY idx_status (status), KEY idx_created (created_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_revenue); // ---------- 10. 提现台账 ---------- $sql_withdrawal = "CREATE TABLE {$prefix}aksrt_withdrawal ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, withdrawal_number VARCHAR(32) NOT NULL, user_id BIGINT UNSIGNED NOT NULL, amount DECIMAL(10,2) NOT NULL DEFAULT 0, gross_amount DECIMAL(10,2) NOT NULL DEFAULT 0, 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_withdrawal_number (withdrawal_number), 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) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_withdrawal); // ---------- 11. 举报工单 ---------- $sql_report = "CREATE TABLE {$prefix}aksrt_report ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, reporter_id BIGINT UNSIGNED NOT NULL, target_type VARCHAR(20) NOT NULL, target_id BIGINT UNSIGNED NOT NULL, reason TEXT NOT NULL, category VARCHAR(40) NOT NULL DEFAULT '', status VARCHAR(20) NOT NULL DEFAULT 'pending', created_at DATETIME NOT NULL, updated_at DATETIME DEFAULT NULL, notes_json TEXT DEFAULT NULL, PRIMARY KEY (id), KEY idx_status (status), KEY idx_target (target_type, target_id), KEY idx_reporter (reporter_id), KEY idx_created (created_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_report); // ---------- 12. 用户限制/封禁 ---------- $sql_restriction = "CREATE TABLE {$prefix}aksrt_user_restriction ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, type VARCHAR(20) NOT NULL DEFAULT 'warn', reason TEXT NOT NULL, scope VARCHAR(20) NOT NULL DEFAULT 'global', expires_at DATETIME DEFAULT NULL, created_by BIGINT UNSIGNED NOT NULL DEFAULT 0, created_at DATETIME NOT NULL, PRIMARY KEY (id), KEY idx_user (user_id), KEY idx_type (type), KEY idx_scope (scope), KEY idx_expires (expires_at), KEY idx_created (created_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_restriction); // ── follow ── $sql_follow = "CREATE TABLE {$prefix}aksrt_follow ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, follower_id BIGINT UNSIGNED NOT NULL, following_id BIGINT UNSIGNED NOT NULL, created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (id), UNIQUE KEY idx_pair (follower_id, following_id), KEY idx_following (following_id), KEY idx_created (created_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_follow); // ── coupon ── $sql_coupon = "CREATE TABLE {$prefix}aksrt_coupon ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, code VARCHAR(60) NOT NULL DEFAULT '', type VARCHAR(20) NOT NULL DEFAULT 'fixed', value DECIMAL(10,2) NOT NULL DEFAULT 0, min_amount DECIMAL(10,2) NOT NULL DEFAULT 0, usage_limit INT UNSIGNED NOT NULL DEFAULT 0, used_count INT UNSIGNED NOT NULL DEFAULT 0, expires_at DATETIME DEFAULT NULL, per_user_limit INT UNSIGNED NOT NULL DEFAULT 0, product_scope TEXT DEFAULT NULL, max_discount DECIMAL(10,2) NOT NULL DEFAULT 0, status VARCHAR(20) NOT NULL DEFAULT 'active', created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (id), UNIQUE KEY idx_code (code), KEY idx_status (status), KEY idx_expires (expires_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_coupon); // ── coupon_usage (R68) ── $sql_coupon_usage = "CREATE TABLE {$prefix}aksrt_coupon_usage ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, coupon_id BIGINT UNSIGNED NOT NULL DEFAULT 0, user_id BIGINT UNSIGNED NOT NULL DEFAULT 0, order_number VARCHAR(32) NOT NULL DEFAULT '', discount DECIMAL(10,2) NOT NULL DEFAULT 0, created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (id), KEY idx_coupon (coupon_id), KEY idx_user (user_id), UNIQUE KEY uniq_coupon_usage_order (order_number) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_coupon_usage); // ── 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 '', password VARCHAR(80) NOT NULL DEFAULT '', type VARCHAR(20) NOT NULL DEFAULT 'balance', amount DECIMAL(10,2) NOT NULL DEFAULT 0, balance DECIMAL(10,2) NOT NULL DEFAULT 0, status VARCHAR(20) NOT NULL DEFAULT 'active', meta LONGTEXT DEFAULT NULL, order_number VARCHAR(32) NOT NULL DEFAULT '', used_by BIGINT UNSIGNED DEFAULT NULL, used_at DATETIME DEFAULT NULL, expires_at DATETIME DEFAULT NULL, created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', note TEXT DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY idx_password (password), KEY idx_card (card), KEY idx_type (type), KEY idx_status (status), KEY idx_used_by (used_by), KEY idx_order_number (order_number), KEY idx_expires (expires_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_charge_card); // ── canonical Ref attribution and permanent user binding ── $sql_affiliate_relation = "CREATE TABLE {$prefix}aksrt_affiliate_relation ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, referral_code VARCHAR(32) NOT NULL, promoter_id BIGINT UNSIGNED NOT NULL, invitee_id BIGINT UNSIGNED DEFAULT NULL, first_touch_at DATETIME NOT NULL, bound_at DATETIME DEFAULT NULL, status VARCHAR(20) NOT NULL DEFAULT 'captured', reward_status VARCHAR(20) NOT NULL DEFAULT 'skipped', rewarded_at DATETIME DEFAULT NULL, registration_ip VARCHAR(64) DEFAULT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), KEY idx_referral_code (referral_code), UNIQUE KEY uniq_invitee (invitee_id), KEY idx_promoter (promoter_id), KEY idx_status_touch (status, first_touch_at), KEY idx_reward_status (reward_status), KEY idx_reward_ip (registration_ip, rewarded_at) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_affiliate_relation); // ── immutable commission ledger ── $sql_commission_ledger = "CREATE TABLE {$prefix}aksrt_commission_ledger ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, promoter_id BIGINT UNSIGNED NOT NULL, source_user_id BIGINT UNSIGNED NOT NULL DEFAULT 0, order_number VARCHAR(64) NOT NULL, order_type VARCHAR(32) NOT NULL, eligible_base DECIMAL(18,2) NOT NULL DEFAULT 0, ratio DECIMAL(8,4) NOT NULL DEFAULT 0, original_amount DECIMAL(18,2) NOT NULL DEFAULT 0, 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) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_commission_ledger); // ── immutable commission adjustments (refund/debt/manual) ── $sql_commission_adjustment = "CREATE TABLE {$prefix}aksrt_commission_adjustment ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, ledger_id BIGINT UNSIGNED NOT NULL, promoter_id BIGINT UNSIGNED NOT NULL, amount DECIMAL(18,2) NOT NULL DEFAULT 0, reason VARCHAR(32) NOT NULL, source_key VARCHAR(128) NOT NULL, operator_id BIGINT UNSIGNED NOT NULL DEFAULT 0, created_at DATETIME NOT NULL, note TEXT DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uniq_adjustment_source (source_key), KEY idx_ledger (ledger_id), KEY idx_promoter (promoter_id) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_commission_adjustment); // ── payout account snapshots ── $sql_payout_account = "CREATE TABLE {$prefix}aksrt_payout_account ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, channel VARCHAR(20) NOT NULL, attachment_id BIGINT UNSIGNED NOT NULL DEFAULT 0, account_hash CHAR(64) NOT NULL DEFAULT '', status VARCHAR(20) NOT NULL DEFAULT 'active', created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uniq_user_channel (user_id, channel), KEY idx_user_status (user_id, status) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_payout_account); // ── order_items (§6.5 多商品多商家) ── $sql_order_items = "CREATE TABLE {$prefix}aksrt_order_item ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, order_number VARCHAR(32) NOT NULL DEFAULT '', product_id BIGINT UNSIGNED NOT NULL DEFAULT 0, product_title VARCHAR(255) NOT NULL DEFAULT '', options_key VARCHAR(255) NOT NULL DEFAULT '', options_label VARCHAR(255) NOT NULL DEFAULT '', quantity INT UNSIGNED NOT NULL DEFAULT 1, unit_price DECIMAL(10,2) NOT NULL DEFAULT 0, total_price DECIMAL(10,2) NOT NULL DEFAULT 0, discount_amount DECIMAL(10,2) NOT NULL DEFAULT 0, shipping_fee DECIMAL(10,2) NOT NULL DEFAULT 0, pay_price DECIMAL(10,2) NOT NULL DEFAULT 0, shipping_type VARCHAR(20) NOT NULL DEFAULT 'express', auto_delivery_content TEXT DEFAULT NULL, discount_hit TEXT DEFAULT NULL, gift_data TEXT DEFAULT NULL, image VARCHAR(512) NOT NULL DEFAULT '', PRIMARY KEY (id), KEY idx_order (order_number), KEY idx_product (product_id) ) ENGINE=InnoDB {$charset_collate};"; dbDelta($sql_order_items); self::migrate_identity_tables($prefix, $charset_collate); self::migrate_vip_tables($prefix, $charset_collate); } }