updates
This commit is contained in:
parent
cedf46d3c9
commit
923f60f733
|
|
@ -8,7 +8,7 @@ from app.services.message_service import (
|
||||||
send_and_save,
|
send_and_save,
|
||||||
save_messages,
|
save_messages,
|
||||||
)
|
)
|
||||||
from app.services.wechat_client import sync_msg
|
from app.services.wechat_client import sync_msg, list_accounts
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
|
|
||||||
router = APIRouter(prefix="/api")
|
router = APIRouter(prefix="/api")
|
||||||
|
|
@ -77,3 +77,10 @@ async def sync_messages(
|
||||||
"saved": saved,
|
"saved": saved,
|
||||||
"total": len(msg_list),
|
"total": len(msg_list),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/accounts")
|
||||||
|
async def get_accounts():
|
||||||
|
"""获取客服账号列表(用于查看正确的 open_kfid)"""
|
||||||
|
result = await list_accounts()
|
||||||
|
return result
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,16 @@ async def send_msg(touser: str, open_kfid: str, msgtype: str, content: str) -> d
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
|
async def list_accounts(offset: int = 0, limit: int = 100) -> dict:
|
||||||
|
"""获取客服账号列表"""
|
||||||
|
access_token = await get_access_token()
|
||||||
|
url = f"{WECHAT_API_BASE}/cgi-bin/kf/account/list?access_token={access_token}"
|
||||||
|
body = {"offset": offset, "limit": limit}
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
resp = await client.post(url, json=body)
|
||||||
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
async def sync_msg(open_kfid: str, cursor: str = "", token: str = "", limit: int = 100) -> dict:
|
async def sync_msg(open_kfid: str, cursor: str = "", token: str = "", limit: int = 100) -> dict:
|
||||||
"""拉取客服消息(轮询模式)"""
|
"""拉取客服消息(轮询模式)"""
|
||||||
access_token = await get_access_token()
|
access_token = await get_access_token()
|
||||||
|
|
@ -38,3 +48,13 @@ async def sync_msg(open_kfid: str, cursor: str = "", token: str = "", limit: int
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
resp = await client.post(url, json=body)
|
resp = await client.post(url, json=body)
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
|
async def list_accounts(offset: int = 0, limit: int = 100) -> dict:
|
||||||
|
"""获取客服账号列表"""
|
||||||
|
access_token = await get_access_token()
|
||||||
|
url = f"{WECHAT_API_BASE}/cgi-bin/kf/account/list?access_token={access_token}"
|
||||||
|
body = {"offset": offset, "limit": limit}
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
resp = await client.post(url, json=body)
|
||||||
|
return resp.json()
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@
|
||||||
let currentUser = "";
|
let currentUser = "";
|
||||||
let conversations = [];
|
let conversations = [];
|
||||||
|
|
||||||
|
let currentKfid = "";
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
fetchAccounts();
|
||||||
loadConversations();
|
loadConversations();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -17,6 +20,31 @@ function showToast(msg, type = "success") {
|
||||||
setTimeout(() => { el.style.opacity = "0"; setTimeout(() => el.style.display = "none", 300); }, 2000);
|
setTimeout(() => { el.style.opacity = "0"; setTimeout(() => el.style.display = "none", 300); }, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取客服账号列表
|
||||||
|
async function fetchAccounts() {
|
||||||
|
try {
|
||||||
|
const resp = await fetch("/api/accounts");
|
||||||
|
const data = await resp.json();
|
||||||
|
const el = document.getElementById("currentKfid");
|
||||||
|
if (data.errcode === 0 && data.account_list && data.account_list.length > 0) {
|
||||||
|
const accounts = data.account_list;
|
||||||
|
currentKfid = accounts[0].open_kfid;
|
||||||
|
el.textContent = currentKfid;
|
||||||
|
el.style.color = "#07c160";
|
||||||
|
if (accounts.length > 1) {
|
||||||
|
showToast(`共 ${accounts.length} 个客服账号,默认使用: ${accounts[0].name || currentKfid}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
el.textContent = "获取失败";
|
||||||
|
el.style.color = "#f44336";
|
||||||
|
showToast("获取账号列表失败: " + (data.errmsg || "未知"), "error");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
document.getElementById("currentKfid").textContent = "请求失败";
|
||||||
|
showToast("获取账号列表失败: " + e.message, "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 加载会话列表
|
// 加载会话列表
|
||||||
async function loadConversations() {
|
async function loadConversations() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -129,7 +157,7 @@ async function syncMessages() {
|
||||||
const resp = await fetch("/api/sync", {
|
const resp = await fetch("/api/sync", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({}),
|
body: JSON.stringify({ open_kfid: currentKfid }),
|
||||||
});
|
});
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
if (data.errcode === 0) {
|
if (data.errcode === 0) {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,11 @@
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<h2>会话列表</h2>
|
<h2>会话列表</h2>
|
||||||
|
<div style="margin-bottom:6px;font-size:12px;color:#888;">
|
||||||
|
KFID: <span id="currentKfid">...</span>
|
||||||
|
</div>
|
||||||
<button onclick="syncMessages()">同步拉取</button>
|
<button onclick="syncMessages()">同步拉取</button>
|
||||||
|
<button onclick="fetchAccounts()" style="background:#576b95;margin-left:4px;">查账号</button>
|
||||||
<span id="syncStatus" style="font-size:12px;color:#888;margin-left:8px;"></span>
|
<span id="syncStatus" style="font-size:12px;color:#888;margin-left:8px;"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="conversation-list" id="conversationList"></div>
|
<div class="conversation-list" id="conversationList"></div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue