'subscription', 'plural' => 'subscriptions', 'ajax' => false, )); } /** * 获取列 */ public function get_columns() { return array( 'cb' => '', 'id' => __('ID', 'yoone-subscriptions'), 'customer' => __('客户', 'yoone-subscriptions'), 'status' => __('状态', 'yoone-subscriptions'), 'total' => __('金额', 'yoone-subscriptions'), 'billing_period' => __('计费周期', 'yoone-subscriptions'), 'next_payment' => __('下次付款', 'yoone-subscriptions'), 'created_date' => __('创建日期', 'yoone-subscriptions'), 'actions' => __('操作', 'yoone-subscriptions'), ); } /** * 获取可排序列 */ public function get_sortable_columns() { return array( 'id' => array('id', false), 'status' => array('status', false), 'total' => array('total', false), 'next_payment' => array('next_payment_date', false), 'created_date' => array('created_at', false), ); } /** * 获取批量操作 */ public function get_bulk_actions() { return array( 'activate' => __('激活', 'yoone-subscriptions'), 'pause' => __('暂停', 'yoone-subscriptions'), 'cancel' => __('取消', 'yoone-subscriptions'), 'delete' => __('删除', 'yoone-subscriptions'), ); } /** * 准备项目 */ public function prepare_items() { global $wpdb; $per_page = 20; $current_page = $this->get_pagenum(); // 处理搜索 $search = isset($_REQUEST['s']) ? sanitize_text_field($_REQUEST['s']) : ''; // 处理状态过滤 $status_filter = isset($_REQUEST['status']) ? sanitize_text_field($_REQUEST['status']) : ''; // 构建查询 $where_conditions = array('1=1'); $where_values = array(); if (!empty($search)) { $where_conditions[] = "(s.id LIKE %s OR u.display_name LIKE %s OR u.user_email LIKE %s)"; $where_values[] = '%' . $wpdb->esc_like($search) . '%'; $where_values[] = '%' . $wpdb->esc_like($search) . '%'; $where_values[] = '%' . $wpdb->esc_like($search) . '%'; } if (!empty($status_filter)) { $where_conditions[] = "s.status = %s"; $where_values[] = $status_filter; } $where_clause = implode(' AND ', $where_conditions); // 排序 $allowed_orderby = array('id', 'status', 'total', 'next_payment_date', 'created_at'); $orderby = isset($_REQUEST['orderby']) && in_array($_REQUEST['orderby'], $allowed_orderby) ? $_REQUEST['orderby'] : 'id'; $order = isset($_REQUEST['order']) && $_REQUEST['order'] === 'asc' ? 'ASC' : 'DESC'; // 获取总数 $total_query = " SELECT COUNT(*) FROM {$wpdb->prefix}yoone_subscriptions s LEFT JOIN {$wpdb->users} u ON s.customer_id = u.ID WHERE {$where_clause} "; if (!empty($where_values)) { $total_items = $wpdb->get_var($wpdb->prepare($total_query, $where_values)); } else { $total_items = $wpdb->get_var($total_query); } // 获取数据 $offset = ($current_page - 1) * $per_page; $items_query = " SELECT s.*, u.display_name, u.user_email FROM {$wpdb->prefix}yoone_subscriptions s LEFT JOIN {$wpdb->users} u ON s.customer_id = u.ID WHERE {$where_clause} ORDER BY s.{$orderby} {$order} LIMIT %d OFFSET %d "; $query_values = array_merge($where_values, array($per_page, $offset)); $this->items = $wpdb->get_results($wpdb->prepare($items_query, $query_values)); // 设置分页 $this->set_pagination_args(array( 'total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page), )); $this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns(), ); } /** * 默认列显示 */ public function column_default($item, $column_name) { switch ($column_name) { case 'id': return '#' . $item->id; case 'customer': $customer_link = admin_url('user-edit.php?user_id=' . $item->customer_id); return '' . $item->display_name . '
' . $item->user_email . ''; case 'status': return $this->get_status_badge($item->status); case 'total': return wc_price($item->total); case 'billing_period': return $this->format_billing_period($item->billing_period, $item->billing_interval); case 'next_payment': if ($item->next_payment_date && $item->status === 'active') { $date = new DateTime($item->next_payment_date); return $date->format('Y-m-d H:i'); } return '-'; case 'created_date': $date = new DateTime($item->created_at); return $date->format('Y-m-d H:i'); case 'actions': return $this->get_row_actions($item); default: return isset($item->$column_name) ? $item->$column_name : ''; } } /** * 复选框列 */ public function column_cb($item) { return sprintf('', $item->id); } /** * 获取状态徽章 */ private function get_status_badge($status) { $statuses = array( 'active' => array('label' => __('活跃', 'yoone-subscriptions'), 'color' => 'green'), 'paused' => array('label' => __('暂停', 'yoone-subscriptions'), 'color' => 'orange'), 'cancelled' => array('label' => __('已取消', 'yoone-subscriptions'), 'color' => 'red'), 'expired' => array('label' => __('已过期', 'yoone-subscriptions'), 'color' => 'gray'), 'pending' => array('label' => __('待处理', 'yoone-subscriptions'), 'color' => 'blue'), ); $status_info = isset($statuses[$status]) ? $statuses[$status] : array('label' => $status, 'color' => 'gray'); return sprintf( '%s', $status, $status_info['color'], $status_info['label'] ); } /** * 格式化计费周期 */ private function format_billing_period($period, $interval) { $periods = array( 'day' => __('天', 'yoone-subscriptions'), 'week' => __('周', 'yoone-subscriptions'), 'month' => __('月', 'yoone-subscriptions'), 'year' => __('年', 'yoone-subscriptions'), ); $period_name = isset($periods[$period]) ? $periods[$period] : $period; if ($interval > 1) { return sprintf(__('每 %d %s', 'yoone-subscriptions'), $interval, $period_name); } else { return sprintf(__('每%s', 'yoone-subscriptions'), $period_name); } } /** * 获取行操作 */ private function get_row_actions($item) { $actions = array(); $edit_url = admin_url('admin.php?page=yoone-subscriptions&action=edit&id=' . $item->id); $actions['edit'] = '' . __('编辑', 'yoone-subscriptions') . ''; if ($item->status === 'active') { $pause_url = wp_nonce_url( admin_url('admin.php?page=yoone-subscriptions&action=pause&id=' . $item->id), 'pause_subscription_' . $item->id ); $actions['pause'] = '' . __('暂停', 'yoone-subscriptions') . ''; } if ($item->status === 'paused') { $resume_url = wp_nonce_url( admin_url('admin.php?page=yoone-subscriptions&action=resume&id=' . $item->id), 'resume_subscription_' . $item->id ); $actions['resume'] = '' . __('恢复', 'yoone-subscriptions') . ''; } if (in_array($item->status, array('active', 'paused'))) { $cancel_url = wp_nonce_url( admin_url('admin.php?page=yoone-subscriptions&action=cancel&id=' . $item->id), 'cancel_subscription_' . $item->id ); $actions['cancel'] = '' . __('取消', 'yoone-subscriptions') . ''; } $delete_url = wp_nonce_url( admin_url('admin.php?page=yoone-subscriptions&action=delete&id=' . $item->id), 'delete_subscription_' . $item->id ); $actions['delete'] = '' . __('删除', 'yoone-subscriptions') . ''; return implode(' | ', $actions); } /** * 显示状态过滤器 */ protected function get_views() { global $wpdb; $status_counts = $wpdb->get_results(" SELECT status, COUNT(*) as count FROM {$wpdb->prefix}yoone_subscriptions GROUP BY status ", ARRAY_A); $total_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}yoone_subscriptions"); $views = array(); $current_status = isset($_REQUEST['status']) ? $_REQUEST['status'] : ''; // 全部 $class = empty($current_status) ? 'current' : ''; $views['all'] = sprintf( '%s (%d)', admin_url('admin.php?page=yoone-subscriptions'), $class, __('全部', 'yoone-subscriptions'), $total_count ); // 各状态 $status_labels = array( 'active' => __('活跃', 'yoone-subscriptions'), 'paused' => __('暂停', 'yoone-subscriptions'), 'cancelled' => __('已取消', 'yoone-subscriptions'), 'expired' => __('已过期', 'yoone-subscriptions'), 'pending' => __('待处理', 'yoone-subscriptions'), ); foreach ($status_counts as $status_data) { $status = $status_data['status']; $count = $status_data['count']; if (isset($status_labels[$status])) { $class = $current_status === $status ? 'current' : ''; $views[$status] = sprintf( '%s (%d)', admin_url('admin.php?page=yoone-subscriptions&status=' . $status), $class, $status_labels[$status], $count ); } } return $views; } /** * 处理批量操作 */ public function process_bulk_action() { $action = $this->current_action(); if (!$action) { return; } $subscription_ids = isset($_REQUEST['subscription']) ? array_map('intval', $_REQUEST['subscription']) : array(); if (empty($subscription_ids)) { return; } foreach ($subscription_ids as $subscription_id) { $subscription = new Yoone_Subscription($subscription_id); if (!$subscription->get_id()) { continue; } switch ($action) { case 'activate': $subscription->activate(); break; case 'pause': $subscription->pause(); break; case 'cancel': $subscription->cancel(); break; case 'delete': $subscription->delete(); break; } } wp_redirect(admin_url('admin.php?page=yoone-subscriptions&bulk_action=' . $action . '&processed=' . count($subscription_ids))); exit; } /** * 显示批量操作通知 */ public function admin_notices() { if (isset($_GET['bulk_action']) && isset($_GET['processed'])) { $action = sanitize_text_field($_GET['bulk_action']); $processed = intval($_GET['processed']); $messages = array( 'activate' => __('已激活 %d 个订阅', 'yoone-subscriptions'), 'pause' => __('已暂停 %d 个订阅', 'yoone-subscriptions'), 'cancel' => __('已取消 %d 个订阅', 'yoone-subscriptions'), 'delete' => __('已删除 %d 个订阅', 'yoone-subscriptions'), ); if (isset($messages[$action])) { echo '
'; echo '

' . sprintf($messages[$action], $processed) . '

'; echo '
'; } } } }