215 lines
9.7 KiB
PHP
215 lines
9.7 KiB
PHP
<?php
|
|
/**
|
|
* 订阅列表管理页面模板
|
|
*
|
|
* @package Yoone_Subscriptions
|
|
* @version 1.0.0
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit; // 防止直接访问
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
// 获取订阅列表
|
|
$per_page = 20;
|
|
$current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
|
|
$offset = ($current_page - 1) * $per_page;
|
|
|
|
$search = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';
|
|
$status_filter = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : '';
|
|
|
|
$where_conditions = array('1=1');
|
|
$where_values = array();
|
|
|
|
if ($search) {
|
|
$where_conditions[] = "(s.id LIKE %s OR u.user_email LIKE %s OR u.display_name LIKE %s)";
|
|
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
|
|
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
|
|
$where_values[] = '%' . $wpdb->esc_like($search) . '%';
|
|
}
|
|
|
|
if ($status_filter) {
|
|
$where_conditions[] = "s.status = %s";
|
|
$where_values[] = $status_filter;
|
|
}
|
|
|
|
$where_clause = implode(' AND ', $where_conditions);
|
|
|
|
// 获取总数
|
|
$total_query = "SELECT COUNT(*) FROM {$wpdb->prefix}yoone_subscriptions s
|
|
LEFT JOIN {$wpdb->users} u ON s.user_id = u.ID
|
|
WHERE {$where_clause}";
|
|
|
|
if (!empty($where_values)) {
|
|
$total = $wpdb->get_var($wpdb->prepare($total_query, $where_values));
|
|
} else {
|
|
$total = $wpdb->get_var($total_query);
|
|
}
|
|
|
|
// 获取订阅数据
|
|
$query = "SELECT s.*, u.user_email, u.display_name, p.post_title as product_name
|
|
FROM {$wpdb->prefix}yoone_subscriptions s
|
|
LEFT JOIN {$wpdb->users} u ON s.user_id = u.ID
|
|
LEFT JOIN {$wpdb->posts} p ON s.product_id = p.ID
|
|
WHERE {$where_clause}
|
|
ORDER BY s.created_at DESC
|
|
LIMIT %d OFFSET %d";
|
|
|
|
$query_values = array_merge($where_values, array($per_page, $offset));
|
|
$subscriptions = $wpdb->get_results($wpdb->prepare($query, $query_values));
|
|
|
|
$total_pages = ceil($total / $per_page);
|
|
|
|
// 获取状态统计
|
|
$status_counts = $wpdb->get_results(
|
|
"SELECT status, COUNT(*) as count FROM {$wpdb->prefix}yoone_subscriptions GROUP BY status"
|
|
);
|
|
?>
|
|
|
|
<div class="wrap">
|
|
<h1 class="wp-heading-inline"><?php _e('订阅管理', 'yoone-subscriptions'); ?></h1>
|
|
|
|
<!-- 搜索和筛选 -->
|
|
<form method="get" class="search-form">
|
|
<input type="hidden" name="page" value="yoone-subscriptions">
|
|
|
|
<p class="search-box">
|
|
<label class="screen-reader-text" for="subscription-search-input"><?php _e('搜索订阅', 'yoone-subscriptions'); ?>:</label>
|
|
<input type="search" id="subscription-search-input" name="s" value="<?php echo esc_attr($search); ?>" placeholder="<?php _e('搜索订阅ID、用户邮箱或姓名', 'yoone-subscriptions'); ?>">
|
|
|
|
<select name="status">
|
|
<option value=""><?php _e('所有状态', 'yoone-subscriptions'); ?></option>
|
|
<option value="active" <?php selected($status_filter, 'active'); ?>><?php _e('活跃', 'yoone-subscriptions'); ?></option>
|
|
<option value="paused" <?php selected($status_filter, 'paused'); ?>><?php _e('暂停', 'yoone-subscriptions'); ?></option>
|
|
<option value="cancelled" <?php selected($status_filter, 'cancelled'); ?>><?php _e('已取消', 'yoone-subscriptions'); ?></option>
|
|
<option value="expired" <?php selected($status_filter, 'expired'); ?>><?php _e('已过期', 'yoone-subscriptions'); ?></option>
|
|
</select>
|
|
|
|
<?php submit_button(__('搜索', 'yoone-subscriptions'), '', '', false, array('id' => 'search-submit')); ?>
|
|
</p>
|
|
</form>
|
|
|
|
<!-- 状态统计 -->
|
|
<ul class="subsubsub">
|
|
<li class="all">
|
|
<a href="<?php echo admin_url('admin.php?page=yoone-subscriptions'); ?>" <?php echo empty($status_filter) ? 'class="current"' : ''; ?>>
|
|
<?php _e('全部', 'yoone-subscriptions'); ?> <span class="count">(<?php echo $total; ?>)</span>
|
|
</a>
|
|
</li>
|
|
<?php foreach ($status_counts as $status_count): ?>
|
|
<li class="<?php echo esc_attr($status_count->status); ?>">
|
|
| <a href="<?php echo admin_url('admin.php?page=yoone-subscriptions&status=' . $status_count->status); ?>" <?php echo $status_filter === $status_count->status ? 'class="current"' : ''; ?>>
|
|
<?php echo Yoone_Frontend::get_subscription_status_label($status_count->status); ?> <span class="count">(<?php echo $status_count->count; ?>)</span>
|
|
</a>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
|
|
<!-- 订阅列表表格 -->
|
|
<table class="wp-list-table widefat fixed striped">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="manage-column column-id"><?php _e('ID', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-user"><?php _e('用户', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-product"><?php _e('产品', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-status"><?php _e('状态', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-billing"><?php _e('计费周期', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-next-payment"><?php _e('下次付款', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-created"><?php _e('创建时间', 'yoone-subscriptions'); ?></th>
|
|
<th scope="col" class="manage-column column-actions"><?php _e('操作', 'yoone-subscriptions'); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($subscriptions)): ?>
|
|
<tr class="no-items">
|
|
<td class="colspanchange" colspan="8"><?php _e('未找到订阅', 'yoone-subscriptions'); ?></td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($subscriptions as $subscription): ?>
|
|
<tr>
|
|
<td class="column-id">
|
|
<strong>#<?php echo $subscription->id; ?></strong>
|
|
</td>
|
|
<td class="column-user">
|
|
<?php if ($subscription->user_id): ?>
|
|
<a href="<?php echo admin_url('user-edit.php?user_id=' . $subscription->user_id); ?>">
|
|
<?php echo esc_html($subscription->display_name ?: $subscription->user_email); ?>
|
|
</a>
|
|
<br><small><?php echo esc_html($subscription->user_email); ?></small>
|
|
<?php else: ?>
|
|
<em><?php _e('访客用户', 'yoone-subscriptions'); ?></em>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="column-product">
|
|
<?php if ($subscription->product_id): ?>
|
|
<a href="<?php echo admin_url('post.php?post=' . $subscription->product_id . '&action=edit'); ?>">
|
|
<?php echo esc_html($subscription->product_name ?: __('未知产品', 'yoone-subscriptions')); ?>
|
|
</a>
|
|
<?php else: ?>
|
|
<em><?php _e('产品已删除', 'yoone-subscriptions'); ?></em>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="column-status">
|
|
<span class="subscription-status status-<?php echo esc_attr($subscription->status); ?>">
|
|
<?php echo Yoone_Frontend::get_subscription_status_label($subscription->status); ?>
|
|
</span>
|
|
</td>
|
|
<td class="column-billing">
|
|
<?php echo Yoone_Helper::format_billing_period($subscription->billing_period, $subscription->billing_interval); ?>
|
|
</td>
|
|
<td class="column-next-payment">
|
|
<?php if ($subscription->next_payment_date && $subscription->status === 'active'): ?>
|
|
<?php echo date_i18n(get_option('date_format'), strtotime($subscription->next_payment_date)); ?>
|
|
<?php else: ?>
|
|
<em><?php _e('无', 'yoone-subscriptions'); ?></em>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="column-created">
|
|
<?php echo date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($subscription->created_at)); ?>
|
|
</td>
|
|
<td class="column-actions">
|
|
<a href="<?php echo admin_url('admin.php?page=yoone-subscriptions&action=edit&id=' . $subscription->id); ?>" class="button button-small">
|
|
<?php _e('编辑', 'yoone-subscriptions'); ?>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
|
|
<!-- 分页 -->
|
|
<?php if ($total_pages > 1): ?>
|
|
<div class="tablenav bottom">
|
|
<div class="tablenav-pages">
|
|
<?php
|
|
$pagination_args = array(
|
|
'base' => add_query_arg('paged', '%#%'),
|
|
'format' => '',
|
|
'prev_text' => __('«'),
|
|
'next_text' => __('»'),
|
|
'total' => $total_pages,
|
|
'current' => $current_page
|
|
);
|
|
echo paginate_links($pagination_args);
|
|
?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<style>
|
|
.subscription-status {
|
|
padding: 3px 8px;
|
|
border-radius: 3px;
|
|
font-size: 11px;
|
|
font-weight: bold;
|
|
text-transform: uppercase;
|
|
}
|
|
.status-active { background: #46b450; color: white; }
|
|
.status-paused { background: #ffb900; color: white; }
|
|
.status-cancelled { background: #dc3232; color: white; }
|
|
.status-expired { background: #666; color: white; }
|
|
</style>
|