feat(admin): unify native admin pages on a shared modern UI
Add NativeUi helper + native-ui.css (tokens mirror the SPA Naive UI theme) and move the pay center, orders, products, coupons, charge cards, income, withdrawals, tickets, invite codes, VIP, verify, messages and report/ban pages onto shared header, stat cards, cards, filters, badges and empty states. Remove inline styles and dead helpers; split PayChargeCards into sibling traits to stay under the file size limit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa692f3c9f
commit
18951b01d6
29 files changed
+2503
-1593
No files matched your search
@@ -13,17 +13,18 @@ defined('ABSPATH') || exit;
|
||||
|
||||
trait UsersMenusTicketsList {
|
||||
|
||||
/** 代客提交:原生 <details> 折叠,失败回跳时自动展开。 */
|
||||
/** 代客提交:共享折叠卡片,失败回跳时自动展开。 */
|
||||
private function render_ticket_create_form(): void {
|
||||
$types = \AKSRT\Ticket\TicketTypeService::all();
|
||||
$failed = isset($_GET['aksrt_ticket_msg']) && sanitize_key((string) wp_unslash($_GET['aksrt_ticket_msg'])) === 'create_failed';
|
||||
|
||||
echo '<details class="aksrt-tickets-admin__create"' . ($failed ? ' open' : '') . '>';
|
||||
echo '<details class="aksrt-native-card aksrt-native-collapse"' . ($failed ? ' open' : '') . '>';
|
||||
echo '<summary><span class="dashicons dashicons-plus-alt2" aria-hidden="true"></span>' . esc_html__('代客提交工单', 'aksrt') . '</summary>';
|
||||
echo '<div class="aksrt-native-card__body">';
|
||||
|
||||
if ($types === []) {
|
||||
printf(
|
||||
'<p class="aksrt-tickets-admin__create-empty">%s <a href="%s">%s</a></p></details>',
|
||||
'<p class="aksrt-native-muted">%s <a href="%s">%s</a></p></div></details>',
|
||||
esc_html__('尚未配置工单部门,无法创建工单。', 'aksrt'),
|
||||
esc_url(admin_url('admin.php?page=aksrt-settings#/users/ticket')),
|
||||
esc_html__('前往配置', 'aksrt')
|
||||
@@ -31,43 +32,43 @@ trait UsersMenusTicketsList {
|
||||
return;
|
||||
}
|
||||
|
||||
echo $this->ticket_form_open('create', 0, 'aksrt-tickets-admin__create-form'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $this->ticket_form_open('create', 0); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
wp_nonce_field('aksrt_ticket_create_0');
|
||||
echo '<div class="aksrt-tickets-admin__create-grid">';
|
||||
echo '<div class="aksrt-native-form-grid">';
|
||||
printf(
|
||||
'<label><span>%s</span><input type="number" name="user_id" min="1" required class="regular-text" placeholder="%s" /></label>',
|
||||
'<label class="aksrt-native-field"><span class="aksrt-native-field__label">%s</span><input type="number" name="user_id" min="1" required placeholder="%s" /></label>',
|
||||
esc_html__('用户 ID', 'aksrt'),
|
||||
esc_attr__('工单归属用户', 'aksrt')
|
||||
);
|
||||
echo '<label><span>' . esc_html__('部门', 'aksrt') . '</span><select name="ticket_type_id" required>';
|
||||
echo '<label class="aksrt-native-field"><span class="aksrt-native-field__label">' . esc_html__('部门', 'aksrt') . '</span><select name="ticket_type_id" required>';
|
||||
foreach ($types as $row) {
|
||||
printf('<option value="%d">%s</option>', (int) $row['id'], esc_html((string) $row['name']));
|
||||
}
|
||||
echo '</select></label>';
|
||||
printf(
|
||||
'<label class="is-wide"><span>%s</span><input type="text" name="title" maxlength="%d" required class="large-text" /></label>',
|
||||
'<label class="aksrt-native-field is-wide"><span class="aksrt-native-field__label">%s</span><input type="text" name="title" maxlength="%d" required /></label>',
|
||||
esc_html__('标题', 'aksrt'),
|
||||
\AKSRT\Ticket\TicketSettings::title_max()
|
||||
);
|
||||
if (\AKSRT\Ticket\TicketSettings::order_link_enabled()) {
|
||||
printf(
|
||||
'<label class="is-wide"><span>%s</span><input type="text" name="order_number" class="regular-text" placeholder="%s" /></label>',
|
||||
'<label class="aksrt-native-field is-wide"><span class="aksrt-native-field__label">%s</span><input type="text" name="order_number" placeholder="%s" /></label>',
|
||||
esc_html__('关联订单', 'aksrt'),
|
||||
esc_attr__('可选', 'aksrt')
|
||||
);
|
||||
}
|
||||
printf(
|
||||
'<label class="is-wide"><span>%s</span><textarea name="content" rows="4" maxlength="%d" required class="large-text"></textarea></label>',
|
||||
'<label class="aksrt-native-field is-wide"><span class="aksrt-native-field__label">%s</span><textarea name="content" rows="4" maxlength="%d" required></textarea></label>',
|
||||
esc_html__('问题描述', 'aksrt'),
|
||||
\AKSRT\Ticket\TicketSettings::content_max()
|
||||
);
|
||||
echo '</div>';
|
||||
printf(
|
||||
'<p class="aksrt-tickets-admin__create-foot"><span class="description">%s</span><button type="submit" class="button button-primary">%s</button></p>',
|
||||
'<div class="aksrt-native-form-foot"><span class="aksrt-native-muted">%s</span><button type="submit" class="button button-primary">%s</button></div>',
|
||||
esc_html__('创建后状态为「已回复」并由你跟进,用户会收到通知。', 'aksrt'),
|
||||
esc_html__('创建工单', 'aksrt')
|
||||
);
|
||||
echo '</form></details>';
|
||||
echo '</form></div></details>';
|
||||
}
|
||||
|
||||
private function render_ticket_list_tab(): void {
|
||||
@@ -84,8 +85,7 @@ trait UsersMenusTicketsList {
|
||||
], static fn($value): bool => $value !== '' && $value !== 0);
|
||||
$view_url = $this->ticket_page_url(array_merge($filters, $paged > 1 ? ['paged' => $paged] : []));
|
||||
|
||||
$this->render_ticket_status_views($status);
|
||||
$this->render_ticket_filter_form($status, $type_id, $s);
|
||||
$this->render_ticket_toolbar($status, $type_id, $s);
|
||||
|
||||
$repo = \AKSRT\Ticket\TicketRepository::get_instance();
|
||||
$result = $repo->paginate([
|
||||
@@ -98,7 +98,7 @@ trait UsersMenusTicketsList {
|
||||
$items = $result['items'];
|
||||
$total = $result['total'];
|
||||
|
||||
echo '<div class="aksrt-tickets-admin__table-wrap">';
|
||||
NativeUi::table_card_open(__('工单列表', 'aksrt'));
|
||||
echo '<table class="widefat striped aksrt-tickets-admin__table">';
|
||||
echo '<thead><tr>';
|
||||
echo '<th class="column-title">' . esc_html__('工单', 'aksrt') . '</th>';
|
||||
@@ -113,17 +113,14 @@ trait UsersMenusTicketsList {
|
||||
$hint = $filters === []
|
||||
? __('暂无进行中的工单,已关闭工单可在「已关闭」视图查看。', 'aksrt')
|
||||
: __('当前筛选条件下没有工单。', 'aksrt');
|
||||
printf(
|
||||
'<tr class="no-items"><td colspan="6"><div class="aksrt-tickets-admin__empty"><strong>%s</strong><span>%s</span></div></td></tr>',
|
||||
esc_html__('暂无工单', 'aksrt'),
|
||||
esc_html($hint)
|
||||
);
|
||||
echo NativeUi::empty_row(6, __('暂无工单', 'aksrt'), $hint); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
foreach ($items as $ticket) {
|
||||
$this->render_ticket_center_row($ticket, $view_url, $open_id === (int) $ticket['id']);
|
||||
}
|
||||
echo '</tbody></table></div>';
|
||||
echo '</tbody></table>';
|
||||
NativeUi::table_wrap_close();
|
||||
|
||||
\AKSRT\Admin\Native\AdminListPagination::render(
|
||||
self::TICKET_PAGE_SLUG,
|
||||
@@ -133,6 +130,17 @@ trait UsersMenusTicketsList {
|
||||
$filters,
|
||||
'users.php'
|
||||
);
|
||||
NativeUi::card_close();
|
||||
}
|
||||
|
||||
/** 状态视图 + 部门/关键词筛选,合成一张工具条卡片。 */
|
||||
private function render_ticket_toolbar(string $status, int $type_id, string $s): void {
|
||||
NativeUi::card_open();
|
||||
echo '<div class="aksrt-native-toolbar">';
|
||||
$this->render_ticket_status_views($status);
|
||||
$this->render_ticket_filter_form($status, $type_id, $s);
|
||||
echo '</div>';
|
||||
NativeUi::card_close();
|
||||
}
|
||||
|
||||
/** 状态视图:未关闭(默认)+ 各进行中状态 + 完结态,均带计数。 */
|
||||
@@ -152,7 +160,7 @@ trait UsersMenusTicketsList {
|
||||
}
|
||||
array_unshift($views, ['', __('未关闭', 'aksrt'), $open_total, '']);
|
||||
|
||||
echo '<ul class="subsubsub aksrt-tickets-admin__views">';
|
||||
echo '<ul class="subsubsub">';
|
||||
$last = count($views) - 1;
|
||||
foreach ($views as $i => [$key, $label, $count, $color]) {
|
||||
printf(
|
||||
@@ -170,7 +178,7 @@ trait UsersMenusTicketsList {
|
||||
|
||||
/** 部门 + 关键词筛选(状态由视图链接决定,以隐藏域保留)。 */
|
||||
private function render_ticket_filter_form(string $status, int $type_id, string $s): void {
|
||||
echo '<form method="get" action="' . esc_url(admin_url('users.php')) . '" class="aksrt-tickets-admin__filters">';
|
||||
echo '<form method="get" action="' . esc_url(admin_url('users.php')) . '" class="aksrt-native-filters">';
|
||||
echo '<input type="hidden" name="page" value="' . esc_attr(self::TICKET_PAGE_SLUG) . '" />';
|
||||
if ($status !== '') {
|
||||
echo '<input type="hidden" name="status" value="' . esc_attr($status) . '" />';
|
||||
@@ -240,7 +248,7 @@ trait UsersMenusTicketsList {
|
||||
$this->ticket_user_chip((int) $ticket['user_id'], (string) $ticket['user_name']), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
(int) $ticket['admin_id'] > 0
|
||||
? esc_html((string) $ticket['admin_name'])
|
||||
: '<span class="aksrt-tickets-admin__muted">' . esc_html__('未指派', 'aksrt') . '</span>',
|
||||
: '<span class="aksrt-native-muted">' . esc_html__('未指派', 'aksrt') . '</span>',
|
||||
esc_html($last),
|
||||
esc_html(sprintf(
|
||||
/* translators: %s submit time */
|
||||
|
||||
Reference in new issue
Block a user