refactor(autoload): migrate theme classes to Composer PSR-4

Move 288 types from global AKSRT_* + inc/classes manual requires into
namespace AKSRT\{Domain} under src/AKSRT/, wire composer.json psr-4,
and slim bootstrap to helpers/modules/hooks only. Split multi-class
widget/gateway files, update admin contract audit paths, and document
the layout in ADR/README.
This commit is contained in:
kate522 committed 2026-07-17 13:29:22 +08:00
1 parent 8f349b40fb
commit aaf458af1c
404 files changed
+13602 -7705

No files matched your search

+295
View File
@@ -0,0 +1,295 @@
<?php
/**
* @package AKSRT
*/
namespace AKSRT\Admin\Native;
defined('ABSPATH') || exit;
class PayMenus {
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('PayOrders')) {
PayOrders::get_instance()->render_orders_page();
return;
}
wp_die(esc_html__('订单模块未初始化。', 'aksrt'));
},
],
'products' => [
'slug' => 'aksrt_pay_products',
'title' => __('付费文章', 'aksrt'),
'callback' => static function (): void {
if (class_exists('PayProducts')) {
PayProducts::get_instance()->render_products_page();
return;
}
wp_die(esc_html__('付费文章模块未初始化。', 'aksrt'));
},
],
'download_logs' => [
'slug' => 'aksrt_download_logs',
'title' => __('下载记录', 'aksrt'),
'callback' => static function (): void {
if (class_exists('PayDownloadLogs')) {
PayDownloadLogs::get_instance()->render_page();
return;
}
wp_die(esc_html__('下载记录模块未初始化。', 'aksrt'));
},
],
'shipping' => [
'slug' => 'aksrt_shipping',
'title' => __('发货及物流', 'aksrt'),
'callback' => static function (): void {
if (class_exists('PayShipping')) {
PayShipping::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('PayAfterSale')) {
PayAfterSale::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('PayCoupons')) {
PayCoupons::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('PayChargeCards')) {
PayChargeCards::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('PayIncome')) {
PayIncome::get_instance()->render_income_page();
return;
}
wp_die(esc_html__('分成模块未初始化。', 'aksrt'));
},
],
'rebate' => [
'slug' => 'aksrt_rebate',
'title' => __('推广返佣', 'aksrt'),
'callback' => static function (): void {
if (class_exists('PayRebate')) {
PayRebate::get_instance()->render_rebate_page();
return;
}
wp_die(esc_html__('返佣模块未初始化。', 'aksrt'));
},
],
'withdraw' => [
'slug' => 'aksrt_withdraw',
'title' => __('提现审核', 'aksrt'),
'callback' => static function (): void {
if (class_exists('PayWithdrawals')) {
PayWithdrawals::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\Payment\Withdrawal')) {
$pending = (int) \AKSRT\Payment\Withdrawal::get_instance()->get_count(['status' => \AKSRT\Payment\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\Payment\AfterSale')) {
$as_stats = \AKSRT\Payment\AfterSale::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\Payment\OrderRepository')
? \AKSRT\Payment\OrderRepository::get_instance()->get_stats()
: [];
$withdraw_stats = class_exists('\AKSRT\Payment\Withdrawal')
? \AKSRT\Payment\Withdrawal::get_instance()->get_stats()
: [];
$card_stats = class_exists('\AKSRT\Payment\ChargeCard')
? \AKSRT\Payment\ChargeCard::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\Payment\OrderRepository')) {
$pending_ship = (int) (\AKSRT\Payment\OrderRepository::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>';
}
}