Files
baiyue-logistics-chat/templates/admin.html
T
ouyangxq 805675f8db 重构物流客服模块并完善会话接待工作台
- 拆分应用工厂、业务服务与路由,保留原有 HTTP/SSE 和存储入口
- 分离页面资源,重排客服工作台并完善响应式导航、草稿和附件交互
- 整理维护脚本、请求示例和贡献指南,移除启动脚本中的密钥配置
- 上传文件改为仅本地保留,补充隔离的后端与前端回归验证

验证:46 项 Python 测试通过,含 14 个已有子测试;12 个 Node 前端场景通过。
2026-10-29 10:59:29 +08:00

93 lines
7.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<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') }}">
</head>
<body>
<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>
</div>
<div class="topbar-actions">
<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>
<a class="export-link" href="/api/export_chat">导出记录 ↗</a>
</div>
</details>
</div>
</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>
</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>
<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">
<div class="composer-heading"><label for="replyText">回复客户</label><span>Shift + Enter 换行</span></div>
<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>
<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>
<script src="{{ url_for('static', filename='js/admin.js') }}"></script>
</body>
</html>