新增客服重定向接口
This commit is contained in:
@@ -16,6 +16,7 @@ load_dotenv()
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
from rag2_0.intent_recognition import AsyncIntentRecognizer
|
from rag2_0.intent_recognition import AsyncIntentRecognizer
|
||||||
|
from rag2_0.api.kefu_redirect_url import router as kefu_router
|
||||||
|
|
||||||
# 确保日志目录存在
|
# 确保日志目录存在
|
||||||
os.makedirs('data/logs', exist_ok=True)
|
os.makedirs('data/logs', exist_ok=True)
|
||||||
@@ -84,6 +85,9 @@ app.add_middleware(
|
|||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 注册外部路由
|
||||||
|
app.include_router(kefu_router)
|
||||||
|
|
||||||
# 全局变量存储AsyncIntentRecognizer实例
|
# 全局变量存储AsyncIntentRecognizer实例
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
from fastapi.responses import RedirectResponse
|
||||||
|
import os
|
||||||
|
import sqlite3
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
from queue import Queue, Full
|
||||||
|
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
# 以当前文件为基准的相对路径:../../data/db
|
||||||
|
PROJECT_ROOT = os.getcwd()
|
||||||
|
DB_DIR = os.path.join(PROJECT_ROOT, "data", "db")
|
||||||
|
DB_FILE = os.path.join(DB_DIR, "redirects.sqlite3")
|
||||||
|
TABLE_SQL = (
|
||||||
|
"CREATE TABLE IF NOT EXISTS redirects ("
|
||||||
|
" msg_id TEXT PRIMARY KEY,"
|
||||||
|
" url TEXT NOT NULL"
|
||||||
|
")"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_db():
|
||||||
|
"""确保数据库与表存在。"""
|
||||||
|
os.makedirs(DB_DIR, exist_ok=True)
|
||||||
|
with sqlite3.connect(DB_FILE) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute(TABLE_SQL)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def save_redirect(msg_id: str, url: str) -> None:
|
||||||
|
"""将 msg_id 与 url 写入 SQLite,若已存在则忽略。
|
||||||
|
|
||||||
|
使用 INSERT OR IGNORE 结合 PRIMARY KEY(msg_id) 来避免重复写入。
|
||||||
|
"""
|
||||||
|
_ensure_db()
|
||||||
|
with sqlite3.connect(DB_FILE) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute(
|
||||||
|
"INSERT OR IGNORE INTO redirects (msg_id, url) VALUES (?, ?)",
|
||||||
|
(msg_id, url),
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
# ========= 异步写库队列与后台线程 =========
|
||||||
|
_write_queue: "Queue[tuple[str, str]]" = Queue(maxsize=10000)
|
||||||
|
|
||||||
|
|
||||||
|
def _write_worker():
|
||||||
|
_ensure_db()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
msg_id, url = _write_queue.get()
|
||||||
|
try:
|
||||||
|
with sqlite3.connect(DB_FILE) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute(
|
||||||
|
"INSERT OR IGNORE INTO redirects (msg_id, url) VALUES (?, ?)",
|
||||||
|
(msg_id, url),
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
except Exception:
|
||||||
|
# 失败忽略,避免阻断工作线程
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
_write_queue.task_done()
|
||||||
|
except Exception:
|
||||||
|
# 防御性 sleep,避免异常导致CPU空转
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
_worker_thread = threading.Thread(target=_write_worker, daemon=True)
|
||||||
|
_worker_thread.start()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/kefu_login", summary="客服登录页重定向")
|
||||||
|
async def kefu_redirect(msg_id:str):
|
||||||
|
"""重定向到客服登录页。"""
|
||||||
|
target_url = "https://www.booway.com.cn/kefu/toLoginPage"
|
||||||
|
# 写入 SQLite:若 msg_id 已存在将不会重复写入
|
||||||
|
try:
|
||||||
|
if msg_id:
|
||||||
|
# 走异步队列
|
||||||
|
_write_queue.put_nowait((msg_id, target_url))
|
||||||
|
except Exception:
|
||||||
|
# 出于稳健性考虑,即使写库失败也不影响重定向
|
||||||
|
pass
|
||||||
|
return RedirectResponse(target_url, status_code=302)
|
||||||
|
|
||||||
Reference in New Issue
Block a user