加字体大小设置,修复人工客服轮询和限流问题
This commit is contained in:
+76
-50
@@ -62,97 +62,123 @@ th,td{padding:6px 10px;border-bottom:1px solid #eee;text-align:left;}
|
||||
<a href="/">← 返回客服页</a>
|
||||
|
||||
<script>
|
||||
let curSid = 0;
|
||||
let lastId = 0;
|
||||
const sessions = {}; // sid -> {lastId, msgs:[]}
|
||||
var curSid = 0;
|
||||
var sessions = {};
|
||||
|
||||
fetch("/api/admin/stats").then(r=>r.json()).then(d=>{
|
||||
fetch("/api/admin/stats").then(function(r){return r.json()}).then(function(d){
|
||||
s1.textContent=d.total_conv; s2.textContent=d.total_msg;
|
||||
s3.textContent=d.today_conv; s4.textContent=d.good; s5.textContent=d.bad;
|
||||
});
|
||||
|
||||
function loadQueue(){
|
||||
fetch("/api/human/queue").then(r=>r.json()).then(list=>{
|
||||
fetch("/api/human/queue").then(function(r){return r.json()}).then(function(list){
|
||||
document.getElementById("queue").innerHTML = list.length
|
||||
? list.map(x=>`<button class="btn" onclick="accept(${x.id})">#${x.id} ${x.ctime}</button>`).join(" ")
|
||||
? list.map(function(x){return '<button class="btn" onclick="accept('+x.id+')">#'+x.id+' '+x.ctime+'</button>'}).join(" ")
|
||||
: "暂无";
|
||||
});
|
||||
}
|
||||
loadQueue(); setInterval(loadQueue, 3000);
|
||||
|
||||
// 自动接入等待的客户
|
||||
setInterval(()=>{
|
||||
fetch("/api/human/queue").then(r=>r.json()).then(list=>{
|
||||
if(list.length && !sessions[list[0].id]){
|
||||
accept(list[0].id);
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
setInterval(loadQueue, 3000);
|
||||
|
||||
// 加载已有进行中的对话
|
||||
fetch("/api/human/active").then(function(r){return r.json()}).then(function(list){
|
||||
list.forEach(function(s){
|
||||
sessions[String(s.id)] = {lastId:0, msgs:[], unread:0};
|
||||
});
|
||||
renderSessionList();
|
||||
if(list.length && !curSid) switchSession(String(list[0].id));
|
||||
});
|
||||
|
||||
function accept(sid){
|
||||
fetch("/api/human/accept",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sid})}).then(()=>{
|
||||
sessions[sid] = {lastId:0};
|
||||
sid = String(sid);
|
||||
if(sessions[sid]) return;
|
||||
fetch("/api/human/accept",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sid:parseInt(sid)})}).then(function(){
|
||||
sessions[sid] = {lastId:0, msgs:[], unread:0};
|
||||
switchSession(sid);
|
||||
});
|
||||
}
|
||||
|
||||
function switchSession(sid){
|
||||
curSid = sid;
|
||||
lastId = sessions[sid].lastId;
|
||||
curSid = String(sid);
|
||||
document.getElementById("chatCard").style.display="block";
|
||||
document.getElementById("chatTitle").textContent="对话 #"+sid;
|
||||
// 渲染已有消息
|
||||
document.getElementById("chatBox").innerHTML = "";
|
||||
sessions[sid].msgs.forEach(m=>{
|
||||
const div=document.createElement("div");
|
||||
div.className="msg "+(m.side==="customer"?"cust":"agent");
|
||||
div.textContent=(m.side==="customer"?"客户: ":"客服: ")+m.content;
|
||||
document.getElementById("chatBox").appendChild(div);
|
||||
sessions[sid].msgs.forEach(function(m){
|
||||
appendMsg(m);
|
||||
});
|
||||
sessions[sid].unread = 0;
|
||||
renderSessionList();
|
||||
}
|
||||
|
||||
function appendMsg(m){
|
||||
var div=document.createElement("div");
|
||||
div.className="msg "+(m.side==="customer"?"cust":"agent");
|
||||
div.textContent=(m.side==="customer"?"客户: ":"客服: ")+m.content;
|
||||
document.getElementById("chatBox").appendChild(div);
|
||||
document.getElementById("chatBox").scrollTop=999999;
|
||||
}
|
||||
|
||||
function renderSessionList(){
|
||||
const el=document.getElementById("sessionList");
|
||||
var el=document.getElementById("sessionList");
|
||||
el.innerHTML="";
|
||||
Object.keys(sessions).forEach(sid=>{
|
||||
const div=document.createElement("div");
|
||||
Object.keys(sessions).forEach(function(sid){
|
||||
var unread = sessions[sid].unread || 0;
|
||||
var div=document.createElement("div");
|
||||
div.className="session-item"+(sid==curSid?" active":"");
|
||||
div.textContent="对话 #"+sid;
|
||||
div.onclick=()=>switchSession(sid);
|
||||
div.innerHTML="对话 #"+sid+(unread>0?'<span class="badge">'+unread+'</span>':"");
|
||||
div.onclick=function(){ switchSession(sid); };
|
||||
el.appendChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
function poll(){
|
||||
Object.keys(sessions).forEach(sid=>{
|
||||
fetch("/api/human/poll?sid="+sid+"&after="+sessions[sid].lastId).then(r=>r.json()).then(d=>{
|
||||
d.messages.forEach(m=>{
|
||||
sessions[sid].lastId=m.id;
|
||||
sessions[sid].msgs.push(m);
|
||||
if(sid==curSid){
|
||||
const div=document.createElement("div");
|
||||
div.className="msg "+(m.side==="customer"?"cust":"agent");
|
||||
div.textContent=(m.side==="customer"?"客户: ":"客服: ")+m.content;
|
||||
document.getElementById("chatBox").appendChild(div);
|
||||
document.getElementById("chatBox").scrollTop=999999;
|
||||
// 先拉所有进行中的会话
|
||||
fetch("/api/human/active").then(function(r){return r.json()}).then(function(list){
|
||||
list.forEach(function(s){
|
||||
if(!sessions[String(s.id)]){
|
||||
sessions[String(s.id)] = {lastId:0, msgs:[], unread:0};
|
||||
}
|
||||
});
|
||||
renderSessionList();
|
||||
}).then(function(){
|
||||
Object.keys(sessions).forEach(function(sid){
|
||||
fetch("/api/human/poll?sid="+parseInt(sid)+"&after="+sessions[sid].lastId)
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(d){
|
||||
if(d.status==="closed"){
|
||||
delete sessions[sid];
|
||||
if(sid==curSid){ curSid=0; document.getElementById("chatCard").style.display="none"; }
|
||||
renderSessionList();
|
||||
return;
|
||||
}
|
||||
});
|
||||
d.messages.forEach(function(m){
|
||||
sessions[sid].lastId=m.id;
|
||||
sessions[sid].msgs.push(m);
|
||||
if(m.side==="customer" && sid!=curSid){
|
||||
sessions[sid].unread=(sessions[sid].unread||0)+1;
|
||||
renderSessionList();
|
||||
}
|
||||
if(sid==curSid) appendMsg(m);
|
||||
});
|
||||
})
|
||||
.catch(function(){});
|
||||
});
|
||||
});
|
||||
setTimeout(poll, 2000);
|
||||
}
|
||||
poll();
|
||||
setInterval(poll, 1000);
|
||||
|
||||
function sendReply(){
|
||||
const t=document.getElementById("replyText").value.trim();
|
||||
var t=document.getElementById("replyText").value.trim();
|
||||
if(!t || !curSid) return;
|
||||
fetch("/api/human/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sid:curSid,side:"agent",content:t})});
|
||||
fetch("/api/human/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sid:parseInt(curSid),side:"agent",content:t})});
|
||||
document.getElementById("replyText").value="";
|
||||
document.getElementById("replyText").focus();
|
||||
}
|
||||
|
||||
function closeSession(){
|
||||
fetch("/api/human/close",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sid:curSid})});
|
||||
fetch("/api/human/close",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sid:parseInt(curSid)})});
|
||||
delete sessions[curSid];
|
||||
curSid=0;
|
||||
document.getElementById("chatCard").style.display="none";
|
||||
@@ -163,10 +189,10 @@ document.getElementById("replyText").addEventListener("keydown", function(e){
|
||||
if(e.key==="Enter"){ e.preventDefault(); sendReply(); }
|
||||
});
|
||||
|
||||
fetch("/api/get_history").then(r=>r.json()).then(list=>{
|
||||
const tb=document.getElementById("tbl");
|
||||
list.slice(0,20).forEach(c=>{
|
||||
tb.innerHTML+=`<tr><td>${c.id}</td><td>${c.title}</td><td>${c.utime||c.ctime}</td></tr>`;
|
||||
fetch("/api/get_history").then(function(r){return r.json()}).then(function(list){
|
||||
var tb=document.getElementById("tbl");
|
||||
list.slice(0,20).forEach(function(c){
|
||||
tb.innerHTML+="<tr><td>"+c.id+"</td><td>"+c.title+"</td><td>"+(c.utime||c.ctime)+"</td></tr>";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user