diff --git a/app/routes/api.py b/app/routes/api.py index b2b8088..1259ee0 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -8,7 +8,7 @@ from app.services.message_service import ( send_and_save, 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 router = APIRouter(prefix="/api") @@ -77,3 +77,10 @@ async def sync_messages( "saved": saved, "total": len(msg_list), } + + +@router.get("/accounts") +async def get_accounts(): + """获取客服账号列表(用于查看正确的 open_kfid)""" + result = await list_accounts() + return result diff --git a/app/services/wechat_client.py b/app/services/wechat_client.py index ff23287..dcdc5e4 100644 --- a/app/services/wechat_client.py +++ b/app/services/wechat_client.py @@ -23,6 +23,16 @@ async def send_msg(touser: str, open_kfid: str, msgtype: str, content: str) -> d 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: """拉取客服消息(轮询模式)""" 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: resp = await client.post(url, json=body) 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() diff --git a/app/static/app.js b/app/static/app.js index 493fc38..8562f47 100644 --- a/app/static/app.js +++ b/app/static/app.js @@ -2,8 +2,11 @@ let currentUser = ""; let conversations = []; +let currentKfid = ""; + // 初始化 document.addEventListener("DOMContentLoaded", () => { + fetchAccounts(); loadConversations(); }); @@ -17,6 +20,31 @@ function showToast(msg, type = "success") { 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() { try { @@ -129,7 +157,7 @@ async function syncMessages() { const resp = await fetch("/api/sync", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({}), + body: JSON.stringify({ open_kfid: currentKfid }), }); const data = await resp.json(); if (data.errcode === 0) { diff --git a/app/templates/index.html b/app/templates/index.html index fac6f2d..d65ff0a 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -54,7 +54,11 @@