backend update 260127

This commit is contained in:
lusixing
2026-01-27 20:01:29 -08:00
parent e3fa788318
commit 4b5b6fb976
5 changed files with 131 additions and 26 deletions

View File

@@ -1,5 +1,6 @@
# database.py
import os
from datetime import datetime
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
@@ -43,7 +44,9 @@ async def init_db():
private_key=private_key,
public_key=public_key,
is_admin=True,
guale=False
guale=False,
tier="Unlimited",
last_active_at=datetime.utcnow()
)
session.add(admin_user)
await session.commit()

View File

@@ -7,6 +7,8 @@ from passlib.context import CryptContext
from sqlalchemy.exc import IntegrityError
from contextlib import asynccontextmanager
import httpx
from datetime import datetime
from typing import List
@asynccontextmanager
async def lifespan(app: FastAPI):
@@ -17,6 +19,23 @@ async def lifespan(app: FastAPI):
app = FastAPI(lifespan=lifespan)
from fastapi.middleware.cors import CORSMiddleware
origins = [
"http://localhost",
"http://localhost:8081",
"http://localhost:8080",
"http://localhost:3000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.post("/register", response_model=schemas.UserOut)
async def register(user: schemas.UserCreate, db: AsyncSession = Depends(database.get_db)):
@@ -25,9 +44,12 @@ async def register(user: schemas.UserCreate, db: AsyncSession = Depends(database
new_user = models.User(
username=user.username,
email=user.email,
hashed_password=hashed_pwd,
private_key=private_key,
public_key=public_key
public_key=public_key,
tier="Free",
last_active_at=datetime.utcnow()
)
db.add(new_user)
try:
@@ -40,12 +62,17 @@ async def register(user: schemas.UserCreate, db: AsyncSession = Depends(database
await db.rollback()
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="用户名已存在"
detail="邮箱已存在"
)
except Exception as e:
await db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"注册失败: {str(e)}"
)
@app.post("/token")
@app.post("/login", response_model=schemas.LoginResponse)
async def login(form_data: schemas.UserLogin, db: AsyncSession = Depends(database.get_db)):
result = await db.execute(select(models.User).where(models.User.username == form_data.username))
user = result.scalars().first()
@@ -53,10 +80,31 @@ async def login(form_data: schemas.UserLogin, db: AsyncSession = Depends(databas
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token = auth.create_access_token(data={"sub": user.username})
return {"access_token": access_token, "token_type": "bearer"}
# Update last_active_at
user.last_active_at = datetime.utcnow()
await db.commit()
return {
"access_token": access_token,
"token_type": "bearer",
"user": user
}
@app.post("/assets/", response_model=schemas.AssetOut)
@app.get("/assets/get", response_model=List[schemas.AssetOut])
async def get_my_assets(
current_user: models.User = Depends(auth.get_current_user),
db: AsyncSession = Depends(database.get_db)
):
result = await db.execute(
select(models.Asset).where(models.Asset.author_id == current_user.id)
)
return result.scalars().all()
@app.post("/assets/create", response_model=schemas.AssetOut)
async def create_asset(
asset: schemas.AssetCreate,
current_user: models.User = Depends(auth.get_current_user),

View File

@@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, String, ForeignKey, Text, Table, Boolean
from sqlalchemy import Column, Integer, String, ForeignKey, Text, Table, Boolean, DateTime
from sqlalchemy.orm import relationship
from .database import Base
@@ -8,8 +8,14 @@ class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True)
username = Column(String, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
tier = Column(String)
tier_expires_at = Column(DateTime)
last_active_at = Column(DateTime)
# System keys
public_key = Column(String)
private_key = Column(String) # Encrypted or raw? Storing raw for now as per req
@@ -34,4 +40,14 @@ class Asset(Base):
private_key_shard = Column(String)
author = relationship("User", foreign_keys=[author_id], back_populates="assets")
heir = relationship("User", foreign_keys=[heir_id], back_populates="inherited_assets")
heir = relationship("User", foreign_keys=[heir_id], back_populates="inherited_assets")
class AIConfig(Base):
__tablename__ = "ai_configs"
id = Column(Integer, primary_key=True, index=True)
provider_name = Column(String, unique=True, index=True)
api_key = Column(String)
api_url = Column(String)
default_model = Column(String)
is_active = Column(Boolean, default=True)

View File

@@ -1,5 +1,6 @@
from pydantic import BaseModel, ConfigDict
from typing import List, Optional
from datetime import datetime
# Heir Schemas
class HeirBase(BaseModel):
@@ -17,6 +18,7 @@ class HeirOut(HeirBase):
class UserCreate(BaseModel):
username: str
password: str
email: str
class UserLogin(BaseModel):
username: str
@@ -28,9 +30,18 @@ class UserOut(BaseModel):
public_key: Optional[str] = None
is_admin: bool = False
guale: bool = False
tier: Optional[str] = None
tier_expires_at: Optional[datetime] = None
last_active_at: Optional[datetime] = None
#heirs: List[HeirOut] = []
model_config = ConfigDict(from_attributes=True)
class LoginResponse(BaseModel):
access_token: str
token_type: str
user: UserOut
# Asset Schemas (renamed from Article)
class AssetBase(BaseModel):
title: str