This commit is contained in:
amb
2026-09-01 14:49:07 +08:00
parent 4db2d1a411
commit 70ece67910
8 changed files with 495 additions and 9 deletions
+24
View File
@@ -18,11 +18,27 @@ from app.api.deps import get_db
from app.core.errors import NotFoundError, RateLimitedError
from app.core.rate_limit import check_rate_limit
from app.core.security import decrypt_token
from app.services.access_log_service import AccessLogService
from app.services.kb_public_service import KbPublicService
router = APIRouter(prefix="/k", tags=["public"])
def _log_access(db: Session, kb_id: str, path: str, request: Request, doc_id: str | None = None, req_type: str | None = None) -> None:
"""记录访问日志(best-effort,不阻塞响应)。"""
try:
ua = request.headers.get("user-agent", "")
AccessLogService(db).record(
knowledge_base_id=kb_id,
document_id=doc_id,
path=path,
user_agent=ua,
request_type=req_type,
)
except Exception:
pass # 日志失败不影响响应
def _rate_limit(request: Request, token: str) -> None:
"""限流检查。"""
ip = request.client.host if request.client else "unknown"
@@ -51,6 +67,7 @@ def kb_index_markdown(
_rate_limit(request, token)
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
_log_access(db, kb.id, f"/k/{token}.md", request, req_type="md")
docs, _ = svc.list_documents(kb)
lines = [f"# {kb.name}", ""]
@@ -87,6 +104,7 @@ def kb_index_text(
_rate_limit(request, token)
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
_log_access(db, kb.id, f"/k/{token}.txt", request, req_type="txt")
docs, _ = svc.list_documents(kb)
lines = [kb.name, "=" * len(kb.name), ""]
@@ -119,6 +137,7 @@ def kb_index_json(
_rate_limit(request, token)
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
_log_access(db, kb.id, f"/k/{token}.json", request, req_type="json")
docs, _ = svc.list_documents(kb)
doc_list = []
@@ -156,6 +175,7 @@ def kb_index_html(
_rate_limit(request, token)
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
_log_access(db, kb.id, f"/k/{token}", request, req_type="html")
docs, total = svc.list_documents(kb, page=page, page_size=50)
doc_rows = ""
@@ -232,6 +252,7 @@ def doc_page_html(
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
doc = svc.get_document_by_token(kb, doc_token)
_log_access(db, kb.id, f"/k/{token}/doc/{doc_token}", request, doc_id=doc.id, req_type="doc_html")
markdown_content = svc.get_document_markdown(doc)
# Markdown → HTML(简单转换)
@@ -291,6 +312,7 @@ def doc_page_markdown(
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
doc = svc.get_document_by_token(kb, doc_token)
_log_access(db, kb.id, f"/k/{token}/doc/{doc_token}.md", request, doc_id=doc.id, req_type="doc_md")
markdown_content = svc.get_document_markdown(doc)
return PlainTextResponse(content=markdown_content, media_type="text/markdown")
@@ -307,6 +329,7 @@ def doc_page_text(
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
doc = svc.get_document_by_token(kb, doc_token)
_log_access(db, kb.id, f"/k/{token}/doc/{doc_token}.txt", request, doc_id=doc.id, req_type="doc_txt")
markdown_content = svc.get_document_markdown(doc)
# 去掉 Markdown 标记
@@ -332,6 +355,7 @@ def search_html(
_rate_limit(request, token)
svc = KbPublicService(db)
kb = svc.get_kb_by_token(token)
_log_access(db, kb.id, f"/k/{token}/search?q={q}", request, req_type="search")
results, total = svc.search_documents(kb, q, page=page)
result_items = ""