__('全部', 'aksrt'), 'href' => $this->page_url],
];
if ($s === '') {
$sub_but[] = ['name' => __('未使用', 'aksrt'), 'href' => add_query_arg('status', '0', $this->page_url)];
$sub_but[] = ['name' => __('已使用', 'aksrt'), 'href' => add_query_arg('status', 'used', $this->page_url)];
foreach ($this->type_labels() as $_k => $_v) {
$sub_but[] = ['name' => $_v, 'href' => add_query_arg('type', $_k, $this->page_url)];
}
}
$but_html = '';
foreach ($sub_but as $but) {
$but_html .= '
' . esc_html($but['name']) . ' | ';
}
$but_html = substr($but_html, 0, -2);
$search = '';
// 当前筛选参数(不含 paged)。分页链接显式带上它,不再依赖 add_query_arg()
// 默认取 $_SERVER['REQUEST_URI'](链接会随环境漂移,且列条件容易丢)。
$query_args = $this->list_query_args($status, $type, $other, $s, $orderby, $order, $per_page);
echo '';
$filters = [
'status' => $status,
'type' => $type,
'other' => $other,
'search' => $s,
'orderby' => $orderby,
'order' => $order,
];
$result = $svc->get_list($filters + ['limit' => $per_page, 'offset' => ($paged - 1) * $per_page]);
$items = (array) ($result['items'] ?? []);
$count_all = (int) ($result['total'] ?? 0);
// 页码越界(手工改 URL、或筛选后总数变小)会让 offset 落到数据之外,
// 表现为「空白表格 + 一个分页控件都没有」的死胡同,只能靠手改 URL 退出。
// 这里回退到最后一页重查一次,保证越界页码也能拿到数据与分页条。
$max_page = max(1, (int) ($result['max_pages'] ?? 1));
if (!$items && $count_all > 0 && $paged > $max_page) {
$paged = $max_page;
$result = $svc->get_list($filters + ['limit' => $per_page, 'offset' => ($paged - 1) * $per_page]);
$items = (array) ($result['items'] ?? []);
$count_all = (int) ($result['total'] ?? $count_all);
}
if (!$items) {
NativeUi::table_card_open();
echo '';
echo '' . NativeUi::empty_row(1, esc_html__('未找到对应内容,或暂无内容', 'aksrt')) . '';
echo '
';
NativeUi::table_wrap_close();
NativeUi::card_close();
return;
}
// 表头(与参考主题同列、同排序链接)。
$theads = [
['width' => '6%', 'orderby' => 'card', 'name' => __('卡号', 'aksrt')],
['width' => '10%', 'orderby' => 'password', 'name' => __('密码', 'aksrt')],
['width' => '5%', 'orderby' => 'type', 'name' => __('类型', 'aksrt')],
['width' => '5%', 'orderby' => 'create_time', 'name' => __('创建时间', 'aksrt')],
['width' => '5%', 'orderby' => 'modified_time', 'name' => __('更新时间', 'aksrt')],
['width' => '5%', 'orderby' => 'status', 'name' => __('状态', 'aksrt')],
['width' => '8%', 'orderby' => 'other', 'name' => __('标识', 'aksrt')],
];
$thead_th = ' | ';
foreach ($theads as $thead) {
$orderby_links = '';
if ($thead['orderby']) {
$orderby_url = add_query_arg('orderby', $thead['orderby']);
$orderby_links .= '';
$orderby_links .= '';
$orderby_links = '' . $orderby_links . '';
}
$thead_th .= '' . esc_html($thead['name']) . $orderby_links . ' | ';
}
$tbody = '';
foreach ($items as $msg) {
$meta = [];
if (!empty($msg['meta'])) {
$decoded = json_decode((string) $msg['meta'], true);
$meta = is_array($decoded) ? $decoded : [];
}
// 自定义卡密不展示状态;其余类型按状态着色(类型链接统一在下方链表中生成)。
$status_html = '';
if ($msg['type'] !== 'custom') {
$status_html = '' . esc_html__('未使用', 'aksrt') . '';
if ($msg['status'] === 'used') {
$status_html = '' . esc_html__('已使用', 'aksrt') . '';
if (!empty($msg['order_number'])) {
$order_link_url = admin_url('admin.php?page=aksrt_orders&s=' . urlencode((string) $msg['order_number']));
$status_html .= ' [' . esc_html__('查看', 'aksrt') . ']';
}
} elseif ($msg['status'] === 'expired') {
$status_html = '' . esc_html__('已过期', 'aksrt') . '';
} elseif ($msg['status'] === 'disabled') {
$status_html = '' . esc_html__('已禁用', 'aksrt') . '';
}
}
$other_a = '';
if (!empty($msg['note'])) {
$other_a = '' . esc_html($msg['note']) . '';
}
if ($msg['type'] === 'vip') {
$type_html = '' . esc_html__('会员兑换', 'aksrt') . '';
$level = (int) ($meta['level'] ?? 1);
$type_html .= '
' . esc_html($this->vip_level_name($level)) . ':' . esc_html($this->vip_time_text($meta));
} elseif ($msg['type'] === 'credits') {
$type_html = '' . esc_html__('积分兑换', 'aksrt') . '';
$type_html .= '
' . esc_html__('积分:', 'aksrt') . esc_html((string) (int) ($meta['points'] ?? 0));
} elseif ($msg['type'] === 'balance') {
$type_html = '' . esc_html__('余额充值', 'aksrt') . '';
$type_html .= '
' . esc_html__('金额:', 'aksrt') . esc_html($this->balance_amount_text($meta));
} else {
$type_html = '' . esc_html__('自定义卡密', 'aksrt') . '';
}
$card_name = (string) ($meta['custom_name']['card_name'] ?? '');
$password_name = (string) ($meta['custom_name']['password_name'] ?? '');
$tbody .= '';
$tbody .= '|
| ';
$tbody .= "" . esc_html($card_name) . ' ' . esc_html((string) $msg['card']) . ' | ';
$tbody .= "" . esc_html($password_name) . ' ' . esc_html((string) $msg['password']) . ' | ';
$tbody .= "$type_html | ";
$tbody .= '' . esc_html((string) $msg['created_at']) . ' | ';
$tbody .= '' . esc_html((string) ($msg['used_at'] ?: $msg['created_at'])) . ' | ';
$tbody .= "$status_html | ";
$tbody .= "$other_a | ";
$tbody .= '
';
}
echo '';
}
/**
* 列表筛选参数(不含 paged / page),用于构造翻页链接与「每页显示」表单。
* 显式列条件而不是依赖 add_query_arg() 默认取 $_SERVER['REQUEST_URI']:
* 后者把链接绑到当前请求上,一旦请求形态变化(POST、代理改写)就会丢条件。
*
* @return array
*/
private function list_query_args(string $status, string $type, string $other, string $s, string $orderby, string $order, int $per_page): array {
$args = [];
if ($status !== '') {
$args['status'] = $status;
}
if ($type !== '') {
$args['type'] = $type;
}
if ($other !== '') {
$args['other'] = $other;
}
if ($s !== '') {
$args['s'] = $s;
}
if ($orderby !== '' && $orderby !== 'modified_time') {
$args['orderby'] = $orderby;
}
if ($order === 'ASC') {
$args['desc'] = 'ASC';
}
if ($per_page !== AdminListPagination::DEFAULT_PER_PAGE) {
$args['ice_perpage'] = (string) $per_page;
}
return $args;
}
}