2026-10-27 16:07:11 +08:00
<!DOCTYPE html>
2026-10-29 10:59:29 +08:00
< html lang = "zh-CN" >
2026-10-27 16:07:11 +08:00
< head >
2026-10-29 10:59:29 +08:00
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > 客服工作台 · 柏悦物流</ title >
< link rel = "icon" href = "{{ url_for('static', filename='fa.jpg') }}" >
< link rel = "stylesheet" href = "{{ url_for('static', filename='css/theme.css') }}" >
< link rel = "stylesheet" href = "{{ url_for('static', filename='css/admin.css') }}" >
2026-10-27 16:07:11 +08:00
</ head >
< body >
2026-10-29 10:59:29 +08:00
< header class = "topbar" >
< div class = "app-identity" >
< a class = "brand" href = "/admin/dashboard" >< span class = "brand-mark" >< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "1.6" stroke-linecap = "round" stroke-linejoin = "round" aria-hidden = "true" >< path d = "m4 7 8-4 8 4v10l-8 4-8-4Z" />< path d = "m4 7 8 4 8-4M12 11v10M8 5l8 4" /></ svg ></ span >< span class = "brand-name" > 柏悦物流</ span ></ a >
< span class = "nav-divider" aria-hidden = "true" ></ span >< h1 > 客服工作台</ h1 >
2026-10-28 10:44:48 +08:00
</ div >
2026-10-29 10:59:29 +08:00
< div class = "topbar-actions" >
2026-10-29 16:28:50 +08:00
< span id = "nightBadge" class = "night-badge" hidden > 非工作时段</ span >
< button id = "notifications-toggle" class = "icon-button" type = "button" aria-label = "开启浏览器通知" title = "开启浏览器通知" aria-pressed = "false" > 🔔</ button >
2026-10-29 10:59:29 +08:00
< a class = "workspace-link" href = "/" > 客户入口 ↗</ a >
< details class = "data-overview" id = "data-overview" >
< summary >< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "1.6" aria-hidden = "true" >< path d = "M4 4v16h17M8 16v-5M13 16V7M18 16V3" /></ svg > 数据概览</ summary >
< div class = "stats" aria-label = "历史对话统计" >
< h2 > 历史对话与反馈</ h2 >
< div class = "stat" >< span > 历史对话</ span >< b id = "s1" > —</ b ></ div >
< div class = "stat" >< span > 历史消息</ span >< b id = "s2" > —</ b ></ div >
< div class = "stat" >< span > 今日新对话</ span >< b id = "s3" > —</ b ></ div >
< div class = "stat" >< span > 有帮助</ span >< b id = "s4" > —</ b ></ div >
< div class = "stat" >< span > 需改进</ span >< b id = "s5" > —</ b ></ div >
2026-10-29 16:28:50 +08:00
< div class = "stat" >< span > 服务评价</ span >< b id = "s6" > —</ b ></ div >
< a class = "export-link" href = "/api/export_chat" > 导出 Excel ↗</ a >
2026-10-29 10:59:29 +08:00
</ div >
</ details >
2026-10-28 10:44:48 +08:00
</ div >
2026-10-29 10:59:29 +08:00
</ header >
< div id = "sync-status" class = "sync-status" role = "status" hidden > 会话连接中断,正在重试…</ div >
< main class = "layout" >
< aside class = "conv-list" id = "session-browser" aria-label = "会话列表" >
< div class = "list-heading" >
< h2 > 客户会话</ h2 >< p > 查看咨询,及时接待与回复</ p >
< div class = "session-search-wrap" >< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "1.7" aria-hidden = "true" >< circle cx = "10.5" cy = "10.5" r = "6.5" />< path d = "m16 16 4 4" /></ svg >< input id = "session-search" type = "search" aria-label = "搜索客户会话" placeholder = "搜索会话或消息" autocomplete = "off" ></ div >
2026-10-29 16:28:50 +08:00
< button id = "history-search-toggle" class = "text-button" type = "button" > 搜索历史记录 ↗</ button >
2026-10-29 10:59:29 +08:00
</ div >
< div class = "session-tabs" role = "tablist" aria-label = "会话状态" >
< button id = "tab-active" type = "button" role = "tab" aria-selected = "true" aria-controls = "sessionList" > 接待中 < span id = "active-count" class = "section-count" > 0</ span ></ button >
< button id = "tab-queue" type = "button" role = "tab" aria-selected = "false" aria-controls = "queue" tabindex = "-1" > 排队中 < span id = "queue-count" class = "section-count" > 0</ span ></ button >
</ div >
< div class = "session-scroll" >
< div id = "sessionList" role = "tabpanel" aria-labelledby = "tab-active" >< div class = "list-empty" > 暂无进行中的会话</ div ></ div >
< div id = "queue" role = "tabpanel" aria-labelledby = "tab-queue" hidden >< div class = "list-empty" > 正在加载会话…</ div ></ div >
</ div >
< div class = "list-footer" >< span >< span class = "list-footer-mark" aria-hidden = "true" ></ span > 柏悦物流 · 客户服务</ span >< button id = "tools-from-list" type = "button" aria-controls = "service-tools" aria-expanded = "false" > 服务资料</ button ></ div >
</ aside >
< section class = "chat-area" id = "chatArea" aria-label = "会话内容" >
< header class = "chat-header" >
< button id = "sessions-back" class = "sessions-back" type = "button" aria-label = "返回会话列表" > ‹ </ button >
< div class = "participant-avatar" aria-hidden = "true" > 客</ div >
< div class = "participant-copy" >< h2 id = "chatTitle" > 会话接待</ h2 >< p id = "chat-subtitle" > 选择一段会话,开始回复客户</ p ></ div >
< div class = "chat-header-actions" >
< button id = "tools-toggle" class = "tools-toggle" type = "button" aria-label = "资料与快捷回复" aria-controls = "service-tools" aria-expanded = "false" >< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "1.6" aria-hidden = "true" >< rect x = "4" y = "3" width = "16" height = "18" rx = "2" />< circle cx = "9" cy = "9" r = "2" />< path d = "M6 16a3 3 0 0 1 6 0M14 8h3M14 12h3M14 16h3" /></ svg >< span > 资料与回复</ span ></ button >
2026-10-29 16:28:50 +08:00
< button id = "transfer-session" class = "close" type = "button" onclick = "transferSession()" > 转接</ button >
2026-10-29 10:59:29 +08:00
< button id = "close-session" class = "close" type = "button" onclick = "closeSession()" > 结束会话</ button >
</ div >
</ header >
< div class = "empty" id = "emptyTip" >< div >
< div class = "empty-illustration" >< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "1.6" stroke-linecap = "round" stroke-linejoin = "round" aria-hidden = "true" >< path d = "m4 7 8-4 8 4v10l-8 4-8-4Z" />< path d = "m4 7 8 4 8-4M12 11v10M8 5l8 4" /></ svg ></ div >
< h2 > 选择会话,开始接待</ h2 >< p > 在会话列表查看客户咨询,< br > 新咨询可从「排队中」接入。</ p >
</ div ></ div >
< div id = "chatContent" class = "session-panel" style = "display:none" >
< div id = "chatBox" role = "log" aria-live = "polite" aria-label = "会话消息" ></ div >
< footer class = "agent-composer" >
2026-10-29 16:28:50 +08:00
< div class = "composer-heading" >< label for = "replyText" > 回复客户</ label >< div class = "emoji-control" >< button id = "agent-emoji-toggle" class = "text-button" type = "button" aria-label = "选择表情" aria-expanded = "false" aria-controls = "agent-emoji-panel" > 😊 表情</ button >< div id = "agent-emoji-panel" class = "emoji-picker" hidden ></ div ></ div >< span > Shift + Enter 换行</ span ></ div >
2026-10-29 10:59:29 +08:00
< div class = "input-bar" >
< textarea id = "replyText" rows = "2" aria-label = "回复客户" placeholder = "输入回复内容,按 Enter 发送…" ></ textarea >
< div class = "input-actions" >< span > 常用回复可在「资料与回复」中选择</ span >< button id = "reply-send" type = "button" onclick = "sendReply()" > 发送</ button ></ div >
</ div >
< p id = "reply-status" class = "reply-status" role = "status" hidden ></ p >
</ footer >
</ div >
</ section >
< aside class = "side" id = "service-tools" aria-label = "客户信息与回复" aria-hidden = "true" inert >
< header class = "side-heading" >< h2 > 服务资料</ h2 >< button id = "tools-close" type = "button" class = "icon-button" aria-label = "关闭服务资料" > × </ button ></ header >
< section class = "card" >< h3 > 客户信息</ h3 >< div class = "info-row" id = "cInfo" > 选择会话后查看客户信息</ div >< p class = "info-hint" > 咨询运费时,可先确认运单号、货物重量、尺寸与目的地。</ p ></ section >
2026-10-29 16:28:50 +08:00
< section class = "card" >< h3 >< label for = "noteInput" > 会话备注</ label ></ h3 >< textarea id = "noteInput" class = "note-input" rows = "3" placeholder = "填写本次会话的跟进事项" disabled ></ textarea >< button id = "note-save" type = "button" class = "quick" disabled > 保存备注</ button ></ section >
2026-10-29 10:59:29 +08:00
< section class = "card" >< h3 > 常用回复</ h3 >
< p class = "card-caption" > 点击填入草稿,编辑后再发送</ p >
< button type = "button" class = "quick" onclick = "quickReply('您好,请问有什么可以帮您?')" > 您好,有什么可以帮您?</ button >
< button type = "button" class = "quick" onclick = "quickReply('请提供运单号,我帮您查询。')" > 请提供运单号,我帮您查询</ button >
< button type = "button" class = "quick" onclick = "quickReply('已为您催促,请稍候。')" > 已为您催促,请稍候</ button >
< button type = "button" class = "quick" onclick = "quickReply('感谢您的咨询,祝您生活愉快!')" > 感谢咨询,祝您生活愉快</ button >
</ section >
< section class = "card" >< h3 > 离线留言</ h3 >< div id = "ticketList" >< div class = "list-empty" > 正在加载留言…</ div ></ div ></ section >
</ aside >
</ main >
< button class = "tools-backdrop" id = "tools-backdrop" type = "button" aria-label = "关闭服务资料" ></ button >
2026-10-29 16:28:50 +08:00
< dialog id = "searchResult" class = "search-dialog" aria-labelledby = "search-title" >< header >< h2 id = "search-title" > 搜索历史记录</ h2 >< button id = "search-close" class = "icon-button" type = "button" aria-label = "关闭搜索" > × </ button ></ header >< form id = "history-search-form" >< label class = "sr-only" for = "searchBox" > 历史消息关键词</ label >< input id = "searchBox" type = "search" placeholder = "输入关键词搜索聊天记录" required >< button type = "submit" class = "quick" > 搜索</ button ></ form >< div id = "searchBody" aria-live = "polite" > 请输入关键词搜索历史消息</ div ></ dialog >
< script src = "{{ url_for('static', filename='js/support.js') }}" ></ script >
< script src = "{{ url_for('static', filename='js/admin_tools.js') }}" ></ script >
2026-10-29 10:59:29 +08:00
< script src = "{{ url_for('static', filename='js/admin.js') }}" ></ script >
2026-10-27 16:07:11 +08:00
</ body >
</ html >