@@ -0,0 +1,722 @@
< ? php
/**
* Native WP admin menus for payment / order ops (zibll zibpay-style).
*
* Config stays in the AKSRT SPA; this shell owns operational list pages.
*
* @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' ]);
add_action ( 'admin_post_aksrt_pay_update_order_status' , [ $this , 'handle_update_order_status' ]);
add_action ( 'admin_post_aksrt_pay_update_withdrawal' , [ $this , 'handle_update_withdrawal' ]);
add_action ( 'admin_post_aksrt_pay_disable_charge_card' , [ $this , 'handle_disable_charge_card' ]);
}
/**
* @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' => [ $this , 'render_orders_page' ],
],
'shipping' => [
'slug' => 'aksrt_shipping' ,
'title' => __ ( '发货及物流' , 'aksrt' ),
'callback' => [ $this , 'render_stub_page' ],
],
'after_sale' => [
'slug' => 'aksrt_after_sale' ,
'title' => __ ( '售后管理' , 'aksrt' ),
'callback' => [ $this , 'render_stub_page' ],
],
'coupons' => [
'slug' => 'aksrt_coupons' ,
'title' => __ ( '优惠码' , 'aksrt' ),
'callback' => [ $this , 'render_stub_page' ],
],
'charge_cards' => [
'slug' => 'aksrt_charge_cards' ,
'title' => __ ( '卡密管理' , 'aksrt' ),
'callback' => [ $this , 'render_charge_cards_page' ],
],
'income' => [
'slug' => 'aksrt_income' ,
'title' => __ ( '创作分成' , 'aksrt' ),
'callback' => [ $this , 'render_stub_page' ],
],
'rebate' => [
'slug' => 'aksrt_rebate' ,
'title' => __ ( '推广返佣' , 'aksrt' ),
'callback' => [ $this , 'render_stub_page' ],
],
'withdraw' => [
'slug' => 'aksrt_withdraw' ,
'title' => __ ( '提现审核' , 'aksrt' ),
'callback' => [ $this , 'render_withdrawals_page' ],
],
];
}
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 $key => $page ) {
$parent = self :: MENU_SLUG ;
// First item reuses top-level slug (WP pattern).
add_submenu_page (
$parent ,
$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' ) {
return ;
}
if ( ! class_exists ( 'AKSRT_Withdrawal' )) {
return ;
}
$pending = ( int ) AKSRT_Withdrawal :: get_instance () -> get_count ([ 'status' => AKSRT_Withdrawal :: STATUS_PENDING ]);
if ( $pending <= 0 ) {
return ;
}
$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>' ;
}
/* ------------------------------------------------------------------
* Page shells
* ----------------------------------------------------------------*/
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>' ;
$this -> render_flash ();
}
private function render_footer () : void {
echo '</div>' ;
}
private function render_flash () : void {
if ( empty ( $_GET [ 'aksrt_pay_msg' ])) {
return ;
}
$code = sanitize_key (( string ) wp_unslash ( $_GET [ 'aksrt_pay_msg' ]));
$map = [
'order_updated' => __ ( '订单状态已更新。' , 'aksrt' ),
'order_failed' => __ ( '订单状态更新失败。' , 'aksrt' ),
'withdraw_updated' => __ ( '提现状态已更新。' , 'aksrt' ),
'withdraw_failed' => __ ( '提现状态更新失败。' , 'aksrt' ),
'card_disabled' => __ ( '充值卡已禁用。' , 'aksrt' ),
'card_failed' => __ ( '充值卡禁用失败。' , 'aksrt' ),
];
if ( ! isset ( $map [ $code ])) {
return ;
}
$class = str_contains ( $code , 'failed' ) ? 'notice-error' : 'notice-success' ;
echo '<div class="notice ' . esc_attr ( $class ) . ' is-dismissible"><p>' . esc_html ( $map [ $code ]) . '</p></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;">' ;
$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' ), 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>' ;
}
public function render_stub_page () : void {
$this -> ensure_cap ();
$page = isset ( $_GET [ 'page' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'page' ])) : '' ;
$title = __ ( '支付中心' , 'aksrt' );
foreach ( $this -> pages () as $item ) {
if ( $item [ 'slug' ] === $page ) {
$title = $item [ 'title' ];
break ;
}
}
$this -> render_header ( $title );
echo '<div class="notice notice-info"><p>' ;
echo esc_html__ ( '此运营页骨架已挂载到原生侧栏。完整列表与操作将在 Phase 2b 继续补齐;当前可暂时使用 SPA 对应页面。' , 'aksrt' );
echo '</p></div>' ;
$spa_map = [
'aksrt_shipping' => '#/shop/shipping' ,
'aksrt_after_sale' => '#/shop/after-sale' ,
'aksrt_coupons' => '#/shop/coupons' ,
'aksrt_income' => '#/payment/revenue' ,
'aksrt_rebate' => '#/payment/rebate' ,
];
if ( isset ( $spa_map [ $page ])) {
$url = admin_url ( 'admin.php?page=aksrt-settings' . $spa_map [ $page ]);
echo '<p><a class="button button-primary" href="' . esc_url ( $url ) . '">' . esc_html__ ( '打开 SPA 运营页(过渡)' , 'aksrt' ) . '</a></p>' ;
}
$this -> render_footer ();
}
/* ------------------------------------------------------------------
* Orders
* ----------------------------------------------------------------*/
public function render_orders_page () : void {
$this -> ensure_cap ();
$this -> render_header ( __ ( '订单' , 'aksrt' ));
if ( ! class_exists ( 'AKSRT_Order_Repository' )) {
echo '<div class="notice notice-error"><p>' . esc_html__ ( '订单服务不可用。' , 'aksrt' ) . '</p></div>' ;
$this -> render_footer ();
return ;
}
$status = isset ( $_GET [ 'status' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'status' ])) : '' ;
$search = isset ( $_GET [ 's' ]) ? sanitize_text_field (( string ) wp_unslash ( $_GET [ 's' ])) : '' ;
$page_num = max ( 1 , ( int ) ( $_GET [ 'paged' ] ? ? 1 ));
$per_page = 20 ;
$repo = AKSRT_Order_Repository :: get_instance ();
$args = [
'limit' => $per_page ,
'offset' => ( $page_num - 1 ) * $per_page ,
];
if ( $status !== '' && $status !== 'all' ) {
$args [ 'status' ] = $status ;
}
$items = $repo -> get_orders_admin ( $args , $search );
$total = $repo -> get_orders_count ( $args , $search );
$pages = max ( 1 , ( int ) ceil ( $total / $per_page ));
$labels = class_exists ( 'AKSRT_Domain_Model' )
? AKSRT_Domain_Model :: order_status_labels ()
: [];
echo '<form method="get" style="margin:12px 0;">' ;
echo '<input type="hidden" name="page" value="aksrt_orders" />' ;
echo '<select name="status">' ;
echo '<option value="">' . esc_html__ ( '全部状态' , 'aksrt' ) . '</option>' ;
foreach ( $labels as $key => $label ) {
printf (
'<option value="%s"%s>%s</option>' ,
esc_attr ( $key ),
selected ( $status , $key , false ),
esc_html ( $label )
);
}
echo '</select> ' ;
echo '<input type="search" name="s" value="' . esc_attr ( $search ) . '" placeholder="' . esc_attr__ ( '订单号 / 类型' , 'aksrt' ) . '" /> ' ;
submit_button ( __ ( '筛选' , 'aksrt' ), 'secondary' , '' , false );
echo '</form>' ;
echo '<table class="wp-list-table widefat fixed striped">' ;
echo '<thead><tr>' ;
echo '<th>' . esc_html__ ( '订单号' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '用户' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '类型' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '金额' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '状态' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '时间' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '操作' , 'aksrt' ) . '</th>' ;
echo '</tr></thead><tbody>' ;
if ( ! $items ) {
echo '<tr><td colspan="7">' . esc_html__ ( '暂无订单' , 'aksrt' ) . '</td></tr>' ;
}
foreach ( $items as $row ) {
$order_number = ( string ) ( $row [ 'order_number' ] ? ? '' );
$user_id = ( int ) ( $row [ 'user_id' ] ? ? 0 );
$user = $user_id > 0 ? get_userdata ( $user_id ) : null ;
$status_key = ( string ) ( $row [ 'status' ] ? ? '' );
$status_label = $labels [ $status_key ] ? ? $status_key ;
echo '<tr>' ;
echo '<td><code>' . esc_html ( $order_number ) . '</code></td>' ;
echo '<td>' . ( $user ? esc_html ( $user -> display_name . ' (#' . $user_id . ')' ) : esc_html (( string ) $user_id )) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'product_type' ] ? ? '' )) . '</td>' ;
echo '<td>' . esc_html ( number_format (( float ) ( $row [ 'amount' ] ? ? 0 ), 2 )) . ' ' . esc_html (( string ) ( $row [ 'currency' ] ? ? '' )) . '</td>' ;
echo '<td>' . esc_html ( $status_label ) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'created_at' ] ? ? '' )) . '</td>' ;
echo '<td>' ;
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '" style="display:flex;gap:4px;align-items:center;">' ;
echo '<input type="hidden" name="action" value="aksrt_pay_update_order_status" />' ;
echo '<input type="hidden" name="order_number" value="' . esc_attr ( $order_number ) . '" />' ;
wp_nonce_field ( 'aksrt_pay_update_order_status_' . $order_number );
echo '<select name="new_status">' ;
foreach ( $labels as $key => $label ) {
printf (
'<option value="%s"%s>%s</option>' ,
esc_attr ( $key ),
selected ( $status_key , $key , false ),
esc_html ( $label )
);
}
echo '</select>' ;
submit_button ( __ ( '更新' , 'aksrt' ), 'small' , '' , false );
echo '</form>' ;
echo '</td>' ;
echo '</tr>' ;
}
echo '</tbody></table>' ;
if ( $pages > 1 ) {
echo '<div class="tablenav"><div class="tablenav-pages">' ;
echo paginate_links ([
'base' => add_query_arg ( 'paged' , '%#%' ),
'format' => '' ,
'prev_text' => '«' ,
'next_text' => '»' ,
'total' => $pages ,
'current' => $page_num ,
]);
echo '</div></div>' ;
}
$this -> render_footer ();
}
public function handle_update_order_status () : void {
if ( ! current_user_can ( self :: CAPABILITY )) {
wp_die ( esc_html__ ( '权限不足' , 'aksrt' ));
}
$order_number = isset ( $_POST [ 'order_number' ]) ? sanitize_text_field (( string ) wp_unslash ( $_POST [ 'order_number' ])) : '' ;
$new_status = isset ( $_POST [ 'new_status' ]) ? sanitize_key (( string ) wp_unslash ( $_POST [ 'new_status' ])) : '' ;
check_admin_referer ( 'aksrt_pay_update_order_status_' . $order_number );
$ok = false ;
if ( $order_number !== '' && $new_status !== '' && class_exists ( 'AKSRT_Order_Repository' )) {
$ok = AKSRT_Order_Repository :: get_instance () -> update_status ( $order_number , $new_status , [ 'force' => true ]);
}
wp_safe_redirect ( $this -> page_url ( 'aksrt_orders' , [
'aksrt_pay_msg' => $ok ? 'order_updated' : 'order_failed' ,
]));
exit ;
}
/* ------------------------------------------------------------------
* Withdrawals
* ----------------------------------------------------------------*/
public function render_withdrawals_page () : void {
$this -> ensure_cap ();
$this -> render_header ( __ ( '提现审核' , 'aksrt' ));
if ( ! class_exists ( 'AKSRT_Withdrawal' )) {
echo '<div class="notice notice-error"><p>' . esc_html__ ( '提现模块未初始化。' , 'aksrt' ) . '</p></div>' ;
$this -> render_footer ();
return ;
}
$status = isset ( $_GET [ 'status' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'status' ])) : '' ;
$page_num = max ( 1 , ( int ) ( $_GET [ 'paged' ] ? ? 1 ));
$per_page = 20 ;
$svc = AKSRT_Withdrawal :: get_instance ();
$stats = $svc -> get_stats ();
echo '<p>' . esc_html ( sprintf (
/* translators: 1: total 2: pending 3: completed 4: paid */
__ ( '共 %1$d 条 · 待处理 %2$d · 已完成 %3$d · 已打款 %4$s' , 'aksrt' ),
( int ) ( $stats [ 'total' ] ? ? 0 ),
( int ) ( $stats [ 'pending' ] ? ? 0 ),
( int ) ( $stats [ 'completed' ] ? ? 0 ),
number_format (( float ) ( $stats [ 'total_paid' ] ? ? 0 ), 2 )
)) . '</p>' ;
echo '<form method="get" style="margin:12px 0;">' ;
echo '<input type="hidden" name="page" value="aksrt_withdraw" />' ;
echo '<select name="status">' ;
$status_options = [
'' => __ ( '全部状态' , 'aksrt' ),
'pending' => __ ( '待处理' , 'aksrt' ),
'approved' => __ ( '已通过' , 'aksrt' ),
'processing' => __ ( '处理中' , 'aksrt' ),
'completed' => __ ( '已完成' , 'aksrt' ),
'rejected' => __ ( '已拒绝' , 'aksrt' ),
];
foreach ( $status_options as $key => $label ) {
printf (
'<option value="%s"%s>%s</option>' ,
esc_attr ( $key ),
selected ( $status , $key , false ),
esc_html ( $label )
);
}
echo '</select> ' ;
submit_button ( __ ( '筛选' , 'aksrt' ), 'secondary' , '' , false );
echo '</form>' ;
$items = $svc -> get_all ([
'status' => $status ,
'limit' => $per_page ,
'offset' => ( $page_num - 1 ) * $per_page ,
]);
$total = $svc -> get_count ([ 'status' => $status ]);
$pages = max ( 1 , ( int ) ceil ( $total / $per_page ));
echo '<table class="wp-list-table widefat fixed striped">' ;
echo '<thead><tr>' ;
echo '<th>ID</th>' ;
echo '<th>' . esc_html__ ( '用户' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '金额' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '方式' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '账户' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '状态' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '申请时间' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '操作' , 'aksrt' ) . '</th>' ;
echo '</tr></thead><tbody>' ;
if ( ! $items ) {
echo '<tr><td colspan="8">' . esc_html__ ( '暂无提现记录' , 'aksrt' ) . '</td></tr>' ;
}
foreach ( $items as $row ) {
$id = ( int ) ( $row [ 'id' ] ? ? 0 );
$user_id = ( int ) ( $row [ 'user_id' ] ? ? 0 );
$user = $user_id > 0 ? get_userdata ( $user_id ) : null ;
$st = ( string ) ( $row [ 'status' ] ? ? '' );
echo '<tr>' ;
echo '<td>' . esc_html (( string ) $id ) . '</td>' ;
echo '<td>' . ( $user ? esc_html ( $user -> display_name . ' (#' . $user_id . ')' ) : esc_html (( string ) $user_id )) . '</td>' ;
echo '<td>' . esc_html ( number_format (( float ) ( $row [ 'amount' ] ? ? 0 ), 2 )) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'method' ] ? ? '' )) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'account_info' ] ? ? '' )) . '</td>' ;
echo '<td>' . esc_html ( $status_options [ $st ] ? ? $st ) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'created_at' ] ? ? '' )) . '</td>' ;
echo '<td>' ;
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '" style="display:flex;gap:4px;flex-wrap:wrap;align-items:center;">' ;
echo '<input type="hidden" name="action" value="aksrt_pay_update_withdrawal" />' ;
echo '<input type="hidden" name="withdrawal_id" value="' . esc_attr (( string ) $id ) . '" />' ;
wp_nonce_field ( 'aksrt_pay_update_withdrawal_' . $id );
echo '<select name="new_status">' ;
foreach ( $status_options as $key => $label ) {
if ( $key === '' ) {
continue ;
}
printf (
'<option value="%s"%s>%s</option>' ,
esc_attr ( $key ),
selected ( $st , $key , false ),
esc_html ( $label )
);
}
echo '</select>' ;
echo '<input type="text" name="note" placeholder="' . esc_attr__ ( '备注' , 'aksrt' ) . '" value="" />' ;
submit_button ( __ ( '更新' , 'aksrt' ), 'small' , '' , false );
echo '</form>' ;
echo '</td>' ;
echo '</tr>' ;
}
echo '</tbody></table>' ;
if ( $pages > 1 ) {
echo '<div class="tablenav"><div class="tablenav-pages">' ;
echo paginate_links ([
'base' => add_query_arg ( 'paged' , '%#%' ),
'format' => '' ,
'prev_text' => '«' ,
'next_text' => '»' ,
'total' => $pages ,
'current' => $page_num ,
]);
echo '</div></div>' ;
}
$this -> render_footer ();
}
public function handle_update_withdrawal () : void {
if ( ! current_user_can ( self :: CAPABILITY )) {
wp_die ( esc_html__ ( '权限不足' , 'aksrt' ));
}
$id = isset ( $_POST [ 'withdrawal_id' ]) ? ( int ) $_POST [ 'withdrawal_id' ] : 0 ;
$new_status = isset ( $_POST [ 'new_status' ]) ? sanitize_key (( string ) wp_unslash ( $_POST [ 'new_status' ])) : '' ;
$note = isset ( $_POST [ 'note' ]) ? sanitize_textarea_field (( string ) wp_unslash ( $_POST [ 'note' ])) : '' ;
check_admin_referer ( 'aksrt_pay_update_withdrawal_' . $id );
$ok = false ;
if ( $id > 0 && $new_status !== '' && class_exists ( 'AKSRT_Withdrawal' )) {
$ok = AKSRT_Withdrawal :: get_instance () -> update_status ( $id , $new_status , $note );
}
wp_safe_redirect ( $this -> page_url ( 'aksrt_withdraw' , [
'aksrt_pay_msg' => $ok ? 'withdraw_updated' : 'withdraw_failed' ,
]));
exit ;
}
/* ------------------------------------------------------------------
* Charge cards
* ----------------------------------------------------------------*/
public function render_charge_cards_page () : void {
$this -> ensure_cap ();
$this -> render_header ( __ ( '卡密管理' , 'aksrt' ));
if ( ! class_exists ( 'AKSRT_Charge_Card' )) {
echo '<div class="notice notice-error"><p>' . esc_html__ ( '卡密模块未初始化。' , 'aksrt' ) . '</p></div>' ;
$this -> render_footer ();
return ;
}
$status = isset ( $_GET [ 'status' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'status' ])) : '' ;
$type = isset ( $_GET [ 'type' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'type' ])) : '' ;
$page_num = max ( 1 , ( int ) ( $_GET [ 'paged' ] ? ? 1 ));
$per_page = 20 ;
$svc = AKSRT_Charge_Card :: get_instance ();
$stats = $svc -> get_stats ();
echo '<p>' . esc_html ( sprintf (
/* translators: 1: total 2: active 3: used */
__ ( '共 %1$d 张 · 可用 %2$d · 已用 %3$d' , 'aksrt' ),
( int ) ( $stats [ 'total' ] ? ? 0 ),
( int ) ( $stats [ 'active' ] ? ? 0 ),
( int ) ( $stats [ 'used' ] ? ? 0 )
)) . '</p>' ;
echo '<form method="get" style="margin:12px 0;">' ;
echo '<input type="hidden" name="page" value="aksrt_charge_cards" />' ;
echo '<select name="status">' ;
foreach ([
'' => __ ( '全部状态' , 'aksrt' ),
'active' => __ ( '可用' , 'aksrt' ),
'used' => __ ( '已用' , 'aksrt' ),
'disabled' => __ ( '已禁用' , 'aksrt' ),
] as $key => $label ) {
printf (
'<option value="%s"%s>%s</option>' ,
esc_attr ( $key ),
selected ( $status , $key , false ),
esc_html ( $label )
);
}
echo '</select> ' ;
echo '<select name="type">' ;
foreach ([
'' => __ ( '全部类型' , 'aksrt' ),
'balance' => __ ( '余额' , 'aksrt' ),
'vip' => __ ( 'VIP' , 'aksrt' ),
'points' => __ ( '积分' , 'aksrt' ),
] as $key => $label ) {
printf (
'<option value="%s"%s>%s</option>' ,
esc_attr ( $key ),
selected ( $type , $key , false ),
esc_html ( $label )
);
}
echo '</select> ' ;
submit_button ( __ ( '筛选' , 'aksrt' ), 'secondary' , '' , false );
echo ' <a class="button" href="' . esc_url ( admin_url ( 'admin.php?page=aksrt-settings#/payment/charge-card' )) . '">' . esc_html__ ( 'SPA 批量生成(过渡)' , 'aksrt' ) . '</a>' ;
echo '</form>' ;
$result = $svc -> get_list ([
'status' => $status ,
'type' => $type ,
'limit' => $per_page ,
'offset' => ( $page_num - 1 ) * $per_page ,
]);
$items = $result [ 'items' ] ? ? [];
$total = ( int ) ( $result [ 'total' ] ? ? 0 );
$pages = max ( 1 , ( int ) ( $result [ 'max_pages' ] ? ? 1 ));
echo '<table class="wp-list-table widefat fixed striped">' ;
echo '<thead><tr>' ;
echo '<th>ID</th>' ;
echo '<th>' . esc_html__ ( '类型' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '密码' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '面额' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '状态' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '使用者' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '创建时间' , 'aksrt' ) . '</th>' ;
echo '<th>' . esc_html__ ( '操作' , 'aksrt' ) . '</th>' ;
echo '</tr></thead><tbody>' ;
if ( ! $items ) {
echo '<tr><td colspan="8">' . esc_html__ ( '暂无卡密' , 'aksrt' ) . '</td></tr>' ;
}
foreach ( $items as $row ) {
$id = ( int ) ( $row [ 'id' ] ? ? 0 );
$st = ( string ) ( $row [ 'status' ] ? ? '' );
$user_id = ( int ) ( $row [ 'used_by' ] ? ? $row [ 'user_id' ] ? ? 0 );
$user = $user_id > 0 ? get_userdata ( $user_id ) : null ;
echo '<tr>' ;
echo '<td>' . esc_html (( string ) $id ) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'type' ] ? ? '' )) . '</td>' ;
echo '<td><code>' . esc_html (( string ) ( $row [ 'password' ] ? ? $row [ 'code' ] ? ? '' )) . '</code></td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'amount' ] ? ? '' )) . '</td>' ;
echo '<td>' . esc_html ( $st ) . '</td>' ;
echo '<td>' . ( $user ? esc_html ( $user -> display_name ) : '—' ) . '</td>' ;
echo '<td>' . esc_html (( string ) ( $row [ 'created_at' ] ? ? '' )) . '</td>' ;
echo '<td>' ;
if ( $st === 'active' ) {
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '">' ;
echo '<input type="hidden" name="action" value="aksrt_pay_disable_charge_card" />' ;
echo '<input type="hidden" name="card_id" value="' . esc_attr (( string ) $id ) . '" />' ;
wp_nonce_field ( 'aksrt_pay_disable_charge_card_' . $id );
submit_button ( __ ( '禁用' , 'aksrt' ), 'small' , '' , false );
echo '</form>' ;
} else {
echo '—' ;
}
echo '</td>' ;
echo '</tr>' ;
}
echo '</tbody></table>' ;
if ( $pages > 1 ) {
echo '<div class="tablenav"><div class="tablenav-pages">' ;
echo paginate_links ([
'base' => add_query_arg ( 'paged' , '%#%' ),
'format' => '' ,
'prev_text' => '«' ,
'next_text' => '»' ,
'total' => $pages ,
'current' => $page_num ,
]);
echo '</div></div>' ;
}
$this -> render_footer ();
}
public function handle_disable_charge_card () : void {
if ( ! current_user_can ( self :: CAPABILITY )) {
wp_die ( esc_html__ ( '权限不足' , 'aksrt' ));
}
$id = isset ( $_POST [ 'card_id' ]) ? ( int ) $_POST [ 'card_id' ] : 0 ;
check_admin_referer ( 'aksrt_pay_disable_charge_card_' . $id );
$ok = false ;
if ( $id > 0 && class_exists ( 'AKSRT_Charge_Card' )) {
$ok = AKSRT_Charge_Card :: get_instance () -> disable ( $id );
}
wp_safe_redirect ( $this -> page_url ( 'aksrt_charge_cards' , [
'aksrt_pay_msg' => $ok ? 'card_disabled' : 'card_failed' ,
]));
exit ;
}
}