Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

## 📝 项目概述

DEV 更新待办:

- 智能体的消息加载有问题
- 智能体的管理员的配置无法更新到用户层面


语析是一个强大的问答平台,结合了大模型 RAG 知识库与知识图谱技术,基于 Llamaindex + VueJS + FastAPI + Neo4j 构建。

**核心特点:**
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ dependencies = [
"openai>=1.76.0",
"opencv-python-headless>=4.11.0.86",
"paddleocr>=2.10.0",
"pyjwt>=2.8.0",
"pymilvus>=2.5.8",
"pymupdf>=1.25.5",
"python-dotenv>=1.1.0",
"python-jose[cryptography]>=3.4.0",
"python-multipart>=0.0.20",
"pyyaml>=6.0.2",
"qianfan>=0.4.12.3",
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ langchain
langsmith
langgraph
langchain-openai
langchain-community
langchain-community
PyJWT>=2.10.1
14 changes: 11 additions & 3 deletions server/db_manager.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import os
import sqlite3
import pathlib
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

from server.models.token_model import Base, AgentToken
from server.models import Base
from server.models.user_model import User

class DBManager:
"""数据库管理器"""
Expand All @@ -32,6 +31,15 @@ def create_tables(self):
"""创建数据库表"""
Base.metadata.create_all(self.engine)

def check_first_run(self):
"""检查是否首次运行"""
session = self.get_session()
try:
# 检查是否有任何用户存在
return session.query(User).count() == 0
finally:
session.close()

def get_session(self):
"""获取数据库会话"""
return self.Session()
Expand Down
42 changes: 40 additions & 2 deletions server/main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import uvicorn

from fastapi import FastAPI
from fastapi import FastAPI, Request, HTTPException, status, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware

from server.routers import router
from server.utils.auth_middleware import is_public_path
from src.utils.logging_config import logger


app = FastAPI()
app.include_router(router)
app.include_router(router, prefix="/api")

# CORS 设置
app.add_middleware(
Expand All @@ -18,6 +22,40 @@
allow_headers=["*"],
)

# 鉴权中间件
class AuthMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# 获取请求路径
path = request.url.path

# 检查是否为公开路径,公开路径无需身份验证
if is_public_path(path):
return await call_next(request)

if not path.startswith("/api"):
# 非API路径,可能是前端路由或静态资源
return await call_next(request)

# # 提取Authorization头
# auth_header = request.headers.get("Authorization")
# if not auth_header or not auth_header.startswith("Bearer "):
# return JSONResponse(
# status_code=status.HTTP_401_UNAUTHORIZED,
# content={"detail": f"请先登录。Path: {path}"},
# headers={"WWW-Authenticate": "Bearer"}
# )

# # 获取token
# token = auth_header.split("Bearer ")[1]

# # 添加token到请求状态,后续路由可以直接使用
# request.state.token = token

# 继续处理请求
return await call_next(request)

# 添加鉴权中间件
app.add_middleware(AuthMiddleware)

if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=5050, threads=10, workers=10, reload=True)
Expand Down
3 changes: 3 additions & 0 deletions server/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
24 changes: 0 additions & 24 deletions server/models/token_model.py

This file was deleted.

55 changes: 55 additions & 0 deletions server/models/user_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Text
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship

from server.models import Base

class User(Base):
"""用户模型"""
__tablename__ = 'users'

id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String, nullable=False, unique=True, index=True)
password_hash = Column(String, nullable=False)
role = Column(String, nullable=False, default='user') # 角色: superadmin, admin, user
created_at = Column(DateTime, default=func.now())
last_login = Column(DateTime, nullable=True)

# 关联操作日志
operation_logs = relationship("OperationLog", back_populates="user")

def to_dict(self, include_password=False):
result = {
"id": self.id,
"username": self.username,
"role": self.role,
"created_at": self.created_at.isoformat() if self.created_at else None,
"last_login": self.last_login.isoformat() if self.last_login else None
}
if include_password:
result["password_hash"] = self.password_hash
return result

class OperationLog(Base):
"""操作日志模型"""
__tablename__ = 'operation_logs'

id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
operation = Column(String, nullable=False)
details = Column(Text, nullable=True)
ip_address = Column(String, nullable=True)
timestamp = Column(DateTime, default=func.now())

# 关联用户
user = relationship("User", back_populates="operation_logs")

def to_dict(self):
return {
"id": self.id,
"user_id": self.user_id,
"operation": self.operation,
"details": self.details,
"ip_address": self.ip_address,
"timestamp": self.timestamp.isoformat() if self.timestamp else None
}
6 changes: 2 additions & 4 deletions server/routers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
from server.routers.chat_router import chat
from server.routers.data_router import data
from server.routers.base_router import base
from server.routers.tool_router import tool
from server.routers.admin_router import admin
from server.routers.auth_router import auth

router = APIRouter()
router.include_router(base)
router.include_router(chat)
router.include_router(data)
router.include_router(tool)
router.include_router(admin)
router.include_router(auth)
103 changes: 0 additions & 103 deletions server/routers/admin_router.py

This file was deleted.

Loading