fix(admin): make ticket "view latest" jump reliably

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-31 12:13:57 +08:00
1 parent d7616b193e
commit a9709377bb
3 files changed
+28 -11

No files matched your search

+1 -1
View File
@@ -85,7 +85,7 @@ html.aksrt-ticket-modal-open { overflow: hidden; scrollbar-gutter: stable; }
.aksrt-ticket-conversation > .aksrt-ticket-section-head { margin: 0; padding: 12px 16px; border-bottom: 1px solid var(--an-border-soft); }
/* 会话时间线:用户在左、客服在右、系统事件居中。 */
.aksrt-ticket-conversation__scroll { max-height: 52vh; padding: 20px 16px; overflow-y: auto; overscroll-behavior: contain; scroll-behavior: smooth; }
.aksrt-ticket-conversation__scroll { max-height: 52vh; padding: 20px 16px; overflow-y: auto; overscroll-behavior: contain; }
.aksrt-ticket-detail__thread { display: flex; flex-direction: column; gap: 18px; margin: 0; padding: 0; list-style: none; }
.aksrt-ticket-detail__message { display: flex; align-items: flex-start; gap: 10px; max-width: 86%; margin: 0; }
.aksrt-ticket-detail__message.is-admin { flex-direction: row-reverse; align-self: flex-end; }
+26 -9
View File
@@ -126,6 +126,27 @@
active.querySelectorAll('[data-aksrt-ticket-assign]').forEach(function (button) { button.disabled = true; });
}
/** 会话已在底部或无需滚动时隐藏「查看最新记录」,避免点击无反应。 */
function syncLatest() {
var conversation = panel.querySelector('.aksrt-ticket-conversation__scroll');
var button = panel.querySelector('[data-aksrt-ticket-latest]');
if (!conversation || !button) return;
button.hidden = conversation.scrollHeight - conversation.clientHeight - conversation.scrollTop <= 8;
}
/** 会话内滚到底部;手动触发时同时让弹窗正文露出会话底部。 */
function showLatest(manual) {
var conversation = panel.querySelector('.aksrt-ticket-conversation__scroll');
if (!conversation) return;
conversation.scrollTop = conversation.scrollHeight;
if (manual) {
var gap = conversation.getBoundingClientRect().bottom - panel.getBoundingClientRect().bottom;
if (gap > 0) panel.scrollTop += gap;
conversation.focus({ preventScroll: true });
}
syncLatest();
}
function updateUrl(id, page) {
var url = new URL(window.location.href);
if (id) url.searchParams.set('id', String(id));
@@ -180,10 +201,7 @@
if (typeof data.list === 'string') list.innerHTML = data.list;
updateUrl(id, data.page);
setupForms(panel, restore);
if (message === strings.reply) {
var conversation = panel.querySelector('.aksrt-ticket-conversation__scroll');
if (conversation) conversation.scrollTop = conversation.scrollHeight;
}
showLatest(false);
stale = false;
savedDrafts = {};
savedMessage = '';
@@ -260,11 +278,7 @@
syncStatus(statusForm);
statusForm.querySelector('[type="submit"]').focus();
}
if (event.target.closest('[data-aksrt-ticket-latest]')) {
var conversation = panel.querySelector('.aksrt-ticket-conversation__scroll');
conversation.scrollTop = conversation.scrollHeight;
conversation.focus();
}
if (event.target.closest('[data-aksrt-ticket-latest]')) showLatest(true);
});
root.addEventListener('input', function (event) {
@@ -389,6 +403,9 @@
});
});
// scroll 不冒泡,用捕获监听会话容器。
panel.addEventListener('scroll', syncLatest, true);
window.addEventListener('beforeunload', function (event) {
if (!saving && !dirty()) return;
event.preventDefault();
+1 -1
View File
@@ -30,7 +30,7 @@ trait UsersMenusTicketsDetail {
$html = '<section class="aksrt-ticket-conversation" aria-label="' . esc_attr__('问题与沟通记录', 'aksrt') . '">';
$html .= '<div class="aksrt-ticket-section-head"><h3>' . esc_html__('沟通记录', 'aksrt') . ' <span class="aksrt-ticket-pill">' . esc_html(sprintf(__('%d 条记录', 'aksrt'), count($replies))) . '</span></h3>';
if ($replies !== []) {
$html .= '<button type="button" class="button-link" data-aksrt-ticket-latest>' . esc_html__('查看最新记录', 'aksrt') . '</button>';
$html .= '<button type="button" class="button-link" data-aksrt-ticket-latest hidden>' . esc_html__('查看最新记录', 'aksrt') . '</button>';
}
$html .= '</div><div class="aksrt-ticket-conversation__scroll" tabindex="0" role="region" aria-label="' . esc_attr__('可滚动的沟通记录', 'aksrt') . '"><ol class="aksrt-ticket-detail__thread">';
$html .= $this->ticket_message('origin', (int) $ticket['user_id'], (string) $ticket['user_name'], !empty($ticket['post_admin_id']) ? __('代客提交', 'aksrt') : __('提交了工单', 'aksrt'), (string) $ticket['post_time'], (string) $ticket['content'], (array) $ticket['attachment']);