subscription/includes/admin/class-yoone-bundles-list-ta...

389 lines
13 KiB
PHP

<?php
/**
* 混装产品列表表格类
*
* 处理后台混装产品列表显示
*/
if (!defined('ABSPATH')) {
exit;
}
if (!class_exists('WP_List_Table')) {
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
/**
* 混装产品列表表格类
*/
class Yoone_Bundles_List_Table extends WP_List_Table {
/**
* 构造函数
*/
public function __construct() {
parent::__construct(array(
'singular' => 'bundle',
'plural' => 'bundles',
'ajax' => false,
));
}
/**
* 获取列
*/
public function get_columns() {
return array(
'cb' => '<input type="checkbox" />',
'id' => __('ID', 'yoone-subscriptions'),
'name' => __('名称', 'yoone-subscriptions'),
'status' => __('状态', 'yoone-subscriptions'),
'discount_type' => __('折扣类型', 'yoone-subscriptions'),
'discount_value'=> __('折扣值', 'yoone-subscriptions'),
'min_quantity' => __('最小数量', 'yoone-subscriptions'),
'max_quantity' => __('最大数量', 'yoone-subscriptions'),
'items_count' => __('产品数量', 'yoone-subscriptions'),
'created_date' => __('创建日期', 'yoone-subscriptions'),
'actions' => __('操作', 'yoone-subscriptions'),
);
}
/**
* 获取可排序列
*/
public function get_sortable_columns() {
return array(
'id' => array('id', false),
'name' => array('name', false),
'status' => array('status', false),
'discount_value'=> array('discount_value', false),
'created_date' => array('created_at', false),
);
}
/**
* 获取批量操作
*/
public function get_bulk_actions() {
return array(
'activate' => __('激活', 'yoone-subscriptions'),
'deactivate' => __('停用', '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[] = "(b.name LIKE %s OR b.description LIKE %s)";
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
}
if (!empty($status_filter)) {
$where_conditions[] = "b.status = %s";
$where_values[] = $status_filter;
}
$where_clause = implode(' AND ', $where_conditions);
// 排序
$allowed_orderby = array('id', 'name', 'status', 'discount_value', '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_bundles b
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 b.*,
COUNT(bi.id) as items_count
FROM {$wpdb->prefix}yoone_bundles b
LEFT JOIN {$wpdb->prefix}yoone_bundle_items bi ON b.id = bi.bundle_id
WHERE {$where_clause}
GROUP BY b.id
ORDER BY b.{$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 'name':
$edit_url = admin_url('admin.php?page=yoone-bundles&action=edit&id=' . $item->id);
return '<a href="' . $edit_url . '"><strong>' . esc_html($item->name) . '</strong></a>';
case 'status':
return $this->get_status_badge($item->status);
case 'discount_type':
$types = array(
'percentage' => __('百分比', 'yoone-subscriptions'),
'fixed' => __('固定金额', 'yoone-subscriptions'),
);
return isset($types[$item->discount_type]) ? $types[$item->discount_type] : $item->discount_type;
case 'discount_value':
if ($item->discount_type === 'percentage') {
return $item->discount_value . '%';
} else {
return wc_price($item->discount_value);
}
case 'min_quantity':
return $item->min_quantity ?: '-';
case 'max_quantity':
return $item->max_quantity ?: '-';
case 'items_count':
return $item->items_count;
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('<input type="checkbox" name="bundle[]" value="%s" />', $item->id);
}
/**
* 获取状态徽章
*/
private function get_status_badge($status) {
$statuses = array(
'active' => array('label' => __('活跃', 'yoone-subscriptions'), 'color' => 'green'),
'inactive' => array('label' => __('停用', 'yoone-subscriptions'), 'color' => 'red'),
'draft' => array('label' => __('草稿', 'yoone-subscriptions'), 'color' => 'gray'),
);
$status_info = isset($statuses[$status]) ? $statuses[$status] : array('label' => $status, 'color' => 'gray');
return sprintf(
'<span class="yoone-status-badge yoone-status-%s" style="background-color: %s; color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px;">%s</span>',
$status,
$status_info['color'],
$status_info['label']
);
}
/**
* 获取行操作
*/
private function get_row_actions($item) {
$actions = array();
$edit_url = admin_url('admin.php?page=yoone-bundles&action=edit&id=' . $item->id);
$actions['edit'] = '<a href="' . $edit_url . '">' . __('编辑', 'yoone-subscriptions') . '</a>';
if ($item->status === 'active') {
$deactivate_url = wp_nonce_url(
admin_url('admin.php?page=yoone-bundles&action=deactivate&id=' . $item->id),
'deactivate_bundle_' . $item->id
);
$actions['deactivate'] = '<a href="' . $deactivate_url . '">' . __('停用', 'yoone-subscriptions') . '</a>';
} else {
$activate_url = wp_nonce_url(
admin_url('admin.php?page=yoone-bundles&action=activate&id=' . $item->id),
'activate_bundle_' . $item->id
);
$actions['activate'] = '<a href="' . $activate_url . '">' . __('激活', 'yoone-subscriptions') . '</a>';
}
$duplicate_url = wp_nonce_url(
admin_url('admin.php?page=yoone-bundles&action=duplicate&id=' . $item->id),
'duplicate_bundle_' . $item->id
);
$actions['duplicate'] = '<a href="' . $duplicate_url . '">' . __('复制', 'yoone-subscriptions') . '</a>';
$delete_url = wp_nonce_url(
admin_url('admin.php?page=yoone-bundles&action=delete&id=' . $item->id),
'delete_bundle_' . $item->id
);
$actions['delete'] = '<a href="' . $delete_url . '" style="color: red;" onclick="return confirm(\'' . __('确定要删除这个混装产品吗?', 'yoone-subscriptions') . '\')">' . __('删除', 'yoone-subscriptions') . '</a>';
return implode(' | ', $actions);
}
/**
* 显示状态过滤器
*/
protected function get_views() {
global $wpdb;
$status_counts = $wpdb->get_results("
SELECT status, COUNT(*) as count
FROM {$wpdb->prefix}yoone_bundles
GROUP BY status
", ARRAY_A);
$total_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}yoone_bundles");
$views = array();
$current_status = isset($_REQUEST['status']) ? $_REQUEST['status'] : '';
// 全部
$class = empty($current_status) ? 'current' : '';
$views['all'] = sprintf(
'<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
admin_url('admin.php?page=yoone-bundles'),
$class,
__('全部', 'yoone-subscriptions'),
$total_count
);
// 各状态
$status_labels = array(
'active' => __('活跃', 'yoone-subscriptions'),
'inactive' => __('停用', 'yoone-subscriptions'),
'draft' => __('草稿', '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(
'<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
admin_url('admin.php?page=yoone-bundles&status=' . $status),
$class,
$status_labels[$status],
$count
);
}
}
return $views;
}
/**
* 处理批量操作
*/
public function process_bulk_action() {
$action = $this->current_action();
if (!$action) {
return;
}
$bundle_ids = isset($_REQUEST['bundle']) ? array_map('intval', $_REQUEST['bundle']) : array();
if (empty($bundle_ids)) {
return;
}
foreach ($bundle_ids as $bundle_id) {
$bundle = new Yoone_Bundle($bundle_id);
if (!$bundle->get_id()) {
continue;
}
switch ($action) {
case 'activate':
$bundle->set_status('active');
$bundle->save();
break;
case 'deactivate':
$bundle->set_status('inactive');
$bundle->save();
break;
case 'delete':
$bundle->delete();
break;
}
}
wp_redirect(admin_url('admin.php?page=yoone-bundles&bulk_action=' . $action . '&processed=' . count($bundle_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'),
'deactivate' => __('已停用 %d 个混装产品', 'yoone-subscriptions'),
'delete' => __('已删除 %d 个混装产品', 'yoone-subscriptions'),
);
if (isset($messages[$action])) {
echo '<div class="notice notice-success is-dismissible">';
echo '<p>' . sprintf($messages[$action], $processed) . '</p>';
echo '</div>';
}
}
}
}