Initial upload for secondary development

This commit is contained in:
2026-06-08 19:00:03 +08:00
commit b913b8c78c
81 changed files with 27139 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
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}