初始版本-前端

This commit is contained in:
z66
2025-12-26 17:29:22 +08:00
parent b495bc1dca
commit e19873850c
77 changed files with 6977 additions and 294 deletions
+77
View File
@@ -0,0 +1,77 @@
"""
认证相关 API 端点
"""
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlmodel import Session, select
from datetime import timedelta
from app.core.config import settings
from app.core.security import verify_password, create_access_token, get_password_hash
from app.db.session import get_db
from app.models.user import User
from app.schemas.user import Token, User as UserSchema, UserCreate
router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}/auth/login")
@router.post("/register", response_model=UserSchema, status_code=status.HTTP_201_CREATED)
def register(user_in: UserCreate, db: Session = Depends(get_db)):
"""用户注册"""
# 检查用户名是否已存在
statement = select(User).where(User.username == user_in.username)
existing_user = db.exec(statement).first()
if existing_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="用户名已存在"
)
# 检查邮箱是否已存在
if user_in.email:
statement = select(User).where(User.email == user_in.email)
existing_email = db.exec(statement).first()
if existing_email:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="邮箱已被注册"
)
# 创建新用户
hashed_password = get_password_hash(user_in.password)
db_user = User(
username=user_in.username,
email=user_in.email,
hashed_password=hashed_password
)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
@router.post("/login", response_model=Token)
def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
"""用户登录"""
# 查找用户
statement = select(User).where(User.username == form_data.username)
user = db.exec(statement).first()
if not user or not verify_password(form_data.password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="用户名或密码错误",
headers={"WWW-Authenticate": "Bearer"},
)
# 创建访问令牌
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.username}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
+44
View File
@@ -0,0 +1,44 @@
"""
应用配置
"""
from pydantic_settings import BaseSettings
from typing import Optional
class Settings(BaseSettings):
"""应用配置类"""
# 项目信息
PROJECT_NAME: str = "个人博客网站"
VERSION: str = "0.1.0"
API_V1_STR: str = "/api/v1"
# 数据库配置
DATABASE_URL: str = "sqlite:///./blogweb.db"
# 安全配置
SECRET_KEY: str = "your-secret-key-change-in-production" # 生产环境请修改
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 7 # 7天
# CORS 配置
BACKEND_CORS_ORIGINS: list = [
"http://localhost:3000",
"http://localhost:5173",
"http://localhost:8080",
]
# 文件上传配置
UPLOAD_DIR: str = "./uploads"
MAX_UPLOAD_SIZE: int = 10 * 1024 * 1024 # 10MB
# 第三方 API 配置
OPENWEATHER_API_KEY: Optional[str] = None # OpenWeatherMap API Key
class Config:
env_file = ".env"
case_sensitive = True
settings = Settings()
+14
View File
@@ -0,0 +1,14 @@
"""
数据库基础配置
"""
from sqlmodel import SQLModel
# 导入所有模型以确保表被注册到 metadata
from app.models import (
User, Todo, Post, Transaction, Media, Tag, MediaTag,
ChatMessage, Upload
)
# SQLModel 的 Base 类
Base = SQLModel
+22
View File
@@ -0,0 +1,22 @@
"""
聊天消息模型
"""
from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field, Relationship
from .user import User
class ChatMessage(SQLModel, table=True):
"""聊天消息表"""
__tablename__ = "chat_messages"
id: Optional[int] = Field(default=None, primary_key=True)
content: str
sent_at: datetime = Field(default_factory=datetime.now)
user_id: int = Field(foreign_key="users.id", index=True)
room: str = Field(max_length=50, default="main", index=True)
# 关系
user: Optional[User] = Relationship()