From 929603b9e2e4697fd8851a7069fd35000f3776d5 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 16 Aug 2026 23:11:01 +0800 Subject: [PATCH] feat: adjust affiliate commissions and withdrawal strategy --- .../src/schema/sections/payment/affiliate.js | 35 ++++------------- .../src/schema/sections/payment/withdrawal.js | 26 ++++++------- assets/js/credits.js | 2 +- inc/helpers/aksrt-pay.php | 14 +------ .../user-center-renderers/profile-revenue.php | 6 ++- .../user-center-renderers/withdraw-modal.php | 9 ++++- src/Admin/Schema/SchemaPayment.php | 19 +++------- src/Content/PayHelpers.php | 15 +------- src/Credits/BalanceServiceRest.php | 7 +++- src/Payment/CommissionLedger.php | 25 +++++++++--- src/Payment/ReferralAttribution.php | 3 +- src/Settings/CreditsPaymentGroups.php | 5 ++- src/Settings/PaymentRuntime.php | 38 +++++++++++-------- 13 files changed, 93 insertions(+), 111 deletions(-) diff --git a/assets/admin/src/schema/sections/payment/affiliate.js b/assets/admin/src/schema/sections/payment/affiliate.js index 0bd2368b..ef605a00 100644 --- a/assets/admin/src/schema/sections/payment/affiliate.js +++ b/assets/admin/src/schema/sections/payment/affiliate.js @@ -2,22 +2,16 @@ export const affiliateSchema = { key: 'payment.affiliate', title: '推广返佣', icon: 'fas fa-share-alt', - description: '配置推广归因、佣金比例、结算和提现规则。', + description: '配置推广归因、分级佣金比例和结算规则。', defaults: { affiliate_enabled: false, - affiliate_ratio: 5, + affiliate_ratio_user: 5, + affiliate_ratio_vip_1: 5, + affiliate_ratio_vip_2: 5, affiliate_order_types: ['membership', 'content'], affiliate_touch_window_days: 30, affiliate_settlement_days: 7, - affiliate_allow_self_purchase: false, - affiliate_show_stats: true, affiliate_promotion_text: '', - affiliate_payout_channels: ['alipay', 'wechat'], - affiliate_min_withdrawal: 50, - affiliate_withdrawal_fee: 5, - affiliate_daily_withdrawal_count: 3, - affiliate_daily_withdrawal_limit: 500, - affiliate_withdrawal_reset_time: '00:00', }, groups: [ { @@ -26,25 +20,12 @@ export const affiliateSchema = { icon: 'fas fa-project-diagram', fields: [ { key: 'affiliate_enabled', label: '启用推广返佣', type: 'switch', default: false }, - { key: 'affiliate_ratio', label: '全站佣金比例(%)', type: 'number', default: 5, min: 0, max: 100, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_order_types', label: '适用订单类型', type: 'checkbox', default: ['membership', 'content'], sanitize_type: 'array', options: [{ label: '会员订单', value: 'membership' }, { label: '付费内容', value: 'content' }], dependsOn: { key: 'affiliate_enabled', value: true } }, + { key: 'affiliate_ratio_user', label: '普通会员佣金比例(%)', type: 'number', default: 5, min: 0, max: 100, dependsOn: { key: 'affiliate_enabled', value: true } }, + { key: 'affiliate_ratio_vip_1', label: '一级会员佣金比例(%)', type: 'number', default: 5, min: 0, max: 100, dependsOn: { key: 'affiliate_enabled', value: true } }, + { key: 'affiliate_ratio_vip_2', label: '二级会员佣金比例(%)', type: 'number', default: 5, min: 0, max: 100, dependsOn: { key: 'affiliate_enabled', value: true } }, + { key: 'affiliate_order_types', label: '适用订单类型', type: 'checkbox', default: ['membership', 'content'], sanitize_type: 'array', options: [{ label: '会员订单', value: 'membership' }, { label: '付费内容', value: 'content' }, { label: '购买积分', value: 'credits' }], dependsOn: { key: 'affiliate_enabled', value: true } }, { key: 'affiliate_touch_window_days', label: '首次触达窗口(天)', type: 'number', default: 30, min: 1, max: 365, dependsOn: { key: 'affiliate_enabled', value: true } }, { key: 'affiliate_settlement_days', label: '结算观察期(天)', type: 'number', default: 7, min: 0, max: 90, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_allow_self_purchase', label: '允许自购返佣', type: 'switch', default: false, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_show_stats', label: '展示推广统计', type: 'switch', default: true, dependsOn: { key: 'affiliate_enabled', value: true } }, - ], - }, - { - key: 'withdrawal', - title: '提现规则', - icon: 'fas fa-wallet', - fields: [ - { key: 'affiliate_min_withdrawal', label: '最低提现金额', type: 'number', default: 50, min: 0, max: 99999, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_withdrawal_fee', label: '提现手续费(%)', type: 'number', default: 5, min: 0, max: 100, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_daily_withdrawal_count', label: '每日可提现次数', type: 'number', default: 3, min: 0, max: 99999, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_daily_withdrawal_limit', label: '每日提现上限', type: 'number', default: 500, min: 0, max: 999999, dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_withdrawal_reset_time', label: '重置时间', type: 'input', default: '00:00', help: '按站点 WordPress 时区重置,格式 HH:MM。', dependsOn: { key: 'affiliate_enabled', value: true } }, - { key: 'affiliate_payout_channels', label: '可用收款渠道', type: 'checkbox', default: ['alipay', 'wechat'], sanitize_type: 'array', options: [{ label: '支付宝收款码', value: 'alipay' }, { label: '微信收款码', value: 'wechat' }], dependsOn: { key: 'affiliate_enabled', value: true } }, ], }, { diff --git a/assets/admin/src/schema/sections/payment/withdrawal.js b/assets/admin/src/schema/sections/payment/withdrawal.js index bffdb44e..34908ba2 100644 --- a/assets/admin/src/schema/sections/payment/withdrawal.js +++ b/assets/admin/src/schema/sections/payment/withdrawal.js @@ -1,15 +1,15 @@ export const withdrawalSchema = { key: 'payment.withdrawal', - title: '提现管理', + title: '提现策略', icon: 'fas fa-hand-holding-usd', description: '配置提现门槛、手续费比例与每日限制。', defaults: { - pay_balance_withdraw_s: false, - pay_rebate_withdraw_lowest_money: 50, - withdraw_service_charge: 5, - withdraw_daily_count: 3, - withdraw_daily_limit: 50, - withdraw_reset_time: '00:00', + affiliate_min_withdrawal: 50, + affiliate_withdrawal_fee: 5, + affiliate_daily_withdrawal_count: 3, + affiliate_daily_withdrawal_limit: 500, + affiliate_withdrawal_reset_time: '00:00', + affiliate_payout_channels: ['alipay', 'wechat'], }, groups: [ { @@ -17,12 +17,12 @@ export const withdrawalSchema = { title: '提现设置', icon: 'fas fa-sliders-h', fields: [ - { key: 'pay_balance_withdraw_s', label: '启用余额提现', type: 'switch', default: false }, - { key: 'pay_rebate_withdraw_lowest_money', label: '最低提现金额', type: 'number', default: 50, min: 0, max: 99999, dependsOn: { key: 'pay_balance_withdraw_s', value: true } }, - { key: 'withdraw_service_charge', label: '提现手续费(%)', type: 'number', default: 5, min: 0, max: 50, dependsOn: { key: 'pay_balance_withdraw_s', value: true } }, - { key: 'withdraw_daily_count', label: '每日可提现次数', type: 'number', default: 3, min: 0, max: 99999, dependsOn: { key: 'pay_balance_withdraw_s', value: true } }, - { key: 'withdraw_daily_limit', label: '每日提现上限', type: 'number', default: 50, min: 0, max: 999999, dependsOn: { key: 'pay_balance_withdraw_s', value: true } }, - { key: 'withdraw_reset_time', label: '重置时间', type: 'input', default: '00:00', help: '按站点 WordPress 时区重置,格式 HH:MM。', dependsOn: { key: 'pay_balance_withdraw_s', value: true } }, + { key: 'affiliate_min_withdrawal', label: '最低提现金额', type: 'number', default: 50, min: 0, max: 99999 }, + { key: 'affiliate_withdrawal_fee', label: '提现手续费(%)', type: 'number', default: 5, min: 0, max: 100 }, + { key: 'affiliate_daily_withdrawal_count', label: '每日可提现次数', type: 'number', default: 3, min: 0, max: 99999 }, + { key: 'affiliate_daily_withdrawal_limit', label: '每日提现上限', type: 'number', default: 500, min: 0, max: 999999 }, + { key: 'affiliate_withdrawal_reset_time', label: '重置时间', type: 'input', default: '00:00', help: '按站点 WordPress 时区重置,格式 HH:MM。' }, + { key: 'affiliate_payout_channels', label: '可用收款渠道', type: 'checkbox', default: ['alipay', 'wechat'], sanitize_type: 'array', options: [{ label: '支付宝收款码', value: 'alipay' }, { label: '微信收款码', value: 'wechat' }] }, ], }, ], diff --git a/assets/js/credits.js b/assets/js/credits.js index ef6148c9..3c17bb64 100644 --- a/assets/js/credits.js +++ b/assets/js/credits.js @@ -209,7 +209,7 @@ input.style.width = Math.max(28, Math.min(96, linkLength || 28)) + 'ch'; } if (copy) copy.disabled = !j.url; - var ratio = root.querySelector('[data-affiliate-ratio]'); if (ratio) ratio.textContent = String(j.ratio || 0) + '%'; + var ratio = root.querySelector('[data-affiliate-ratio]'); if (ratio) ratio.textContent = String(j.current_ratio || 0) + '%'; var promoters = root.querySelector('[data-affiliate-promoters]'); if (promoters) promoters.textContent = String(stats.promoters || 0); var payers = root.querySelector('[data-affiliate-payers]'); if (payers) payers.textContent = String(stats.effective_payers || 0); }).catch(function () { setFeedback('推广数据加载失败。', true); }); diff --git a/inc/helpers/aksrt-pay.php b/inc/helpers/aksrt-pay.php index 7e677217..2fa192c7 100644 --- a/inc/helpers/aksrt-pay.php +++ b/inc/helpers/aksrt-pay.php @@ -606,19 +606,7 @@ if (!function_exists('aksrt_get_post_rebate_discount')) { return 0.0; } // Need a positive ratio for referrer (VIP tier of referrer preferred). - $ratio = (int) ($aff['ratio'] ?? 0); - $user_ratio = is_array($aff['user_ratio'] ?? null) ? $aff['user_ratio'] : []; - $ref_vip = 0; - if (function_exists('aksrt_get_user_vip_level')) { - $ref_vip = (int) aksrt_get_user_vip_level($referrer_id); - } - if ($ref_vip >= 2 && !empty($user_ratio['vip2'])) { - $ratio = (int) $user_ratio['vip2']; - } elseif ($ref_vip >= 1 && !empty($user_ratio['vip1'])) { - $ratio = (int) $user_ratio['vip1']; - } elseif (isset($user_ratio['user'])) { - $ratio = (int) $user_ratio['user']; - } + $ratio = (int) round(\AKSRT\Settings\Settings::affiliate_ratio_for_user($referrer_id)); if ($ratio <= 0) { return 0.0; } diff --git a/inc/helpers/user-center-renderers/profile-revenue.php b/inc/helpers/user-center-renderers/profile-revenue.php index d4b3c5df..44714a0b 100644 --- a/inc/helpers/user-center-renderers/profile-revenue.php +++ b/inc/helpers/user-center-renderers/profile-revenue.php @@ -26,7 +26,7 @@ $withdraw_on = !empty($affiliate['enabled']) if ($withdraw_on && class_exists('\AKSRT\Settings\Capabilities') && !\AKSRT\Settings\Capabilities::user_can('balance_withdraw', $user_id)) { $withdraw_on = false; } -$withdraw_min = max(1, (float) ($affiliate['min_withdrawal'] ?? $withdrawal['min_amount'] ?? 50)); +$withdraw_min = max(1, (float) ($withdrawal['min_amount'] ?? 50)); $wallet_fmt = class_exists('\AKSRT\Credits\Balance') ? \AKSRT\Credits\Balance::format((float) \AKSRT\Credits\Balance::balance($user_id)) : '0.00'; @@ -38,7 +38,9 @@ $available_commission = class_exists('\AKSRT\Credits\Balance') ? (float) \AKSRT\Credits\Balance::balance($user_id) : (float) ($commission_stats['settled'] ?? 0); $vip_ratios = []; -$commission_ratio = (float) ($affiliate['ratio'] ?? 0); +$commission_ratio = class_exists('\AKSRT\Settings\Settings') + ? (float) \AKSRT\Settings\Settings::affiliate_ratio_for_user($user_id) + : 0.0; $details_text = trim((string) ($affiliate['promotion_text'] ?? '')); if ($details_text === '') { $details_text = __('好友通过推广链接完成符合条件的订单后,系统会按当前佣金比例记录返佣,结算后进入可提现余额。', 'aksrt'); diff --git a/inc/helpers/user-center-renderers/withdraw-modal.php b/inc/helpers/user-center-renderers/withdraw-modal.php index d1418c9e..87192468 100644 --- a/inc/helpers/user-center-renderers/withdraw-modal.php +++ b/inc/helpers/user-center-renderers/withdraw-modal.php @@ -9,6 +9,10 @@ $GLOBALS['aksrt_withdraw_modal_rendered'] = true; $withdraw_min = max(0, (float) ($withdraw_min ?? 50)); $withdraw_usage = is_array($withdraw_usage ?? null) ? $withdraw_usage : ['remaining_count' => 0, 'remaining_amount' => 0]; $withdraw_fee_rate = (int) ($withdraw_settings['service_charge_rate'] ?? 5); +$withdraw_channels = array_values(array_intersect(['alipay', 'wechat'], (array) ($withdraw_settings['payout_channels'] ?? ['alipay', 'wechat']))); +if (!$withdraw_channels) { + $withdraw_channels = ['alipay', 'wechat']; +} ?>