feat: upgrade widgets and affiliate commission flow
This commit is contained in:
@@ -14,7 +14,7 @@ class DBMigrator {
|
||||
use DBMigratorVip;
|
||||
|
||||
/** Current schema version; changing it re-runs dbDelta. */
|
||||
const SCHEMA_VERSION = '1.22.0';
|
||||
const SCHEMA_VERSION = '1.23.0';
|
||||
|
||||
const OPT_KEY = 'aksrt_db_schema_version';
|
||||
|
||||
|
||||
@@ -377,6 +377,84 @@ trait DBMigratorPart2 {
|
||||
) {$charset_collate};";
|
||||
dbDelta($sql_rebate_log);
|
||||
|
||||
// ── affiliate attribution (new contract; no legacy invite reads) ──
|
||||
$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',
|
||||
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)
|
||||
) {$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,
|
||||
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),
|
||||
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};";
|
||||
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)
|
||||
) {$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)
|
||||
) {$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,
|
||||
|
||||
@@ -33,6 +33,10 @@ trait DBMigratorPart3 {
|
||||
'coupon' => 'aksrt_coupon',
|
||||
'charge_card' => 'aksrt_charge_card',
|
||||
'rebate_log' => 'aksrt_rebate_log',
|
||||
'affiliate_relation' => 'aksrt_affiliate_relation',
|
||||
'commission_ledger' => 'aksrt_commission_ledger',
|
||||
'commission_adjustment' => 'aksrt_commission_adjustment',
|
||||
'payout_account' => 'aksrt_payout_account',
|
||||
'coupon_usage' => 'aksrt_coupon_usage',
|
||||
'user_restriction' => 'aksrt_user_restriction',
|
||||
'identity_application' => 'aksrt_identity_application',
|
||||
|
||||
@@ -337,12 +337,13 @@ class WidgetAjax {
|
||||
}
|
||||
|
||||
private function fail(): \WP_REST_Response {
|
||||
return new \WP_REST_Response(['success' => false, 'message' => 'unavailable'], 500);
|
||||
return new \WP_REST_Response(['success' => false, 'code' => 'widget_unavailable', 'message' => __('小工具服务暂不可用。', 'aksrt'), 'data' => ['items' => [], 'page' => 1, 'max_pages' => 1, 'total' => 0]], 500);
|
||||
}
|
||||
|
||||
private function payload(array $payload, int $page): \WP_REST_Response {
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
'code' => 'ok',
|
||||
'html' => (string) ($payload['html'] ?? ''),
|
||||
'paginate_html' => (string) ($payload['paginate_html'] ?? ''),
|
||||
'has_more' => !empty($payload['has_more']),
|
||||
|
||||
Reference in New Issue
Block a user