feat(admin): replace ticket dialogs with in-page views
Ticket handling on users.php?page=aksrt_tickets no longer uses dialogs. The list, the workspace (?id=N) and the assisted create form (?view=new) are server-rendered page views that carry the list filters and page for going back. Writes still go through the ticket REST routes; on success the page reloads with a native notice, and unsent drafts in other forms survive the reload via sessionStorage. Uncertain or conflicting writes lock every form and only offer a reload. Remove dead code: UsersMenusTicketsDialogs, the aksrt_ticket_view AJAX read and its nonce, dialog CSS/JS (backdrop, scroll lock, focus return, read races) and the dialog runtime test. Fix the create link carrying an unclamped page number on out-of-range list pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
48e54dc115
commit
d86a85e6a6
13 files changed
+720
-1264
No files matched your search
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
/** 工单筛选与列表;详情统一在弹窗内按需加载。@package AKSRT */
|
||||
/** 工单筛选与列表;标题与操作直接链接到处理工作区(?id=)。@package AKSRT */
|
||||
|
||||
namespace AKSRT\Admin\Native;
|
||||
|
||||
@@ -11,8 +11,32 @@ defined('ABSPATH') || exit;
|
||||
|
||||
trait UsersMenusTicketsList {
|
||||
|
||||
/** 返回实际页码,避免处理最后一条工单后停在空的末页。 */
|
||||
private function render_ticket_list(array $filters, int $paged): int {
|
||||
private function render_ticket_list_page(array $filters, int $paged): void {
|
||||
// 先查询并夹取页码,页头「代客提交」链接才能带上实际页码。
|
||||
[$result, $paged] = $this->ticket_list_result($filters, $paged);
|
||||
NativeUi::header(
|
||||
__('工单管理', 'aksrt'),
|
||||
__('查看用户问题、跟进沟通并记录处理结果。', 'aksrt'),
|
||||
'dashicons-tickets-alt',
|
||||
[
|
||||
[
|
||||
'label' => __('代客提交工单', 'aksrt'),
|
||||
'url' => $this->ticket_page_url(['view' => 'new'] + $this->ticket_context($filters, $paged)),
|
||||
'primary' => true,
|
||||
'icon' => 'dashicons-plus-alt2',
|
||||
],
|
||||
[
|
||||
'label' => __('工单配置', 'aksrt'),
|
||||
'url' => admin_url('admin.php?page=aksrt-settings#/users/ticket'),
|
||||
'icon' => 'dashicons-admin-generic',
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->render_ticket_list($filters, $paged, $result);
|
||||
}
|
||||
|
||||
/** 越界页码夹到末页,避免处理最后一条工单后停在空页。返回 [查询结果, 实际页码]。 */
|
||||
private function ticket_list_result(array $filters, int $paged): array {
|
||||
$repo = TicketRepository::get_instance();
|
||||
$args = [
|
||||
'status' => $filters['status'] === '' ? [] : [$filters['status']],
|
||||
@@ -28,6 +52,10 @@ trait UsersMenusTicketsList {
|
||||
$args['offset'] = ($paged - 1) * self::TICKET_PER_PAGE;
|
||||
$result = $repo->paginate($args, true);
|
||||
}
|
||||
return [$result, $paged];
|
||||
}
|
||||
|
||||
private function render_ticket_list(array $filters, int $paged, array $result): void {
|
||||
NativeUi::card_open('', '', true, 'aksrt-tickets-admin__list-card');
|
||||
$this->render_ticket_toolbar($filters);
|
||||
echo '<div class="aksrt-native-table-wrap"><table class="widefat striped aksrt-tickets-admin__table">';
|
||||
@@ -50,14 +78,14 @@ trait UsersMenusTicketsList {
|
||||
? __('请调整筛选条件,或使用标题右侧的「代客提交工单」。', 'aksrt')
|
||||
: __('暂无未关闭工单。可切换状态查看历史记录,或代用户创建工单。', 'aksrt'));
|
||||
}
|
||||
$context = $this->ticket_context($filters, $paged);
|
||||
foreach ($result['items'] as $ticket) {
|
||||
$this->render_ticket_center_row($ticket);
|
||||
$this->render_ticket_center_row($ticket, $context);
|
||||
}
|
||||
echo '</tbody></table>';
|
||||
NativeUi::table_wrap_close();
|
||||
AdminListPagination::render(self::TICKET_PAGE_SLUG, $result['total'], $paged, self::TICKET_PER_PAGE, $filters, 'users.php');
|
||||
NativeUi::card_close();
|
||||
return $paged;
|
||||
}
|
||||
|
||||
private function render_ticket_toolbar(array $filters): void {
|
||||
@@ -108,13 +136,13 @@ trait UsersMenusTicketsList {
|
||||
echo '</form>';
|
||||
}
|
||||
|
||||
private function render_ticket_center_row(array $ticket): void {
|
||||
private function render_ticket_center_row(array $ticket, array $context): void {
|
||||
$id = (int) $ticket['id'];
|
||||
$url = esc_url($this->ticket_page_url(['id' => $id] + $context));
|
||||
$last = (string) $ticket['last_reply_time'] !== '' ? (string) $ticket['last_reply_time'] : (string) $ticket['post_time'];
|
||||
$awaiting = in_array((string) $ticket['status'], [TicketStatusService::KEY_PENDING, TicketStatusService::KEY_USER_REPLIED], true);
|
||||
$hook = ' data-aksrt-ticket-view="' . $id . '" aria-haspopup="dialog" aria-controls="aksrt-ticket-detail-dialog"';
|
||||
echo '<tr class="aksrt-tickets-admin__row' . ($awaiting ? ' is-awaiting' : '') . '">';
|
||||
echo '<td class="column-title"><button type="button" class="button-link row-title"' . $hook . '>' . esc_html((string) $ticket['title']) . '</button>' . $this->ticket_urge_badge($ticket); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<td class="column-title"><a class="row-title" href="' . $url . '">' . esc_html((string) $ticket['title']) . '</a>' . $this->ticket_urge_badge($ticket); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<div class="aksrt-tickets-admin__sub">' . esc_html((string) $ticket['ticket_num']) . '</div>';
|
||||
if ((string) $ticket['order_number'] !== '') {
|
||||
echo '<div class="aksrt-tickets-admin__sub">' . esc_html__('订单:', 'aksrt') . esc_html((string) $ticket['order_number']) . '</div>';
|
||||
@@ -124,7 +152,7 @@ trait UsersMenusTicketsList {
|
||||
echo '<td class="column-user">' . $this->ticket_user_chip((int) $ticket['user_id'], (string) $ticket['user_name']) . '</td>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<td class="column-admin">' . ((int) $ticket['admin_id'] > 0 ? esc_html((string) $ticket['admin_name']) : '<span class="aksrt-ticket-hint">' . esc_html__('未指派', 'aksrt') . '</span>') . '</td>';
|
||||
echo '<td class="column-time"><time>' . esc_html($last) . '</time><div class="aksrt-tickets-admin__sub">' . esc_html(sprintf(__('提交于 %s', 'aksrt'), (string) $ticket['post_time'])) . '</div></td>';
|
||||
echo '<td class="column-actions"><button type="button" class="button' . ($awaiting ? ' button-primary' : '') . '"' . $hook . '>' . esc_html(!empty($ticket['is_closed']) ? __('查看记录', 'aksrt') : __('处理工单', 'aksrt')) . '</button></td></tr>';
|
||||
echo '<td class="column-actions"><a class="button' . ($awaiting ? ' button-primary' : '') . '" href="' . $url . '">' . esc_html(!empty($ticket['is_closed']) ? __('查看记录', 'aksrt') : __('处理工单', 'aksrt')) . '</a></td></tr>';
|
||||
}
|
||||
|
||||
private function ticket_status_badge(array $ticket): string {
|
||||
|
||||
Reference in new issue
Block a user