diff --git a/functions.php b/functions.php index e5e06080..56694bc9 100644 --- a/functions.php +++ b/functions.php @@ -315,6 +315,11 @@ if (is_admin() && class_exists('AKSRT_Topic_Admin_List')) { if (is_admin() && class_exists('AKSRT_Topic_Meta_Box')) { AKSRT_Topic_Meta_Box::get_instance()->init(); } +// 论坛版块列表列 +if (is_admin() && class_exists('AKSRT_Plate_Admin_List')) { + AKSRT_Plate_Admin_List::get_instance()->init(); +} + diff --git a/inc/bootstrap.php b/inc/bootstrap.php index 21fcc75a..accb5d0f 100644 --- a/inc/bootstrap.php +++ b/inc/bootstrap.php @@ -325,6 +325,7 @@ require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-variants-meta-bo require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-plate-meta-box.php'; require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-topic-admin-list.php'; require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-topic-meta-box.php'; +require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-plate-admin-list.php'; require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-1.php'; require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-2.php'; require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-3.php'; diff --git a/inc/classes/admin/native/class-aksrt-admin-pay-menus.php b/inc/classes/admin/native/class-aksrt-admin-pay-menus.php index a49e4336..34f523b9 100644 --- a/inc/classes/admin/native/class-aksrt-admin-pay-menus.php +++ b/inc/classes/admin/native/class-aksrt-admin-pay-menus.php @@ -35,7 +35,9 @@ class AKSRT_Admin_Pay_Menus { add_action('admin_post_aksrt_pay_disable_charge_card', [$this, 'handle_disable_charge_card']); add_action('admin_post_aksrt_pay_batch_charge_cards', [$this, 'handle_batch_charge_cards']); add_action('admin_post_aksrt_pay_update_shipping', [$this, 'handle_update_shipping']); + add_action('admin_post_aksrt_pay_create_shipping', [$this, 'handle_create_shipping']); add_action('admin_post_aksrt_pay_update_after_sale', [$this, 'handle_update_after_sale']); + add_action('admin_post_aksrt_pay_create_after_sale', [$this, 'handle_create_after_sale']); add_action('admin_post_aksrt_pay_create_coupon', [$this, 'handle_create_coupon']); add_action('admin_post_aksrt_pay_disable_coupon', [$this, 'handle_disable_coupon']); add_action('admin_post_aksrt_pay_settle_income', [$this, 'handle_settle_income']); @@ -202,8 +204,12 @@ class AKSRT_Admin_Pay_Menus { 'card_batch_failed' => __('卡密批量生成失败。', 'aksrt'), 'shipping_updated' => __('物流状态已更新。', 'aksrt'), 'shipping_failed' => __('物流状态更新失败。', 'aksrt'), + 'shipping_created' => __('发货记录已创建。', 'aksrt'), + 'shipping_create_failed' => __('发货记录创建失败。', 'aksrt'), 'after_sale_updated' => __('售后状态已更新。', 'aksrt'), 'after_sale_failed' => __('售后状态更新失败。', 'aksrt'), + 'after_sale_created' => __('售后工单已创建。', 'aksrt'), + 'after_sale_create_failed' => __('售后工单创建失败。', 'aksrt'), 'coupon_created' => __('优惠码已创建。', 'aksrt'), 'coupon_create_failed'=> __('优惠码创建失败(可能重复)。', 'aksrt'), 'coupon_disabled' => __('优惠码已禁用。', 'aksrt'), @@ -463,8 +469,18 @@ class AKSRT_Admin_Pay_Menus { echo ''; echo '

' . esc_html__('物流记录', 'aksrt') . '

'; + echo '
'; + echo ''; + echo ''; + wp_nonce_field('aksrt_pay_create_shipping_' . $order_number); + echo '

'; + echo '

'; + echo '

'; + submit_button(__('创建发货', 'aksrt'), 'secondary', '', false); + echo ' ' . esc_html__('物流管理', 'aksrt') . ''; + echo '
'; if (!$shipping_items) { - echo '

' . esc_html__('暂无物流记录。', 'aksrt') . ' ' . esc_html__('去物流管理', 'aksrt') . '

'; + echo '

' . esc_html__('暂无物流记录。', 'aksrt') . '

'; } else { echo ''; foreach ($shipping_items as $item) { @@ -480,8 +496,29 @@ class AKSRT_Admin_Pay_Menus { } echo '

' . esc_html__('售后工单', 'aksrt') . '

'; + echo ''; + echo ''; + echo ''; + echo ''; + wp_nonce_field('aksrt_pay_create_after_sale_' . $order_number); + echo '

'; + echo '

'; + echo '

'; + echo '

'; + submit_button(__('创建售后', 'aksrt'), 'secondary', '', false); + echo ' ' . esc_html__('售后管理', 'aksrt') . ''; + echo ''; if (!$after_sale) { - echo '

' . esc_html__('暂无售后工单。', 'aksrt') . ' ' . esc_html__('去售后管理', 'aksrt') . '

'; + echo '

' . esc_html__('暂无售后工单。', 'aksrt') . '

'; } else { echo '
ID' . esc_html__('承运商', 'aksrt') . '' . esc_html__('运单号', 'aksrt') . '' . esc_html__('状态', 'aksrt') . '' . esc_html__('时间', 'aksrt') . '
'; foreach ($after_sale as $item) { @@ -1019,6 +1056,64 @@ class AKSRT_Admin_Pay_Menus { exit; } + public function handle_create_shipping(): 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'])) : ''; + check_admin_referer('aksrt_pay_create_shipping_' . $order_number); + + $ok = false; + if ($order_number !== '' && class_exists('AKSRT_Shipping')) { + $id = AKSRT_Shipping::get_instance()->create([ + 'order_number' => $order_number, + 'carrier' => sanitize_text_field((string) wp_unslash($_POST['carrier'] ?? '')), + 'tracking_no' => sanitize_text_field((string) wp_unslash($_POST['tracking_no'] ?? '')), + 'note' => sanitize_textarea_field((string) wp_unslash($_POST['note'] ?? '')), + 'operator_id' => get_current_user_id(), + ]); + $ok = $id > 0; + } + + wp_safe_redirect($this->page_url('aksrt_orders', [ + 'order' => $order_number, + 'aksrt_pay_msg' => $ok ? 'shipping_created' : 'shipping_create_failed', + ])); + exit; + } + + public function handle_create_after_sale(): 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'])) : ''; + check_admin_referer('aksrt_pay_create_after_sale_' . $order_number); + + $ok = false; + if ($order_number !== '' && class_exists('AKSRT_After_Sale')) { + $user_id = isset($_POST['user_id']) ? (int) $_POST['user_id'] : 0; + if ($user_id <= 0 && class_exists('AKSRT_Order_Repository')) { + $order = AKSRT_Order_Repository::get_instance()->get($order_number); + $user_id = (int) ($order['user_id'] ?? 0); + } + $id = AKSRT_After_Sale::get_instance()->create([ + 'order_number' => $order_number, + 'user_id' => $user_id, + 'type' => sanitize_key((string) wp_unslash($_POST['type'] ?? 'refund')), + 'reason' => sanitize_textarea_field((string) wp_unslash($_POST['reason'] ?? '')), + 'amount' => (float) ($_POST['amount'] ?? 0), + 'note' => sanitize_textarea_field((string) wp_unslash($_POST['note'] ?? '')), + ]); + $ok = $id > 0; + } + + wp_safe_redirect($this->page_url('aksrt_orders', [ + 'order' => $order_number, + 'aksrt_pay_msg' => $ok ? 'after_sale_created' : 'after_sale_create_failed', + ])); + exit; + } + /* ------------------------------------------------------------------ * After-sale * ----------------------------------------------------------------*/ diff --git a/inc/classes/forum/class-aksrt-plate-admin-list.php b/inc/classes/forum/class-aksrt-plate-admin-list.php new file mode 100644 index 00000000..5ef7cb95 --- /dev/null +++ b/inc/classes/forum/class-aksrt-plate-admin-list.php @@ -0,0 +1,107 @@ + $label) { + $new[$key] = $label; + if ($key === 'title') { + $new['aksrt_plate_mods'] = __('版主数', 'aksrt'); + $new['aksrt_plate_posts'] = __('帖子数', 'aksrt'); + $new['aksrt_plate_reply'] = __('回复数', 'aksrt'); + $new['aksrt_plate_views'] = __('浏览', 'aksrt'); + $new['aksrt_plate_follow'] = __('关注', 'aksrt'); + $new['aksrt_plate_pending_apps'] = __('待审申请', 'aksrt'); + } + } + return $new; + } + + public function sortable_columns(array $columns): array { + $columns['aksrt_plate_posts'] = 'aksrt_posts_count'; + $columns['aksrt_plate_views'] = 'aksrt_plate_views'; + return $columns; + } + + public function render_column(string $column, int $post_id): void { + switch ($column) { + case 'aksrt_plate_mods': + $mods = get_post_meta($post_id, '_aksrt_moderators', true); + $count = is_array($mods) ? count(array_filter(array_map('intval', $mods))) : 0; + echo esc_html((string) $count); + break; + case 'aksrt_plate_posts': + echo esc_html((string) (int) get_post_meta($post_id, '_aksrt_posts_count', true)); + break; + case 'aksrt_plate_reply': + echo esc_html((string) (int) get_post_meta($post_id, '_aksrt_reply_count', true)); + break; + case 'aksrt_plate_views': + echo esc_html((string) (int) get_post_meta($post_id, '_aksrt_plate_views', true)); + break; + case 'aksrt_plate_follow': + echo esc_html((string) (int) get_post_meta($post_id, '_aksrt_follow_count', true)); + break; + case 'aksrt_plate_pending_apps': + $apps = get_post_meta($post_id, '_aksrt_moderator_applications', true); + $pending = 0; + if (is_array($apps)) { + foreach ($apps as $app) { + if (is_array($app) && (($app['status'] ?? '') === 'pending')) { + $pending++; + } + } + } + if ($pending > 0) { + echo '' . esc_html((string) $pending) . ''; + } else { + echo '0'; + } + break; + } + } + + public function apply_orderby(WP_Query $query): void { + if (!is_admin() || !$query->is_main_query()) { + return; + } + if ($query->get('post_type') !== 'aksrt_forum_plate') { + return; + } + $orderby = $query->get('orderby'); + if ($orderby === 'aksrt_posts_count') { + $query->set('meta_key', '_aksrt_posts_count'); + $query->set('orderby', 'meta_value_num'); + } elseif ($orderby === 'aksrt_plate_views') { + $query->set('meta_key', '_aksrt_plate_views'); + $query->set('orderby', 'meta_value_num'); + } + } +}
ID' . esc_html__('类型', 'aksrt') . '' . esc_html__('状态', 'aksrt') . '' . esc_html__('时间', 'aksrt') . '