From 6880746ed3064dc1e768cc4696a1e3c187ae3549 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 Jul 2026 12:40:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(payment):=20=E8=A1=A5=E9=BD=90=E5=88=9B?= =?UTF-8?q?=E4=BD=9C=E5=88=86=E6=88=90=E7=BB=93=E7=AE=97=20+=20=E6=94=B6?= =?UTF-8?q?=E5=B0=BE=20auth=20=E5=A3=B3=E5=B1=82=E6=AC=A0=E8=B4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 AKSRT_Creator_Revenue:监听 aksrt_order_paid,按 share_ratio 把商品作者分成写入既有 aksrt_revenue 台账(幂等、跳过自购),闭合此前"结算引擎"延后项;管理端 /payment/revenue 与 /shop 概览自动读取。 - page-verify-email 套用 sign 壳层与站点 logo,和 reset/bind 对齐。 - modal-auth 补 close_signup 门控,与全页登录页一致。 Co-Authored-By: Claude Fable 5 --- functions.php | 3 + inc/bootstrap.php | 3 + inc/classes/class-aksrt-creator-revenue.php | 145 ++++++++++++++++++++ templates/pages/page-verify-email.php | 12 +- templates/parts/modal-auth.php | 3 + 5 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 inc/classes/class-aksrt-creator-revenue.php diff --git a/functions.php b/functions.php index 955f6ed5..0eec8342 100644 --- a/functions.php +++ b/functions.php @@ -168,6 +168,9 @@ if (class_exists('AKSRT_Signin')) { if (class_exists('AKSRT_Invite')) { AKSRT_Invite::get_instance()->init(); } +if (class_exists('AKSRT_Creator_Revenue')) { + AKSRT_Creator_Revenue::get_instance()->init(); +} if (class_exists('AKSRT_Download')) { AKSRT_Download::get_instance()->init(); } diff --git a/inc/bootstrap.php b/inc/bootstrap.php index 0ef9d916..beade4c6 100644 --- a/inc/bootstrap.php +++ b/inc/bootstrap.php @@ -276,6 +276,9 @@ require_once AKSRT_DIR . '/inc/classes/gateways/class-aksrt-stripe-gateway.php'; // 收益台账 require_once AKSRT_DIR . '/inc/classes/class-aksrt-revenue.php'; +// 创作分成结算(监听 aksrt_order_paid,把作者分成写入收益台账) +require_once AKSRT_DIR . '/inc/classes/class-aksrt-creator-revenue.php'; + // 提现台账 require_once AKSRT_DIR . '/inc/classes/class-aksrt-withdrawal.php'; diff --git a/inc/classes/class-aksrt-creator-revenue.php b/inc/classes/class-aksrt-creator-revenue.php new file mode 100644 index 00000000..853963e6 --- /dev/null +++ b/inc/classes/class-aksrt-creator-revenue.php @@ -0,0 +1,145 @@ +0 wins). + if ($author_id > 0 && function_exists('aksrt_get_user_vip_level')) { + $level = (int) aksrt_get_user_vip_level($author_id); + if ($level === 1 && (float) ($settings['ratio_vip1'] ?? 0) > 0) { + $ratio = (float) $settings['ratio_vip1']; + } elseif ($level >= 2 && (float) ($settings['ratio_vip2'] ?? 0) > 0) { + $ratio = (float) $settings['ratio_vip2']; + } + } + + return max(0.0, min(100.0, $ratio)); + } + + /** + * Guard: has this order already been settled into revenue? + */ + private function already_settled(string $order_number): bool { + if ($order_number === '' || !class_exists('AKSRT_DB_Migrator')) { + return false; + } + global $wpdb; + $table = AKSRT_DB_Migrator::table('revenue'); + if ($table === '') { + return false; + } + $count = (int) $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM {$table} WHERE order_number = %s AND type = %s", + $order_number, + 'order' + )); + return $count > 0; + } + + /** + * aksrt_order_paid listener: credit creators their share. + * + * @param string $order_number Paid order number. + * @param array $order Order row (status=paid). + */ + public function handle_order_paid(string $order_number, array $order): void { + if (!$this->is_enabled() || $order_number === '') { + return; + } + if ($this->already_settled($order_number)) { + return; + } + + $buyer_id = (int) ($order['user_id'] ?? 0); + + $items = []; + if (class_exists('AKSRT_Shop')) { + $shop = AKSRT_Shop::get_instance(); + if (method_exists($shop, 'get_order_items')) { + $items = (array) $shop->get_order_items($order_number); + } + } + + if (empty($items)) { + return; // Only structured shop-product orders settle creator revenue here. + } + + $revenue = AKSRT_Revenue::get_instance(); + + foreach ($items as $item) { + $product_id = (int) ($item['product_id'] ?? 0); + $pay_price = (float) ($item['pay_price'] ?? $item['total_price'] ?? 0); + if ($product_id <= 0 || $pay_price <= 0) { + continue; + } + + $author_id = (int) get_post_field('post_author', $product_id); + if ($author_id <= 0 || $author_id === $buyer_id) { + continue; // No author, or buyer is the author. + } + + $ratio = $this->resolve_share_ratio($author_id); + if ($ratio <= 0) { + continue; + } + + $amount = round($pay_price * $ratio / 100, 2); + if ($amount <= 0) { + continue; + } + + $revenue->add($author_id, $amount, $order_number, 'order'); + } + } + } +} diff --git a/templates/pages/page-verify-email.php b/templates/pages/page-verify-email.php index 71a78e86..61468e03 100644 --- a/templates/pages/page-verify-email.php +++ b/templates/pages/page-verify-email.php @@ -49,13 +49,19 @@ $verify_mode = (string) ($verify_context['mode'] ?? 'invalid'); $verify_method= (string) ($verify_context['method'] ?? ''); $verify_vk = (string) ($verify_context['access_key'] ?? ''); +remove_action('wp_footer', 'aksrt_render_footer_tabbar', 20); +remove_action('wp_footer', 'aksrt_render_float_buttons', 30); +add_filter('body_class', static function ($classes) { + $classes[] = 'page-template-user-sign'; + return $classes; +}); get_header(); ?> -
+
-
- +
+

diff --git a/templates/parts/modal-auth.php b/templates/parts/modal-auth.php index 4317752b..6dce1627 100644 --- a/templates/parts/modal-auth.php +++ b/templates/parts/modal-auth.php @@ -26,6 +26,9 @@ $show_qrcode_tab = false; if (class_exists('AKSRT_Settings')) { $registration_open = AKSRT_Settings::registration_enabled(); + if (method_exists('AKSRT_Settings', 'close_signup') && AKSRT_Settings::close_signup()) { + $registration_open = false; + } $email_verification = AKSRT_Settings::registration_requires_email_verification(); $close_signin = AKSRT_Settings::close_signin();