fix(ticket): rework detail modal layout and restore urge

- Detail modal: fixed-height dialog, thread is the only (thin) scroll area
- Collapsible pinned summary bar (collapsed by default, state kept across re-render)
- Composer: toolbar (image / urge / close) above input, pending image tray with remove
- Paste screenshots to upload; create form uses the same button + tray
- Urge/close now POST (routes are CREATABLE); urge cooldown countdown via urge_wait
- Notify admins on urge when ticket is unassigned
- Split composer/form styles into tickets-compose.css; drop dead uploader code

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-27 21:37:03 +08:00
1 parent b74381cfa2
commit 13bde11dda
7 files changed
+713 -392

No files matched your search

+27 -8
View File
@@ -227,7 +227,10 @@
button.disabled = full;
});
var count = root.querySelector('[data-aksrt-ticket-image-count]');
if (count) count.textContent = holder.children.length + ' / ' + attachmentMax();
if (count) {
count.textContent = holder.children.length + ' / ' + attachmentMax();
count.classList.toggle('is-zero', holder.children.length === 0);
}
}
function uploadFiles(root, files) {
@@ -311,16 +314,31 @@
shell.addEventListener('change', function (event) {
clearInvalid(event.target.closest('fieldset') || event.target);
});
// 粘贴截图直接进入待上传区(未开启附件时表单内没有图片容器,自然跳过)。
shell.addEventListener('paste', function (event) {
var root = event.target.closest && event.target.closest('form');
if (!root || !imageHolder(root) || !event.clipboardData) return;
var files = Array.prototype.filter.call(event.clipboardData.files || [], function (file) {
return /^image\//.test(file.type);
});
if (!files.length) return;
event.preventDefault();
uploadFiles(root, files);
});
return ctx;
}
function uploaderHtml() {
// 回复框:工具栏里的「图片」按钮 + 输入框上方的待发送缩略图条(空时由 CSS :empty 收起)。
function attachButtonHtml() {
if (!attachmentEnabled()) return '';
return '<div class="aksrt-ticket-uploader">'
+ '<div class="aksrt-ticket-images" data-aksrt-ticket-images></div>'
+ '<button type="button" class="aksrt-ticket-image is-add" data-aksrt-ticket-upload aria-label="添加图片">'
+ icon('fa-plus') + '<span data-aksrt-ticket-image-count>0 / ' + attachmentMax() + '</span></button>'
+ '</div>';
return '<button type="button" class="aksrt-ticket-tool" data-aksrt-ticket-upload title="添加图片,也可直接粘贴截图">'
+ icon('fa-image') + '<span>图片</span>'
+ '<span class="aksrt-ticket-tool__count is-zero" data-aksrt-ticket-image-count>0 / ' + attachmentMax() + '</span></button>';
}
function attachTrayHtml() {
if (!attachmentEnabled()) return '';
return '<div class="aksrt-ticket-tray" data-aksrt-ticket-images aria-label="待发送图片"></div>';
}
window.AksrtTicketCore = {
@@ -346,6 +364,7 @@
collectAttachments: collectAttachments,
isUploading: isUploading,
bindShell: bindShell,
uploaderHtml: uploaderHtml,
attachButtonHtml: attachButtonHtml,
attachTrayHtml: attachTrayHtml,
};
})();