feat():learning后台管理项目初始化

This commit is contained in:
yuj
2025-12-04 16:23:46 +08:00
parent 39886d50d2
commit 88e048f4d1
154 changed files with 28966 additions and 6 deletions

124
scripts/invite_code_api.py Normal file
View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""
邀请码申请 API - 简洁版本
使用方法:
1. 直接运行: ./scripts/run_invite_api.sh
2. 或者: uv run scripts/invite_code_api.py
3. 访问: POST http://localhost:8000/api/invite-code/apply
默认使用 AWS RDS 数据库(与 Go 项目共享)
如需使用本地数据库,请设置环境变量或创建 scripts/.env 文件
"""
import os
from datetime import datetime, timezone
from typing import Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Text
from sqlalchemy.orm import declarative_base, Session
from sqlalchemy.exc import IntegrityError
# 数据库配置 - 从环境变量读取(默认使用 AWS RDS 配置)
DB_USER = os.getenv("DB_USER", "goalfymax_prod")
DB_PASSWORD = os.getenv("DB_PASSWORD", "X6cQDaOLOifFBOMq")
DB_HOST = os.getenv("DB_HOST", "goalfyagent-aurora-mysql-staging.cb2sq6y2mg93.us-west-2.rds.amazonaws.com")
DB_PORT = os.getenv("DB_PORT", "3306")
DB_NAME = os.getenv("DB_NAME", "goalfymax_prod")
DATABASE_URL = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}?charset=utf8mb4"
Base = declarative_base()
engine = create_engine(DATABASE_URL, echo=False, pool_pre_ping=True)
# 数据模型 - 与 Go 项目的 admin_invite_code_applications 表结构保持一致
class InviteCodeApplication(Base):
__tablename__ = "admin_invite_code_applications"
id = Column(Integer, primary_key=True, autoincrement=True)
email = Column(String(255), nullable=False, index=True)
reason = Column(Text, nullable=True)
language = Column(String(10), nullable=False, default="zh")
status = Column(String(20), nullable=False, default="pending", index=True)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
# 不自动创建表(使用 Go 项目已有的表结构)
# Base.metadata.create_all(engine)
# FastAPI 应用
app = FastAPI(title="邀请码申请 API")
# 请求/响应模型
class ApplicationRequest(BaseModel):
email: EmailStr
reason: Optional[str] = None
language: Optional[str] = "zh" # zh 或 en默认 zh
class ApplicationResponse(BaseModel):
id: int
email: str
reason: Optional[str]
language: str
status: str
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class SuccessResponse(BaseModel):
code: int = 0
message: str
data: ApplicationResponse
# API 端点
@app.post("/api/invite-code/apply", response_model=SuccessResponse)
async def submit_application(req: ApplicationRequest):
"""提交邀请码申请"""
with Session(engine) as session:
# 检查是否已有待处理或已通过的申请
existing = session.query(InviteCodeApplication).filter(
InviteCodeApplication.email == req.email,
InviteCodeApplication.status.in_(["pending", "approved"])
).first()
if existing:
if existing.status == "pending":
raise HTTPException(status_code=400, detail="您已经提交过申请,请等待审核")
if existing.status == "approved":
raise HTTPException(status_code=400, detail="您的申请已通过,请检查邮箱")
# 创建新申请
language = req.language if req.language in ["zh", "en"] else "zh"
application = InviteCodeApplication(
email=req.email,
reason=req.reason,
language=language,
status="pending"
)
try:
session.add(application)
session.commit()
session.refresh(application)
return SuccessResponse(
message="申请已提交我们将在1-2个工作日内处理您的申请",
data=ApplicationResponse.model_validate(application)
)
except IntegrityError:
session.rollback()
raise HTTPException(status_code=500, detail="创建申请失败")
# 健康检查
@app.get("/health")
async def health_check():
return {"status": "ok"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)