Files
wordpress-theme-aksrt/inc/classes/admin/native/class-aksrt-admin-pay-menus.php
T

276 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Native WP admin menus shell for payment / order ops (zibll zibpay-style).
*
* Domain pages live in dedicated AKSRT_Admin_Pay_* classes.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Admin_Pay_Menus {
public const CAPABILITY = 'manage_options';
public const MENU_SLUG = 'aksrt_pay';
private static $instance = null;
public static function get_instance(): self {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function init(): void {
if (!is_admin()) {
return;
}
add_action('admin_menu', [$this, 'register_menus']);
add_action('admin_notices', [$this, 'pending_notices']);
// Domain admin_post handlers are registered by dedicated modules.
}
/**
* @return array<string, array{slug:string,title:string,callback:callable}>
*/
private function pages(): array {
return [
'overview' => [
'slug' => self::MENU_SLUG,
'title' => __('概览', 'aksrt'),
'callback' => [$this, 'render_overview_page'],
],
'orders' => [
'slug' => 'aksrt_orders',
'title' => __('订单', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Orders')) {
AKSRT_Admin_Pay_Orders::get_instance()->render_orders_page();
return;
}
wp_die(esc_html__('订单模块未初始化。', 'aksrt'));
},
],
'shipping' => [
'slug' => 'aksrt_shipping',
'title' => __('发货及物流', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Shipping')) {
AKSRT_Admin_Pay_Shipping::get_instance()->render_shipping_page();
return;
}
wp_die(esc_html__('物流模块未初始化。', 'aksrt'));
},
],
'after_sale' => [
'slug' => 'aksrt_after_sale',
'title' => __('售后管理', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_After_Sale')) {
AKSRT_Admin_Pay_After_Sale::get_instance()->render_after_sale_page();
return;
}
wp_die(esc_html__('售后模块未初始化。', 'aksrt'));
},
],
'coupons' => [
'slug' => 'aksrt_coupons',
'title' => __('优惠码', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Coupons')) {
AKSRT_Admin_Pay_Coupons::get_instance()->render_page();
return;
}
wp_die(esc_html__('优惠码模块未初始化。', 'aksrt'));
},
],
'charge_cards' => [
'slug' => 'aksrt_charge_cards',
'title' => __('卡密管理', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Charge_Cards')) {
AKSRT_Admin_Pay_Charge_Cards::get_instance()->render_charge_cards_page();
return;
}
wp_die(esc_html__('卡密模块未初始化。', 'aksrt'));
},
],
'income' => [
'slug' => 'aksrt_income',
'title' => __('创作分成', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Income')) {
AKSRT_Admin_Pay_Income::get_instance()->render_income_page();
return;
}
wp_die(esc_html__('分成模块未初始化。', 'aksrt'));
},
],
'rebate' => [
'slug' => 'aksrt_rebate',
'title' => __('推广返佣', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Rebate')) {
AKSRT_Admin_Pay_Rebate::get_instance()->render_rebate_page();
return;
}
wp_die(esc_html__('返佣模块未初始化。', 'aksrt'));
},
],
'withdraw' => [
'slug' => 'aksrt_withdraw',
'title' => __('提现审核', 'aksrt'),
'callback' => static function (): void {
if (class_exists('AKSRT_Admin_Pay_Withdrawals')) {
AKSRT_Admin_Pay_Withdrawals::get_instance()->render_withdrawals_page();
return;
}
wp_die(esc_html__('提现模块未初始化。', 'aksrt'));
},
],
];
}
public function register_menus(): void {
if (!current_user_can(self::CAPABILITY)) {
return;
}
add_menu_page(
__('支付中心', 'aksrt'),
__('支付中心', 'aksrt'),
self::CAPABILITY,
self::MENU_SLUG,
[$this, 'render_overview_page'],
'dashicons-cart',
36
);
foreach ($this->pages() as $page) {
add_submenu_page(
self::MENU_SLUG,
$page['title'],
$page['title'],
self::CAPABILITY,
$page['slug'],
$page['callback']
);
}
}
public function pending_notices(): void {
if (!current_user_can(self::CAPABILITY)) {
return;
}
$page = isset($_GET['page']) ? sanitize_key((string) wp_unslash($_GET['page'])) : '';
if ($page !== 'aksrt_withdraw' && class_exists('AKSRT_Withdrawal')) {
$pending = (int) AKSRT_Withdrawal::get_instance()->get_count(['status' => AKSRT_Withdrawal::STATUS_PENDING]);
if ($pending > 0) {
$url = admin_url('admin.php?page=aksrt_withdraw&status=pending');
echo '<div class="notice notice-info is-dismissible">';
echo '<h3>' . esc_html__('提现申请待处理', 'aksrt') . '</h3>';
echo '<p>' . esc_html(sprintf(
/* translators: %d: pending withdrawal count */
__('您有 %d 个提现申请待处理', 'aksrt'),
$pending
)) . '</p>';
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('立即处理', 'aksrt') . '</a></p>';
echo '</div>';
}
}
if ($page !== 'aksrt_after_sale' && class_exists('AKSRT_After_Sale')) {
$as_stats = AKSRT_After_Sale::get_instance()->get_stats();
$pending_as = (int) ($as_stats['pending'] ?? 0);
if ($pending_as > 0) {
$url = admin_url('admin.php?page=aksrt_after_sale&status=pending');
echo '<div class="notice notice-info is-dismissible">';
echo '<h3>' . esc_html__('售后工单待处理', 'aksrt') . '</h3>';
echo '<p>' . esc_html(sprintf(
/* translators: %d: pending after-sale count */
__('您有 %d 个售后工单待处理', 'aksrt'),
$pending_as
)) . '</p>';
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('去处理', 'aksrt') . '</a></p>';
echo '</div>';
}
}
}
private function ensure_cap(): void {
if (!current_user_can(self::CAPABILITY)) {
wp_die(esc_html__('您没有权限访问此页面。', 'aksrt'));
}
}
private function render_header(string $title): void {
echo '<div class="wrap">';
echo '<h1>' . esc_html($title) . '</h1>';
}
private function render_footer(): void {
echo '</div>';
}
private function page_url(string $slug, array $args = []): string {
return add_query_arg(array_merge(['page' => $slug], $args), admin_url('admin.php'));
}
public function render_overview_page(): void {
$this->ensure_cap();
$this->render_header(__('支付中心', 'aksrt'));
$order_stats = class_exists('AKSRT_Order_Repository')
? AKSRT_Order_Repository::get_instance()->get_stats()
: [];
$withdraw_stats = class_exists('AKSRT_Withdrawal')
? AKSRT_Withdrawal::get_instance()->get_stats()
: [];
$card_stats = class_exists('AKSRT_Charge_Card')
? AKSRT_Charge_Card::get_instance()->get_stats()
: [];
echo '<p class="description">' . esc_html__('运营数据入口(对齐 zibll 商城中心)。配置项仍在 AKSRT 主题设置 SPA。', 'aksrt') . '</p>';
echo '<div class="aksrt-pay-stats" style="display:flex;flex-wrap:wrap;gap:16px;margin:20px 0;">';
$pending_ship = 0;
if (class_exists('AKSRT_Order_Repository')) {
$pending_ship = (int) (AKSRT_Order_Repository::get_instance()->get_pending_shipment_orders(['limit' => 1])['total'] ?? 0);
}
$this->stat_card(__('订单总数', 'aksrt'), (string) (int) ($order_stats['total'] ?? 0), $this->page_url('aksrt_orders'));
$this->stat_card(__('待支付', 'aksrt'), (string) (int) ($order_stats['pending'] ?? 0), $this->page_url('aksrt_orders', ['status' => 'pending']));
$this->stat_card(__('已支付', 'aksrt'), (string) (int) ($order_stats['paid'] ?? 0), $this->page_url('aksrt_orders', ['status' => 'paid']));
$this->stat_card(__('待发货', 'aksrt'), (string) $pending_ship, $this->page_url('aksrt_shipping', ['view' => 'pending']));
$this->stat_card(__('营收', 'aksrt'), number_format((float) ($order_stats['revenue'] ?? 0), 2), $this->page_url('aksrt_orders'));
$this->stat_card(__('待审提现', 'aksrt'), (string) (int) ($withdraw_stats['pending'] ?? 0), $this->page_url('aksrt_withdraw', ['status' => 'pending']));
$this->stat_card(__('可用卡密', 'aksrt'), (string) (int) ($card_stats['active'] ?? 0), $this->page_url('aksrt_charge_cards', ['status' => 'active']));
echo '</div>';
echo '<h2>' . esc_html__('快捷入口', 'aksrt') . '</h2><ul>';
foreach ($this->pages() as $page) {
if ($page['slug'] === self::MENU_SLUG) {
continue;
}
echo '<li><a href="' . esc_url($this->page_url($page['slug'])) . '">' . esc_html($page['title']) . '</a></li>';
}
echo '</ul>';
$spa = admin_url('admin.php?page=aksrt-settings#/payment/gateway');
echo '<p><a class="button" href="' . esc_url($spa) . '">' . esc_html__('打开支付配置(SPA)', 'aksrt') . '</a></p>';
$this->render_footer();
}
private function stat_card(string $label, string $value, string $url): void {
echo '<a href="' . esc_url($url) . '" style="display:block;min-width:140px;padding:16px;background:#fff;border:1px solid #c3c4c7;border-radius:4px;text-decoration:none;color:inherit;">';
echo '<div style="font-size:12px;color:#646970;">' . esc_html($label) . '</div>';
echo '<div style="font-size:22px;font-weight:600;margin-top:6px;">' . esc_html($value) . '</div>';
echo '</a>';
}
}