feat: 完成全量功能开发,包括前端管理后台与后端服务优化
此提交实现了完整的知识库管理系统: 1. 新增Vue3 + Antd Vue前端管理后台,包含登录、文档管理、检索、类目设置等完整页面 2. 重构后端LLM调用抽象层,支持Ollama与OpenAI兼容服务动态切换 3. 调整默认嵌入模型配置为本地bge-m3模式 4. 优化入库任务去重逻辑与缓存清理机制 5. 完善Docker镜像构建与docker-compose部署配置 6. 修复多项测试用例与兼容性问题 7. 新增运行时配置API,支持动态调整系统参数
This commit is contained in:
+50
-4
@@ -5,13 +5,14 @@ from pathlib import Path
|
||||
import structlog
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
|
||||
|
||||
from app.api.response import ApiError, error
|
||||
from app.api.v1.auth import router as auth_router
|
||||
from app.api.v1.document import router as document_router
|
||||
from app.api.v1.knowledge import router as knowledge_router
|
||||
from app.api.v1.search import router as search_router
|
||||
from app.api.v1.settings import router as settings_router
|
||||
from app.config import settings
|
||||
from app.core.auth import ensure_default_admin
|
||||
from app.services.qdrant import QdrantService
|
||||
@@ -53,6 +54,7 @@ app.include_router(auth_router)
|
||||
app.include_router(search_router)
|
||||
app.include_router(document_router)
|
||||
app.include_router(knowledge_router)
|
||||
app.include_router(settings_router)
|
||||
|
||||
|
||||
@app.exception_handler(ApiError)
|
||||
@@ -84,10 +86,54 @@ async def health() -> dict[str, str]:
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
_ADMIN_HTML = Path(__file__).resolve().parent / "static" / "admin.html"
|
||||
_STATIC_DIR = Path(__file__).resolve().parent / "static"
|
||||
_ADMIN_HTML = _STATIC_DIR / "admin.html"
|
||||
_ADMIN_SPA_DIR = _STATIC_DIR / "admin"
|
||||
|
||||
|
||||
def _spa_index() -> Path | None:
|
||||
"""SPA 入口文件路径;不存在返回 None(回退旧 admin.html)"""
|
||||
index = _ADMIN_SPA_DIR / "index.html"
|
||||
return index if index.is_file() else None
|
||||
|
||||
|
||||
@app.get("/admin", include_in_schema=False)
|
||||
async def admin_page() -> FileResponse:
|
||||
"""管理后台单页(单文件静态 HTML,零外部依赖)"""
|
||||
async def admin_page():
|
||||
"""管理后台:优先服务 Vue SPA,回退到旧单文件 admin.html"""
|
||||
spa = _spa_index()
|
||||
if spa is not None:
|
||||
return FileResponse(spa, media_type="text/html")
|
||||
return FileResponse(_ADMIN_HTML, media_type="text/html")
|
||||
|
||||
|
||||
@app.get("/admin/", include_in_schema=False)
|
||||
async def admin_page_trailing_slash():
|
||||
"""带斜杠的 /admin/ 重定向到 /admin"""
|
||||
return RedirectResponse(url="/admin", status_code=307)
|
||||
|
||||
|
||||
@app.get("/admin/{rest:path}", include_in_schema=False)
|
||||
async def admin_spa(rest: str):
|
||||
"""SPA 静态资源与客户端路由兜底
|
||||
|
||||
- 真实文件(assets/*.js, *.css 等)→ 直接返回
|
||||
- 其余路径(/overview, /documents 等客户端路由)→ 返回 index.html
|
||||
- SPA 目录不存在时 → 404(旧 admin.html 无子路由需求)
|
||||
"""
|
||||
spa_dir = _ADMIN_SPA_DIR
|
||||
if not spa_dir.is_dir():
|
||||
return JSONResponse(
|
||||
status_code=404, content={"code": 1002, "message": "Not found"}
|
||||
)
|
||||
|
||||
# 安全校验:防止路径越界
|
||||
file_path = (spa_dir / rest).resolve()
|
||||
try:
|
||||
file_path.relative_to(spa_dir.resolve())
|
||||
except ValueError:
|
||||
return FileResponse(spa_dir / "index.html", media_type="text/html")
|
||||
|
||||
if file_path.is_file():
|
||||
return FileResponse(file_path)
|
||||
# SPA 客户端路由兜底
|
||||
return FileResponse(spa_dir / "index.html", media_type="text/html")
|
||||
|
||||
Reference in New Issue
Block a user