修改了API接口定义
parent
91aeeca9c8
commit
a243ee7e39
|
|
@ -1,8 +1,8 @@
|
||||||
from fastapi import APIRouter, HTTPException, Depends
|
from fastapi import APIRouter, Depends
|
||||||
from app.core.auth import get_current_admin_user
|
from app.core.auth import get_current_admin_user, get_current_user
|
||||||
from app.core.config import LLM_CONFIG, DEFAULT_RESET_PASSWORD, MAX_FILE_SIZE, MAX_IMAGE_SIZE
|
from app.core.config import LLM_CONFIG, DEFAULT_RESET_PASSWORD, MAX_FILE_SIZE, MAX_IMAGE_SIZE
|
||||||
|
from app.core.response import create_api_response
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
import os
|
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
@ -18,14 +18,6 @@ class SystemConfigModel(BaseModel):
|
||||||
MAX_FILE_SIZE: int # 字节为单位
|
MAX_FILE_SIZE: int # 字节为单位
|
||||||
MAX_IMAGE_SIZE: int # 字节为单位
|
MAX_IMAGE_SIZE: int # 字节为单位
|
||||||
|
|
||||||
class SystemConfigResponse(BaseModel):
|
|
||||||
model_name: str
|
|
||||||
system_prompt: str
|
|
||||||
DEFAULT_RESET_PASSWORD: str
|
|
||||||
MAX_FILE_SIZE: int
|
|
||||||
MAX_IMAGE_SIZE: int
|
|
||||||
message: str = ""
|
|
||||||
|
|
||||||
def load_config_from_file():
|
def load_config_from_file():
|
||||||
"""从文件加载配置,如果文件不存在则返回默认配置"""
|
"""从文件加载配置,如果文件不存在则返回默认配置"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -47,9 +39,7 @@ def load_config_from_file():
|
||||||
def save_config_to_file(config_data):
|
def save_config_to_file(config_data):
|
||||||
"""将配置保存到文件"""
|
"""将配置保存到文件"""
|
||||||
try:
|
try:
|
||||||
# 确保配置目录存在
|
|
||||||
CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
|
CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
|
||||||
json.dump(config_data, f, ensure_ascii=False, indent=2)
|
json.dump(config_data, f, ensure_ascii=False, indent=2)
|
||||||
return True
|
return True
|
||||||
|
|
@ -57,28 +47,26 @@ def save_config_to_file(config_data):
|
||||||
print(f"保存配置文件失败: {e}")
|
print(f"保存配置文件失败: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@router.get("/admin/system-config", response_model=SystemConfigResponse)
|
@router.get("/admin/system-config")
|
||||||
async def get_system_config(current_user=Depends(get_current_admin_user)):
|
async def get_system_config(current_user=Depends(get_current_user)):
|
||||||
"""
|
"""
|
||||||
获取系统配置
|
获取系统配置
|
||||||
只有管理员才能访问
|
普通用户也可以获取
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 优先从文件加载配置,然后从内存配置补充
|
|
||||||
config = load_config_from_file()
|
config = load_config_from_file()
|
||||||
|
response_data = {
|
||||||
return SystemConfigResponse(
|
'model_name': config.get('model_name', LLM_CONFIG['model_name']),
|
||||||
model_name=config.get('model_name', LLM_CONFIG['model_name']),
|
'system_prompt': config.get('system_prompt', LLM_CONFIG['system_prompt']),
|
||||||
system_prompt=config.get('system_prompt', LLM_CONFIG['system_prompt']),
|
'DEFAULT_RESET_PASSWORD': config.get('DEFAULT_RESET_PASSWORD', DEFAULT_RESET_PASSWORD),
|
||||||
DEFAULT_RESET_PASSWORD=config.get('DEFAULT_RESET_PASSWORD', DEFAULT_RESET_PASSWORD),
|
'MAX_FILE_SIZE': config.get('MAX_FILE_SIZE', MAX_FILE_SIZE),
|
||||||
MAX_FILE_SIZE=config.get('MAX_FILE_SIZE', MAX_FILE_SIZE),
|
'MAX_IMAGE_SIZE': config.get('MAX_IMAGE_SIZE', MAX_IMAGE_SIZE),
|
||||||
MAX_IMAGE_SIZE=config.get('MAX_IMAGE_SIZE', MAX_IMAGE_SIZE),
|
}
|
||||||
message="配置获取成功"
|
return create_api_response(code="200", message="配置获取成功", data=response_data)
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=500, detail=f"获取配置失败: {str(e)}")
|
return create_api_response(code="500", message=f"获取配置失败: {str(e)}")
|
||||||
|
|
||||||
@router.put("/admin/system-config", response_model=SystemConfigResponse)
|
@router.put("/admin/system-config")
|
||||||
async def update_system_config(
|
async def update_system_config(
|
||||||
config: SystemConfigModel,
|
config: SystemConfigModel,
|
||||||
current_user=Depends(get_current_admin_user)
|
current_user=Depends(get_current_admin_user)
|
||||||
|
|
@ -88,7 +76,6 @@ async def update_system_config(
|
||||||
只有管理员才能访问
|
只有管理员才能访问
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 准备要保存的配置数据
|
|
||||||
config_data = {
|
config_data = {
|
||||||
'model_name': config.model_name,
|
'model_name': config.model_name,
|
||||||
'system_prompt': config.system_prompt,
|
'system_prompt': config.system_prompt,
|
||||||
|
|
@ -97,49 +84,36 @@ async def update_system_config(
|
||||||
'MAX_IMAGE_SIZE': config.MAX_IMAGE_SIZE
|
'MAX_IMAGE_SIZE': config.MAX_IMAGE_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
# 保存到文件
|
|
||||||
if not save_config_to_file(config_data):
|
if not save_config_to_file(config_data):
|
||||||
raise HTTPException(status_code=500, detail="配置保存到文件失败")
|
return create_api_response(code="500", message="配置保存到文件失败")
|
||||||
|
|
||||||
# 更新运行时配置
|
# 更新运行时配置
|
||||||
LLM_CONFIG['model_name'] = config.model_name
|
LLM_CONFIG['model_name'] = config.model_name
|
||||||
LLM_CONFIG['system_prompt'] = config.system_prompt
|
LLM_CONFIG['system_prompt'] = config.system_prompt
|
||||||
|
|
||||||
# 更新模块级别的配置
|
|
||||||
import app.core.config as config_module
|
import app.core.config as config_module
|
||||||
config_module.DEFAULT_RESET_PASSWORD = config.DEFAULT_RESET_PASSWORD
|
config_module.DEFAULT_RESET_PASSWORD = config.DEFAULT_RESET_PASSWORD
|
||||||
config_module.MAX_FILE_SIZE = config.MAX_FILE_SIZE
|
config_module.MAX_FILE_SIZE = config.MAX_FILE_SIZE
|
||||||
config_module.MAX_IMAGE_SIZE = config.MAX_IMAGE_SIZE
|
config_module.MAX_IMAGE_SIZE = config.MAX_IMAGE_SIZE
|
||||||
|
|
||||||
return SystemConfigResponse(
|
return create_api_response(
|
||||||
model_name=config.model_name,
|
code="200",
|
||||||
system_prompt=config.system_prompt,
|
message="配置更新成功,重启服务后完全生效",
|
||||||
DEFAULT_RESET_PASSWORD=config.DEFAULT_RESET_PASSWORD,
|
data=config_data
|
||||||
MAX_FILE_SIZE=config.MAX_FILE_SIZE,
|
|
||||||
MAX_IMAGE_SIZE=config.MAX_IMAGE_SIZE,
|
|
||||||
message="配置更新成功,重启服务后完全生效"
|
|
||||||
)
|
)
|
||||||
except HTTPException:
|
|
||||||
raise
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=500, detail=f"更新配置失败: {str(e)}")
|
return create_api_response(code="500", message=f"更新配置失败: {str(e)}")
|
||||||
|
|
||||||
# 在应用启动时加载配置
|
# 在应用启动时加载配置
|
||||||
def load_system_config():
|
def load_system_config():
|
||||||
"""在应用启动时调用,加载保存的配置"""
|
"""在应用启动时调用,加载保存的配置"""
|
||||||
try:
|
try:
|
||||||
config = load_config_from_file()
|
config = load_config_from_file()
|
||||||
|
|
||||||
# 更新运行时配置
|
|
||||||
LLM_CONFIG['model_name'] = config.get('model_name', LLM_CONFIG['model_name'])
|
LLM_CONFIG['model_name'] = config.get('model_name', LLM_CONFIG['model_name'])
|
||||||
LLM_CONFIG['system_prompt'] = config.get('system_prompt', LLM_CONFIG['system_prompt'])
|
LLM_CONFIG['system_prompt'] = config.get('system_prompt', LLM_CONFIG['system_prompt'])
|
||||||
|
|
||||||
# 更新其他配置
|
|
||||||
import app.core.config as config_module
|
import app.core.config as config_module
|
||||||
config_module.DEFAULT_RESET_PASSWORD = config.get('DEFAULT_RESET_PASSWORD', DEFAULT_RESET_PASSWORD)
|
config_module.DEFAULT_RESET_PASSWORD = config.get('DEFAULT_RESET_PASSWORD', DEFAULT_RESET_PASSWORD)
|
||||||
config_module.MAX_FILE_SIZE = config.get('MAX_FILE_SIZE', MAX_FILE_SIZE)
|
config_module.MAX_FILE_SIZE = config.get('MAX_FILE_SIZE', MAX_FILE_SIZE)
|
||||||
config_module.MAX_IMAGE_SIZE = config.get('MAX_IMAGE_SIZE', MAX_IMAGE_SIZE)
|
config_module.MAX_IMAGE_SIZE = config.get('MAX_IMAGE_SIZE', MAX_IMAGE_SIZE)
|
||||||
|
|
||||||
print(f"系统配置加载成功: model={config.get('model_name')}")
|
print(f"系统配置加载成功: model={config.get('model_name')}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"加载系统配置失败,使用默认配置: {e}")
|
print(f"加载系统配置失败,使用默认配置: {e}")
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException, Depends
|
|
||||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
||||||
from app.models.models import LoginRequest, LoginResponse
|
|
||||||
from app.core.database import get_db_connection
|
|
||||||
from app.services.jwt_service import jwt_service
|
|
||||||
from app.core.auth import get_current_user
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||||
|
|
||||||
|
from app.core.auth import get_current_user
|
||||||
|
from app.core.database import get_db_connection
|
||||||
|
from app.models.models import LoginRequest, LoginResponse
|
||||||
|
from app.services.jwt_service import jwt_service
|
||||||
|
from app.core.response import create_api_response
|
||||||
|
|
||||||
security = HTTPBearer()
|
security = HTTPBearer()
|
||||||
|
|
||||||
|
|
@ -14,7 +19,7 @@ router = APIRouter()
|
||||||
def hash_password(password: str) -> str:
|
def hash_password(password: str) -> str:
|
||||||
return hashlib.sha256(password.encode()).hexdigest()
|
return hashlib.sha256(password.encode()).hexdigest()
|
||||||
|
|
||||||
@router.post("/auth/login", response_model=LoginResponse)
|
@router.post("/auth/login")
|
||||||
def login(request: LoginRequest):
|
def login(request: LoginRequest):
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
@ -24,11 +29,11 @@ def login(request: LoginRequest):
|
||||||
user = cursor.fetchone()
|
user = cursor.fetchone()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
raise HTTPException(status_code=401, detail="用户名或密码错误")
|
return create_api_response(code="401", message="用户名或密码错误")
|
||||||
|
|
||||||
hashed_input = hash_password(request.password)
|
hashed_input = hash_password(request.password)
|
||||||
if user['password_hash'] != hashed_input:
|
if user['password_hash'] != hashed_input:
|
||||||
raise HTTPException(status_code=401, detail="用户名或密码错误")
|
return create_api_response(code="401", message="用户名或密码错误")
|
||||||
|
|
||||||
# 创建JWT token
|
# 创建JWT token
|
||||||
token_data = {
|
token_data = {
|
||||||
|
|
@ -39,7 +44,7 @@ def login(request: LoginRequest):
|
||||||
}
|
}
|
||||||
token = jwt_service.create_access_token(token_data)
|
token = jwt_service.create_access_token(token_data)
|
||||||
|
|
||||||
return LoginResponse(
|
login_response_data = LoginResponse(
|
||||||
user_id=user['user_id'],
|
user_id=user['user_id'],
|
||||||
username=user['username'],
|
username=user['username'],
|
||||||
caption=user['caption'],
|
caption=user['caption'],
|
||||||
|
|
@ -47,71 +52,83 @@ def login(request: LoginRequest):
|
||||||
token=token,
|
token=token,
|
||||||
role_id=user['role_id']
|
role_id=user['role_id']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="登录成功",
|
||||||
|
data=login_response_data.dict()
|
||||||
|
)
|
||||||
|
|
||||||
@router.post("/auth/logout")
|
@router.post("/auth/logout")
|
||||||
def logout(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
def logout(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
||||||
"""登出接口,撤销当前token"""
|
"""登出接口,撤销当前token"""
|
||||||
token = credentials.credentials
|
token = credentials.credentials
|
||||||
|
|
||||||
# 验证token并获取用户信息(不查询数据库)
|
|
||||||
payload = jwt_service.verify_token(token)
|
payload = jwt_service.verify_token(token)
|
||||||
if not payload:
|
if not payload:
|
||||||
raise HTTPException(status_code=401, detail="Invalid or expired token")
|
return create_api_response(code="401", message="无效或过期的token")
|
||||||
|
|
||||||
user_id = payload.get("user_id")
|
user_id = payload.get("user_id")
|
||||||
if not user_id:
|
if not user_id:
|
||||||
raise HTTPException(status_code=401, detail="Invalid token payload")
|
return create_api_response(code="401", message="无效的token payload")
|
||||||
|
|
||||||
# 撤销当前token
|
|
||||||
revoked = jwt_service.revoke_token(token, user_id)
|
revoked = jwt_service.revoke_token(token, user_id)
|
||||||
|
|
||||||
if revoked:
|
if revoked:
|
||||||
return {"message": "Logged out successfully"}
|
return create_api_response(code="200", message="登出成功")
|
||||||
else:
|
else:
|
||||||
return {"message": "Already logged out or token not found"}
|
return create_api_response(code="400", message="已经登出或token未找到")
|
||||||
|
|
||||||
|
|
||||||
@router.post("/auth/logout-all")
|
@router.post("/auth/logout-all")
|
||||||
def logout_all(current_user: dict = Depends(get_current_user)):
|
def logout_all(current_user: dict = Depends(get_current_user)):
|
||||||
"""登出所有设备"""
|
"""登出所有设备"""
|
||||||
user_id = current_user['user_id']
|
user_id = current_user["user_id"]
|
||||||
revoked_count = jwt_service.revoke_all_user_tokens(user_id)
|
revoked_count = jwt_service.revoke_all_user_tokens(user_id)
|
||||||
return {"message": f"Logged out from {revoked_count} devices"}
|
return create_api_response(code="200", message=f"从 {revoked_count} 个设备登出")
|
||||||
|
|
||||||
|
|
||||||
@router.post("/auth/admin/revoke-user-tokens/{user_id}")
|
@router.post("/auth/admin/revoke-user-tokens/{user_id}")
|
||||||
def admin_revoke_user_tokens(user_id: int, credentials: HTTPAuthorizationCredentials = Depends(security)):
|
def admin_revoke_user_tokens(
|
||||||
|
user_id: int, credentials: HTTPAuthorizationCredentials = Depends(security)
|
||||||
|
):
|
||||||
"""管理员功能:撤销指定用户的所有token"""
|
"""管理员功能:撤销指定用户的所有token"""
|
||||||
token = credentials.credentials
|
token = credentials.credentials
|
||||||
|
|
||||||
# 验证管理员token(不查询数据库)
|
|
||||||
payload = jwt_service.verify_token(token)
|
payload = jwt_service.verify_token(token)
|
||||||
if not payload:
|
if not payload:
|
||||||
raise HTTPException(status_code=401, detail="Invalid or expired token")
|
return create_api_response(code="401", message="无效或过期的token")
|
||||||
|
|
||||||
admin_user_id = payload.get("user_id")
|
admin_user_id = payload.get("user_id")
|
||||||
if not admin_user_id:
|
if not admin_user_id:
|
||||||
raise HTTPException(status_code=401, detail="Invalid token payload")
|
return create_api_response(code="401", message="无效的token payload")
|
||||||
|
|
||||||
# 这里可以添加管理员权限检查,目前暂时允许任何登录用户操作
|
# 这里可以添加管理员权限检查,目前暂时允许任何登录用户操作
|
||||||
# if not payload.get('is_admin'):
|
# if payload.get('role_id') != ADMIN_ROLE_ID:
|
||||||
# raise HTTPException(status_code=403, detail="需要管理员权限")
|
# return create_api_response(code="403", message="需要管理员权限")
|
||||||
|
|
||||||
revoked_count = jwt_service.revoke_all_user_tokens(user_id)
|
revoked_count = jwt_service.revoke_all_user_tokens(user_id)
|
||||||
return {"message": f"Revoked {revoked_count} tokens for user {user_id}"}
|
return create_api_response(
|
||||||
|
code="200", message=f"为用户 {user_id} 撤销了 {revoked_count} 个token"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/auth/me")
|
@router.get("/auth/me")
|
||||||
def get_me(current_user: dict = Depends(get_current_user)):
|
def get_me(current_user: dict = Depends(get_current_user)):
|
||||||
"""获取当前用户信息"""
|
"""获取当前用户信息"""
|
||||||
return current_user
|
return create_api_response(code="200", message="获取用户信息成功", data=current_user)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/auth/refresh")
|
@router.post("/auth/refresh")
|
||||||
def refresh_token(current_user: dict = Depends(get_current_user)):
|
def refresh_token(current_user: dict = Depends(get_current_user)):
|
||||||
"""刷新token"""
|
"""刷新token"""
|
||||||
# 这里需要从请求中获取当前token,为简化先返回新token
|
|
||||||
token_data = {
|
token_data = {
|
||||||
"user_id": current_user['user_id'],
|
"user_id": current_user["user_id"],
|
||||||
"username": current_user['username'],
|
"username": current_user["username"],
|
||||||
"caption": current_user['caption'],
|
"caption": current_user["caption"],
|
||||||
"role_id": current_user['role_id']
|
"role_id": current_user["role_id"],
|
||||||
}
|
}
|
||||||
new_token = jwt_service.create_access_token(token_data)
|
new_token = jwt_service.create_access_token(token_data)
|
||||||
return {"token": new_token}
|
return create_api_response(
|
||||||
|
code="200", message="Token刷新成功", data={"token": new_token}
|
||||||
|
)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,13 +1,13 @@
|
||||||
|
from fastapi import APIRouter, Depends
|
||||||
from fastapi import APIRouter, HTTPException, Depends
|
|
||||||
from app.core.database import get_db_connection
|
from app.core.database import get_db_connection
|
||||||
|
from app.core.response import create_api_response
|
||||||
from app.models.models import Tag
|
from app.models.models import Tag
|
||||||
from typing import List
|
from typing import List
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.get("/tags/", response_model=List[Tag])
|
@router.get("/tags/")
|
||||||
def get_all_tags():
|
def get_all_tags():
|
||||||
"""_summary_
|
"""_summary_
|
||||||
获取所有标签
|
获取所有标签
|
||||||
|
|
@ -18,12 +18,12 @@ def get_all_tags():
|
||||||
with connection.cursor(dictionary=True) as cursor:
|
with connection.cursor(dictionary=True) as cursor:
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
tags = cursor.fetchall()
|
tags = cursor.fetchall()
|
||||||
return tags
|
return create_api_response(code="200", message="获取标签列表成功", data=tags)
|
||||||
except mysql.connector.Error as err:
|
except mysql.connector.Error as err:
|
||||||
print(f"Error: {err}")
|
print(f"Error: {err}")
|
||||||
raise HTTPException(status_code=500, detail="Failed to retrieve tags from database.")
|
return create_api_response(code="500", message="获取标签失败")
|
||||||
|
|
||||||
@router.post("/tags/", response_model=Tag)
|
@router.post("/tags/")
|
||||||
def create_tag(tag_in: Tag):
|
def create_tag(tag_in: Tag):
|
||||||
"""_summary_
|
"""_summary_
|
||||||
创建一个新标签
|
创建一个新标签
|
||||||
|
|
@ -36,10 +36,11 @@ def create_tag(tag_in: Tag):
|
||||||
cursor.execute(query, (tag_in.name, tag_in.color))
|
cursor.execute(query, (tag_in.name, tag_in.color))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
tag_id = cursor.lastrowid
|
tag_id = cursor.lastrowid
|
||||||
return {"id": tag_id, "name": tag_in.name, "color": tag_in.color}
|
new_tag = {"id": tag_id, "name": tag_in.name, "color": tag_in.color}
|
||||||
|
return create_api_response(code="200", message="标签创建成功", data=new_tag)
|
||||||
except mysql.connector.IntegrityError:
|
except mysql.connector.IntegrityError:
|
||||||
connection.rollback()
|
connection.rollback()
|
||||||
raise HTTPException(status_code=400, detail=f"Tag '{tag_in.name}' already exists.")
|
return create_api_response(code="400", message=f"标签 '{tag_in.name}' 已存在")
|
||||||
except mysql.connector.Error as err:
|
except mysql.connector.Error as err:
|
||||||
print(f"Error: {err}")
|
print(f"Error: {err}")
|
||||||
raise HTTPException(status_code=500, detail="Failed to create tag in database.")
|
return create_api_response(code="500", message="创建标签失败")
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
from fastapi import APIRouter, Depends
|
||||||
from fastapi import APIRouter, HTTPException, Depends
|
|
||||||
from app.models.models import UserInfo, PasswordChangeRequest, UserListResponse, CreateUserRequest, UpdateUserRequest, RoleInfo
|
from app.models.models import UserInfo, PasswordChangeRequest, UserListResponse, CreateUserRequest, UpdateUserRequest, RoleInfo
|
||||||
from app.core.database import get_db_connection
|
from app.core.database import get_db_connection
|
||||||
from app.core.auth import get_current_user
|
from app.core.auth import get_current_user
|
||||||
|
from app.core.response import create_api_response
|
||||||
import app.core.config as config_module
|
import app.core.config as config_module
|
||||||
import hashlib
|
import hashlib
|
||||||
import datetime
|
import datetime
|
||||||
|
|
@ -22,68 +22,60 @@ def hash_password(password: str) -> str:
|
||||||
def get_all_roles(current_user: dict = Depends(get_current_user)):
|
def get_all_roles(current_user: dict = Depends(get_current_user)):
|
||||||
"""获取所有角色列表"""
|
"""获取所有角色列表"""
|
||||||
if current_user['role_id'] != 1: # 1 is admin
|
if current_user['role_id'] != 1: # 1 is admin
|
||||||
raise HTTPException(status_code=403, detail="仅管理员有权限查看角色列表")
|
return create_api_response(code="403", message="仅管理员有权限查看角色列表")
|
||||||
|
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
cursor.execute("SELECT role_id, role_name FROM roles ORDER BY role_id")
|
cursor.execute("SELECT role_id, role_name FROM roles ORDER BY role_id")
|
||||||
roles = cursor.fetchall()
|
roles = cursor.fetchall()
|
||||||
return [RoleInfo(**role) for role in roles]
|
return create_api_response(code="200", message="获取角色列表成功", data=[RoleInfo(**role).dict() for role in roles])
|
||||||
|
|
||||||
@router.post("/users", status_code=201)
|
@router.post("/users")
|
||||||
def create_user(request: CreateUserRequest, current_user: dict = Depends(get_current_user)):
|
def create_user(request: CreateUserRequest, current_user: dict = Depends(get_current_user)):
|
||||||
if current_user['role_id'] != 1: # 1 is admin
|
if current_user['role_id'] != 1: # 1 is admin
|
||||||
raise HTTPException(status_code=403, detail="仅管理员有权限创建用户")
|
return create_api_response(code="403", message="仅管理员有权限创建用户")
|
||||||
|
|
||||||
# Validate email format
|
|
||||||
if not validate_email(request.email):
|
if not validate_email(request.email):
|
||||||
raise HTTPException(status_code=400, detail="邮箱格式不正确")
|
return create_api_response(code="400", message="邮箱格式不正确")
|
||||||
|
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
# Check if username exists
|
|
||||||
cursor.execute("SELECT user_id FROM users WHERE username = %s", (request.username,))
|
cursor.execute("SELECT user_id FROM users WHERE username = %s", (request.username,))
|
||||||
if cursor.fetchone():
|
if cursor.fetchone():
|
||||||
raise HTTPException(status_code=400, detail="用户名已存在")
|
return create_api_response(code="400", message="用户名已存在")
|
||||||
|
|
||||||
# Use provided password or default password
|
|
||||||
password = request.password if request.password else config_module.DEFAULT_RESET_PASSWORD
|
password = request.password if request.password else config_module.DEFAULT_RESET_PASSWORD
|
||||||
hashed_password = hash_password(password)
|
hashed_password = hash_password(password)
|
||||||
|
|
||||||
# Insert new user
|
|
||||||
query = "INSERT INTO users (username, password_hash, caption, email, role_id, created_at) VALUES (%s, %s, %s, %s, %s, %s)"
|
query = "INSERT INTO users (username, password_hash, caption, email, role_id, created_at) VALUES (%s, %s, %s, %s, %s, %s)"
|
||||||
created_at = datetime.datetime.utcnow()
|
created_at = datetime.datetime.utcnow()
|
||||||
cursor.execute(query, (request.username, hashed_password, request.caption, request.email, request.role_id, created_at))
|
cursor.execute(query, (request.username, hashed_password, request.caption, request.email, request.role_id, created_at))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
return {"message": "用户创建成功"}
|
return create_api_response(code="200", message="用户创建成功")
|
||||||
|
|
||||||
@router.put("/users/{user_id}", response_model=UserInfo)
|
@router.put("/users/{user_id}")
|
||||||
def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = Depends(get_current_user)):
|
def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = Depends(get_current_user)):
|
||||||
if current_user['role_id'] != 1: # 1 is admin
|
if current_user['role_id'] != 1: # 1 is admin
|
||||||
raise HTTPException(status_code=403, detail="仅管理员有权限修改用户信息")
|
return create_api_response(code="403", message="仅管理员有权限修改用户信息")
|
||||||
|
|
||||||
# Validate email format if provided
|
|
||||||
if request.email and not validate_email(request.email):
|
if request.email and not validate_email(request.email):
|
||||||
raise HTTPException(status_code=400, detail="邮箱格式不正确")
|
return create_api_response(code="400", message="邮箱格式不正确")
|
||||||
|
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
# Check if user exists
|
|
||||||
cursor.execute("SELECT user_id, username, caption, email, role_id FROM users WHERE user_id = %s", (user_id,))
|
cursor.execute("SELECT user_id, username, caption, email, role_id FROM users WHERE user_id = %s", (user_id,))
|
||||||
existing_user = cursor.fetchone()
|
existing_user = cursor.fetchone()
|
||||||
if not existing_user:
|
if not existing_user:
|
||||||
raise HTTPException(status_code=404, detail="用户不存在")
|
return create_api_response(code="404", message="用户不存在")
|
||||||
|
|
||||||
# Check if username is being changed and if it already exists
|
|
||||||
if request.username and request.username != existing_user['username']:
|
if request.username and request.username != existing_user['username']:
|
||||||
cursor.execute("SELECT user_id FROM users WHERE username = %s AND user_id != %s", (request.username, user_id))
|
cursor.execute("SELECT user_id FROM users WHERE username = %s AND user_id != %s", (request.username, user_id))
|
||||||
if cursor.fetchone():
|
if cursor.fetchone():
|
||||||
raise HTTPException(status_code=400, detail="用户名已存在")
|
return create_api_response(code="400", message="用户名已存在")
|
||||||
|
|
||||||
# Prepare update data, using existing values if not provided
|
|
||||||
update_data = {
|
update_data = {
|
||||||
'username': request.username if request.username else existing_user['username'],
|
'username': request.username if request.username else existing_user['username'],
|
||||||
'caption': request.caption if request.caption else existing_user['caption'],
|
'caption': request.caption if request.caption else existing_user['caption'],
|
||||||
|
|
@ -91,12 +83,10 @@ def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = D
|
||||||
'role_id': request.role_id if request.role_id is not None else existing_user['role_id']
|
'role_id': request.role_id if request.role_id is not None else existing_user['role_id']
|
||||||
}
|
}
|
||||||
|
|
||||||
# Update user
|
|
||||||
query = "UPDATE users SET username = %s, caption = %s, email = %s, role_id = %s WHERE user_id = %s"
|
query = "UPDATE users SET username = %s, caption = %s, email = %s, role_id = %s WHERE user_id = %s"
|
||||||
cursor.execute(query, (update_data['username'], update_data['caption'], update_data['email'], update_data['role_id'], user_id))
|
cursor.execute(query, (update_data['username'], update_data['caption'], update_data['email'], update_data['role_id'], user_id))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
# Return updated user info
|
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
SELECT u.user_id, u.username, u.caption, u.email, u.created_at, u.role_id, r.role_name
|
SELECT u.user_id, u.username, u.caption, u.email, u.created_at, u.role_id, r.role_name
|
||||||
FROM users u
|
FROM users u
|
||||||
|
|
@ -105,7 +95,7 @@ def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = D
|
||||||
''', (user_id,))
|
''', (user_id,))
|
||||||
updated_user = cursor.fetchone()
|
updated_user = cursor.fetchone()
|
||||||
|
|
||||||
return UserInfo(
|
user_info = UserInfo(
|
||||||
user_id=updated_user['user_id'],
|
user_id=updated_user['user_id'],
|
||||||
username=updated_user['username'],
|
username=updated_user['username'],
|
||||||
caption=updated_user['caption'],
|
caption=updated_user['caption'],
|
||||||
|
|
@ -113,62 +103,56 @@ def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = D
|
||||||
created_at=updated_user['created_at'],
|
created_at=updated_user['created_at'],
|
||||||
role_id=updated_user['role_id'],
|
role_id=updated_user['role_id'],
|
||||||
role_name=updated_user['role_name'],
|
role_name=updated_user['role_name'],
|
||||||
meetings_created=0, # This is not accurate, but it is not displayed in the list
|
meetings_created=0,
|
||||||
meetings_attended=0
|
meetings_attended=0
|
||||||
)
|
)
|
||||||
|
return create_api_response(code="200", message="用户信息更新成功", data=user_info.dict())
|
||||||
|
|
||||||
@router.delete("/users/{user_id}")
|
@router.delete("/users/{user_id}")
|
||||||
def delete_user(user_id: int, current_user: dict = Depends(get_current_user)):
|
def delete_user(user_id: int, current_user: dict = Depends(get_current_user)):
|
||||||
if current_user['role_id'] != 1: # 1 is admin
|
if current_user['role_id'] != 1: # 1 is admin
|
||||||
raise HTTPException(status_code=403, detail="仅管理员有权限删除用户")
|
return create_api_response(code="403", message="仅管理员有权限删除用户")
|
||||||
|
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
# Check if user exists
|
|
||||||
cursor.execute("SELECT user_id FROM users WHERE user_id = %s", (user_id,))
|
cursor.execute("SELECT user_id FROM users WHERE user_id = %s", (user_id,))
|
||||||
if not cursor.fetchone():
|
if not cursor.fetchone():
|
||||||
raise HTTPException(status_code=404, detail="用户不存在")
|
return create_api_response(code="404", message="用户不存在")
|
||||||
|
|
||||||
# Delete user
|
|
||||||
cursor.execute("DELETE FROM users WHERE user_id = %s", (user_id,))
|
cursor.execute("DELETE FROM users WHERE user_id = %s", (user_id,))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
return {"message": "用户删除成功"}
|
return create_api_response(code="200", message="用户删除成功")
|
||||||
|
|
||||||
@router.post("/users/{user_id}/reset-password")
|
@router.post("/users/{user_id}/reset-password")
|
||||||
def reset_password(user_id: int, current_user: dict = Depends(get_current_user)):
|
def reset_password(user_id: int, current_user: dict = Depends(get_current_user)):
|
||||||
if current_user['role_id'] != 1: # 1 is admin
|
if current_user['role_id'] != 1: # 1 is admin
|
||||||
raise HTTPException(status_code=403, detail="仅管理员有权限重置密码")
|
return create_api_response(code="403", message="仅管理员有权限重置密码")
|
||||||
|
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
# Check if user exists
|
|
||||||
cursor.execute("SELECT user_id FROM users WHERE user_id = %s", (user_id,))
|
cursor.execute("SELECT user_id FROM users WHERE user_id = %s", (user_id,))
|
||||||
if not cursor.fetchone():
|
if not cursor.fetchone():
|
||||||
raise HTTPException(status_code=404, detail="用户不存在")
|
return create_api_response(code="404", message="用户不存在")
|
||||||
|
|
||||||
# Hash password
|
|
||||||
hashed_password = hash_password(config_module.DEFAULT_RESET_PASSWORD)
|
hashed_password = hash_password(config_module.DEFAULT_RESET_PASSWORD)
|
||||||
|
|
||||||
# Update user password
|
|
||||||
query = "UPDATE users SET password_hash = %s WHERE user_id = %s"
|
query = "UPDATE users SET password_hash = %s WHERE user_id = %s"
|
||||||
cursor.execute(query, (hashed_password, user_id))
|
cursor.execute(query, (hashed_password, user_id))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
return {"message": f"用户 {user_id} 的密码已重置"}
|
return create_api_response(code="200", message=f"用户 {user_id} 的密码已重置")
|
||||||
|
|
||||||
@router.get("/users", response_model=UserListResponse)
|
@router.get("/users")
|
||||||
def get_all_users(page: int = 1, size: int = 10, current_user: dict = Depends(get_current_user)):
|
def get_all_users(page: int = 1, size: int = 10, current_user: dict = Depends(get_current_user)):
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
# Get total count
|
|
||||||
cursor.execute("SELECT COUNT(*) as total FROM users")
|
cursor.execute("SELECT COUNT(*) as total FROM users")
|
||||||
total = cursor.fetchone()['total']
|
total = cursor.fetchone()['total']
|
||||||
|
|
||||||
# Get paginated users with role names
|
|
||||||
offset = (page - 1) * size
|
offset = (page - 1) * size
|
||||||
query = '''
|
query = '''
|
||||||
SELECT
|
SELECT
|
||||||
|
|
@ -186,9 +170,10 @@ def get_all_users(page: int = 1, size: int = 10, current_user: dict = Depends(ge
|
||||||
|
|
||||||
user_list = [UserInfo(**user) for user in users]
|
user_list = [UserInfo(**user) for user in users]
|
||||||
|
|
||||||
return UserListResponse(users=user_list, total=total)
|
response_data = UserListResponse(users=user_list, total=total)
|
||||||
|
return create_api_response(code="200", message="获取用户列表成功", data=response_data.dict())
|
||||||
|
|
||||||
@router.get("/users/{user_id}", response_model=UserInfo)
|
@router.get("/users/{user_id}")
|
||||||
def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
|
def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
@ -203,7 +188,7 @@ def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
|
||||||
user = cursor.fetchone()
|
user = cursor.fetchone()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
raise HTTPException(status_code=404, detail="用户不存在")
|
return create_api_response(code="404", message="用户不存在")
|
||||||
|
|
||||||
created_query = "SELECT COUNT(*) as count FROM meetings WHERE user_id = %s"
|
created_query = "SELECT COUNT(*) as count FROM meetings WHERE user_id = %s"
|
||||||
cursor.execute(created_query, (user_id,))
|
cursor.execute(created_query, (user_id,))
|
||||||
|
|
@ -213,7 +198,7 @@ def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
|
||||||
cursor.execute(attended_query, (user_id,))
|
cursor.execute(attended_query, (user_id,))
|
||||||
meetings_attended = cursor.fetchone()['count']
|
meetings_attended = cursor.fetchone()['count']
|
||||||
|
|
||||||
return UserInfo(
|
user_info = UserInfo(
|
||||||
user_id=user['user_id'],
|
user_id=user['user_id'],
|
||||||
username=user['username'],
|
username=user['username'],
|
||||||
caption=user['caption'],
|
caption=user['caption'],
|
||||||
|
|
@ -224,11 +209,12 @@ def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
|
||||||
meetings_created=meetings_created,
|
meetings_created=meetings_created,
|
||||||
meetings_attended=meetings_attended
|
meetings_attended=meetings_attended
|
||||||
)
|
)
|
||||||
|
return create_api_response(code="200", message="获取用户信息成功", data=user_info.dict())
|
||||||
|
|
||||||
@router.put("/users/{user_id}/password")
|
@router.put("/users/{user_id}/password")
|
||||||
def update_password(user_id: int, request: PasswordChangeRequest, current_user: dict = Depends(get_current_user)):
|
def update_password(user_id: int, request: PasswordChangeRequest, current_user: dict = Depends(get_current_user)):
|
||||||
if user_id != current_user['user_id'] and current_user['role_id'] != 1:
|
if user_id != current_user['user_id'] and current_user['role_id'] != 1:
|
||||||
raise HTTPException(status_code=403, detail="没有权限修改其他用户的密码")
|
return create_api_response(code="403", message="没有权限修改其他用户的密码")
|
||||||
|
|
||||||
with get_db_connection() as connection:
|
with get_db_connection() as connection:
|
||||||
cursor = connection.cursor(dictionary=True)
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
@ -237,15 +223,14 @@ def update_password(user_id: int, request: PasswordChangeRequest, current_user:
|
||||||
user = cursor.fetchone()
|
user = cursor.fetchone()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
raise HTTPException(status_code=404, detail="用户不存在")
|
return create_api_response(code="404", message="用户不存在")
|
||||||
|
|
||||||
# If not admin, verify old password
|
|
||||||
if current_user['role_id'] != 1:
|
if current_user['role_id'] != 1:
|
||||||
if user['password_hash'] != hash_password(request.old_password):
|
if user['password_hash'] != hash_password(request.old_password):
|
||||||
raise HTTPException(status_code=400, detail="旧密码错误")
|
return create_api_response(code="400", message="旧密码错误")
|
||||||
|
|
||||||
new_password_hash = hash_password(request.new_password)
|
new_password_hash = hash_password(request.new_password)
|
||||||
cursor.execute("UPDATE users SET password_hash = %s WHERE user_id = %s", (new_password_hash, user_id))
|
cursor.execute("UPDATE users SET password_hash = %s WHERE user_id = %s", (new_password_hash, user_id))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
return {"message": "密码修改成功"}
|
return create_api_response(code="200", message="密码修改成功")
|
||||||
|
|
@ -23,7 +23,7 @@ DATABASE_CONFIG = {
|
||||||
'host': os.getenv('DB_HOST', '10.100.51.161'),
|
'host': os.getenv('DB_HOST', '10.100.51.161'),
|
||||||
'user': os.getenv('DB_USER', 'root'),
|
'user': os.getenv('DB_USER', 'root'),
|
||||||
'password': os.getenv('DB_PASSWORD', 'sagacity'),
|
'password': os.getenv('DB_PASSWORD', 'sagacity'),
|
||||||
'database': os.getenv('DB_NAME', 'imeeting'),
|
'database': os.getenv('DB_NAME', 'imeeting_dev'),
|
||||||
'port': int(os.getenv('DB_PORT', '3306')),
|
'port': int(os.getenv('DB_PORT', '3306')),
|
||||||
'charset': 'utf8mb4'
|
'charset': 'utf8mb4'
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ QINIU_DOMAIN = os.getenv('QINIU_DOMAIN', 't0vogyxkz.hn-bkt.clouddn.com')
|
||||||
|
|
||||||
# 应用配置
|
# 应用配置
|
||||||
APP_CONFIG = {
|
APP_CONFIG = {
|
||||||
'base_url': os.getenv('BASE_URL', 'http://imeeting.unisspace.com')
|
'base_url': os.getenv('BASE_URL', 'http://dev.imeeting.unisspace.com')
|
||||||
}
|
}
|
||||||
|
|
||||||
# Redis配置
|
# Redis配置
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
from typing import Union
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi.encoders import jsonable_encoder
|
||||||
|
|
||||||
|
def create_api_response(code: str, message: str, data: Union[dict, list, None] = None) -> JSONResponse:
|
||||||
|
"""Creates a standardized API JSON response."""
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=200,
|
||||||
|
content={
|
||||||
|
"code": str(code),
|
||||||
|
"message": message,
|
||||||
|
"data": jsonable_encoder(data) if data is not None else {},
|
||||||
|
},
|
||||||
|
)
|
||||||
Binary file not shown.
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"model_name": "qwen-plus",
|
"model_name": "qwen-plus",
|
||||||
"system_prompt": "你是一个专业的会议记录分析助手。请根据提供的会议转录内容,生成简洁明了的会议总结。\n\n总结应该包括以下几部分(生成MD二级目录):\n1. 会议概述 - 简要说明会议的主要目的和背景(生成MD引用)\n2. 主要讨论点 - 列出会议中讨论的重要话题和内容\n3. 决策事项 - 明确记录会议中做出的决定和结论\n4. 待办事项 - 列出需要后续跟进的任务和责任人\n5. 关键信息 - 其他重要的信息点\n\n输出要求:\n- 保持客观中性,不添加个人观点\n- 使用简洁、准确的中文表达\n- 按重要性排序各项内容\n- 如果某个部分没有相关内容,可以说明\"无相关内容\"\n- 总字数控制在500字以内",
|
"system_prompt": "你是一个专业的会议记录分析助手。请根据提供的会议转录内容,生成简洁明了的会议总结。\n\n总结包括五个部分(名称严格一致,生成为MD二级目录):\n1. 会议概述 - 简要说明会议的主要目的和背景(生成MD引用)\n2. 主要讨论点 - 列出会议中讨论的重要话题和内容\n3. 决策事项 - 明确记录会议中做出的决定和结论\n4. 待办事项 - 列出需要后续跟进的任务和责任人\n5. 关键信息 - 其他重要的信息点\n\n输出要求:\n- 保持客观中性,不添加个人观点\n- 使用简洁、准确的中文表达\n- 按重要性排序各项内容\n- 如果某个部分没有相关内容,可以说明\"无相关内容\"\n- 总字数控制在500字以内",
|
||||||
"DEFAULT_RESET_PASSWORD": "123456",
|
"DEFAULT_RESET_PASSWORD": "111111",
|
||||||
"MAX_FILE_SIZE": 209715200,
|
"MAX_FILE_SIZE": 209715200,
|
||||||
"MAX_IMAGE_SIZE": 10485760
|
"MAX_IMAGE_SIZE": 10485760
|
||||||
}
|
}
|
||||||
|
|
@ -46,6 +46,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
# 挂载上传目录保持数据持久化
|
# 挂载上传目录保持数据持久化
|
||||||
- ./uploads:/app/uploads
|
- ./uploads:/app/uploads
|
||||||
|
- ./config:/app/config
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
container_name: imeeting-backend
|
container_name: imeeting-backend
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
|
|
|
||||||
5
main.py
5
main.py
|
|
@ -3,8 +3,7 @@ from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from app.api.endpoints import auth, users, meetings, tags, admin
|
from app.api.endpoints import auth, users, meetings, tags, admin
|
||||||
from app.core.config import UPLOAD_DIR, API_CONFIG, MAX_FILE_SIZE
|
from app.core.config import UPLOAD_DIR, API_CONFIG
|
||||||
from app.services.async_llm_service import async_llm_service
|
|
||||||
from app.api.endpoints.admin import load_system_config
|
from app.api.endpoints.admin import load_system_config
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
@ -47,7 +46,7 @@ def health_check():
|
||||||
return {
|
return {
|
||||||
"status": "healthy",
|
"status": "healthy",
|
||||||
"service": "iMeeting API",
|
"service": "iMeeting API",
|
||||||
"version": "1.0.0"
|
"version": "1.0.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue