// 状态 let currentUser = ""; let conversations = []; let currentKfid = ""; // 初始化 document.addEventListener("DOMContentLoaded", () => { fetchAccounts(); }); // Toast function showToast(msg, type = "success") { const el = document.getElementById("toast"); el.textContent = msg; el.className = "toast toast-" + type; el.style.display = "block"; el.style.opacity = "1"; setTimeout(() => { el.style.opacity = "0"; setTimeout(() => el.style.display = "none", 300); }, 2000); } // 获取客服账号列表,填充下拉框 async function fetchAccounts() { const select = document.getElementById("accountSelect"); select.innerHTML = ''; try { const resp = await fetch("/api/accounts"); const data = await resp.json(); if (data.errcode === 0 && data.account_list && data.account_list.length > 0) { const accounts = data.account_list; select.innerHTML = accounts.map((a, i) => `` ).join(""); currentKfid = accounts[0].open_kfid; showToast(`已加载 ${accounts.length} 个客服账号`); // 自动加载会话 loadConversations(); } else { select.innerHTML = ''; showToast("获取账号列表失败: " + (data.errmsg || "未知错误"), "error"); } } catch (e) { select.innerHTML = ''; showToast("获取账号列表失败: " + e.message, "error"); } } function onAccountChange() { const select = document.getElementById("accountSelect"); currentKfid = select.value; if (currentKfid) { currentUser = ""; document.getElementById("msgHeader").textContent = "请选择会话"; document.getElementById("messageList").innerHTML = '
选择左侧会话查看消息
'; document.getElementById("sendBtn").disabled = true; loadConversations(); } } // 加载会话列表 async function loadConversations() { try { const resp = await fetch("/api/conversations?open_kfid=" + encodeURIComponent(currentKfid)); const data = await resp.json(); conversations = data.conversations || []; renderConversations(); if (conversations.length === 0) { showToast('暂无会话,请先点击 同步拉取 获取消息', "error"); } } catch (e) { showToast("加载会话失败: " + e.message, "error"); } } // 渲染会话列表 function renderConversations() { const list = document.getElementById("conversationList"); if (conversations.length === 0) { list.innerHTML = '
暂无会话
'; return; } list.innerHTML = conversations.map(c => `
${c.external_userid}
${escapeHtml(c.latest_content || '[非文本消息]')}
${formatTime(c.latest_time)}
`).join(""); } // 选择会话 async function selectConversation(userid) { currentUser = userid; document.getElementById("msgHeader").textContent = "客户: " + userid; document.getElementById("sendBtn").disabled = false; document.getElementById("msgInput").disabled = false; renderConversations(); await loadMessages(userid); } // 加载消息 async function loadMessages(userid) { try { const resp = await fetch(`/api/messages?external_userid=${userid}&open_kfid=${encodeURIComponent(currentKfid)}`); const data = await resp.json(); const msgs = data.messages || []; renderMessages(msgs); } catch (e) { showToast("加载消息失败: " + e.message, "error"); } } // 渲染消息 function renderMessages(msgs) { const container = document.getElementById("messageList"); if (msgs.length === 0) { container.innerHTML = '
暂无消息
'; return; } container.innerHTML = msgs.map(m => `
${escapeHtml(m.content || `[${m.msgtype}]`)}
${formatTime(m.send_time)}
`).join(""); container.scrollTop = container.scrollHeight; } // 发送消息 async function sendMessage() { if (!currentUser) return; const input = document.getElementById("msgInput"); const content = input.value.trim(); if (!content) return; const btn = document.getElementById("sendBtn"); btn.disabled = true; btn.textContent = "发送中..."; try { const resp = await fetch("/api/send", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ external_userid: currentUser, content, open_kfid: currentKfid }), }); const result = await resp.json(); if (result.errcode === 0) { input.value = ""; showToast("发送成功"); await loadMessages(currentUser); } else { showToast("发送失败: " + (result.errmsg || JSON.stringify(result)), "error"); } } catch (e) { showToast("发送失败: " + e.message, "error"); } finally { btn.disabled = false; btn.textContent = "发送"; } } // 同步拉取 async function syncMessages() { const statusEl = document.getElementById("syncStatus"); statusEl.textContent = "同步中..."; try { const resp = await fetch("/api/sync", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ open_kfid: currentKfid }), }); const data = await resp.json(); if (data.errcode === 0) { showToast(`同步成功,获取 ${data.total} 条消息,新增入库 ${data.saved} 条`); await loadConversations(); if (currentUser) await loadMessages(currentUser); } else { showToast("同步失败: " + (data.errmsg || JSON.stringify(data)), "error"); } } catch (e) { showToast("同步失败: " + e.message, "error"); } finally { statusEl.textContent = ""; } } // 格式化时间 function formatTime(iso) { if (!iso) return ""; const d = new Date(iso); const pad = (n) => String(n).padStart(2, "0"); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`; } // HTML 转义 function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; }