68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from pydantic import BaseModel
|
|
from typing import Optional
|
|
import aiosqlite
|
|
from database import get_db
|
|
|
|
router = APIRouter(prefix="/api/knowledge", tags=["knowledge"])
|
|
|
|
class KnowledgePatch(BaseModel):
|
|
content: str
|
|
|
|
@router.get("")
|
|
async def list_knowledge(
|
|
keyword: Optional[str] = None,
|
|
db: aiosqlite.Connection = Depends(get_db)
|
|
):
|
|
if keyword:
|
|
# FTS5 查询前先用 jieba 分词,提高中文召回率
|
|
from services.fts import build_match_query
|
|
fts_query = build_match_query(keyword)
|
|
if not fts_query:
|
|
return []
|
|
async with db.execute(
|
|
"SELECT k.id, k.topic_id, k.created_at, k.updated_at, t.title, t.group_id, g.name as group_name "
|
|
"FROM knowledge_docs k JOIN topics t ON k.topic_id=t.id "
|
|
"LEFT JOIN groups g ON t.group_id=g.id "
|
|
"WHERE k.id IN (SELECT doc_id FROM knowledge_fts WHERE knowledge_fts MATCH ?)",
|
|
(fts_query,)
|
|
) as cur:
|
|
return [dict(r) for r in await cur.fetchall()]
|
|
async with db.execute(
|
|
"SELECT k.id, k.topic_id, k.created_at, k.updated_at, t.title, t.group_id, g.name as group_name "
|
|
"FROM knowledge_docs k JOIN topics t ON k.topic_id=t.id "
|
|
"LEFT JOIN groups g ON t.group_id=g.id "
|
|
"ORDER BY g.name, k.updated_at DESC"
|
|
) as cur:
|
|
return [dict(r) for r in await cur.fetchall()]
|
|
|
|
@router.get("/{doc_id}")
|
|
async def get_knowledge(doc_id: int, db: aiosqlite.Connection = Depends(get_db)):
|
|
async with db.execute("SELECT * FROM knowledge_docs WHERE id=?", (doc_id,)) as cur:
|
|
row = await cur.fetchone()
|
|
if not row:
|
|
raise HTTPException(404, "not found")
|
|
return dict(row)
|
|
|
|
@router.patch("/{doc_id}")
|
|
async def patch_knowledge(doc_id: int, body: KnowledgePatch, db: aiosqlite.Connection = Depends(get_db)):
|
|
await db.execute(
|
|
"UPDATE knowledge_docs SET content=?, updated_at=CURRENT_TIMESTAMP, curated_at=CURRENT_TIMESTAMP WHERE id=?",
|
|
(body.content, doc_id)
|
|
)
|
|
await db.commit()
|
|
# update FTS
|
|
async with db.execute("SELECT topic_id FROM knowledge_docs WHERE id=?", (doc_id,)) as cur:
|
|
row = await cur.fetchone()
|
|
if row:
|
|
async with db.execute("SELECT title FROM topics WHERE id=?", (row["topic_id"],)) as cur:
|
|
topic = await cur.fetchone()
|
|
await db.execute("DELETE FROM knowledge_fts WHERE doc_id=?", (doc_id,))
|
|
from services.fts import tokenize
|
|
await db.execute(
|
|
"INSERT INTO knowledge_fts (doc_id, title, content) VALUES (?, ?, ?)",
|
|
(doc_id, tokenize(topic["title"]), tokenize(body.content))
|
|
)
|
|
await db.commit()
|
|
return {"ok": True}
|