db9d10a795
- 新增 import_obsidian_kb.py 批量导入脚本(164篇入库,知识库186条) - parse_md_file 补强:来源fallback、相关装备/应用领域实体提取、 Obsidian双链去括号、原始类别/源文件路径存metadata、TYPE_MAP扩充 - search_similar 改进:智能摘要(中文2-gram拆词+加权段落匹配)、 min_similarity=0.3过滤、top_k 5→10、返回完整content_md - 前端搜索卡片升级:展开全文、关键词加粗渲染、相关度分档样式 - CLAUDE.md 状态更新 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
139 lines
4.2 KiB
Python
139 lines
4.2 KiB
Python
"""
|
||
知识库 API — 上传 / 列表 / 删除 / 来源筛选 / 语义搜索
|
||
"""
|
||
|
||
from typing import Optional
|
||
from pydantic import BaseModel
|
||
|
||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Query, status
|
||
from sqlmodel import Session
|
||
|
||
from app.core.deps import get_current_user, require_role
|
||
from app.db.session import get_session
|
||
from app.models.user import User, UserRole
|
||
from app.services.knowledge_service import KnowledgeService
|
||
|
||
|
||
router = APIRouter(prefix="/api/knowledge", tags=["知识库"])
|
||
|
||
|
||
@router.post("/upload")
|
||
async def upload_md_files(
|
||
files: list[UploadFile] = File(...),
|
||
session: Session = Depends(get_session),
|
||
current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian)),
|
||
):
|
||
"""
|
||
上传单个或多个 .md 文件,解析 frontmatter,写入知识库(含向量)。
|
||
仅制片人/责编可用。
|
||
"""
|
||
svc = KnowledgeService()
|
||
results = []
|
||
errors = []
|
||
|
||
for f in files:
|
||
if not f.filename.endswith(".md"):
|
||
errors.append({"file": f.filename, "error": "仅支持 .md 文件"})
|
||
continue
|
||
try:
|
||
content = await f.read()
|
||
item = svc.store_md_file(content, f.filename)
|
||
results.append({
|
||
"id": item.id,
|
||
"title": item.title,
|
||
"source_type": item.source_type,
|
||
})
|
||
except Exception as e:
|
||
errors.append({"file": f.filename, "error": str(e)})
|
||
|
||
return {"uploaded": results, "errors": errors}
|
||
|
||
|
||
@router.get("/items")
|
||
def list_knowledge_items(
|
||
source_type: Optional[str] = Query(None),
|
||
session: Session = Depends(get_session),
|
||
current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian, UserRole.biandao)),
|
||
):
|
||
"""
|
||
知识库列表,支持按 source_type 筛选。三角色均可读。
|
||
"""
|
||
svc = KnowledgeService()
|
||
items = svc.list_items(source_type=source_type)
|
||
return items
|
||
|
||
|
||
@router.delete("/items/{item_id}")
|
||
def delete_knowledge_item(
|
||
item_id: int,
|
||
session: Session = Depends(get_session),
|
||
current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian)),
|
||
):
|
||
"""
|
||
删除知识库条目(级联删除向量)。仅制片人/责编可用。
|
||
"""
|
||
svc = KnowledgeService()
|
||
deleted = svc.delete_item(item_id)
|
||
if not deleted:
|
||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="条目不存在")
|
||
return {"message": "删除成功"}
|
||
|
||
|
||
@router.get("/sources")
|
||
def list_distinct_sources(
|
||
session: Session = Depends(get_session),
|
||
current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian, UserRole.biandao)),
|
||
):
|
||
"""
|
||
返回库里所有不重复的具体出处(source_detail),供来源筛选下拉动态生成。
|
||
三角色均可读。
|
||
"""
|
||
svc = KnowledgeService()
|
||
sources = svc.get_distinct_sources()
|
||
return [{"source": s} for s in sources]
|
||
|
||
|
||
@router.get("/grouped")
|
||
def get_grouped_knowledge_items(
|
||
session: Session = Depends(get_session),
|
||
current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian, UserRole.biandao)),
|
||
):
|
||
"""
|
||
返回按 source_type → source_detail 两层聚合的树形结构,
|
||
含「全部」根节点,供知识库树形导航使用。
|
||
三角色均可读。
|
||
"""
|
||
svc = KnowledgeService()
|
||
return svc.get_grouped_items()
|
||
|
||
|
||
class SearchRequest(BaseModel):
|
||
query: str
|
||
top_k: int = 10
|
||
min_similarity: float = 0.3
|
||
|
||
|
||
@router.post("/search")
|
||
def search_knowledge(
|
||
body: SearchRequest,
|
||
session: Session = Depends(get_session),
|
||
current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian, UserRole.biandao)),
|
||
):
|
||
"""
|
||
语义检索:输入一段文字,返回最相关的知识库条目及相似度。
|
||
查询向量用 type="query"(区分于存入时的 type="db")。
|
||
top_k 默认 10,min_similarity 默认 0.3 过滤低相关条目。
|
||
三角色均可读。
|
||
"""
|
||
svc = KnowledgeService()
|
||
results = svc.search_similar(
|
||
query_text=body.query,
|
||
top_k=body.top_k,
|
||
min_similarity=body.min_similarity,
|
||
)
|
||
return {
|
||
"results": results,
|
||
"query": body.query,
|
||
"count": len(results),
|
||
}
|