Initial commit: SQL audit platform v0.1.0

FastAPI backend with auth, user, instance, ticket, query, dashboard APIs.
React + TypeScript frontend with mock data UI (10 pages).
SQLite + async SQLAlchemy, JWT auth, role-based access control.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
loganandClaude Opus 4.7 committed 2026-05-22 11:11:57 +08:00
commit 439155c92e
290 files changed
+61950

No files matched your search

+104
View File
@@ -0,0 +1,104 @@
from typing import Optional, List
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
from app.core.security import get_current_user, hash_password, require_role
from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate, UserResponse
router = APIRouter(prefix="/users", tags=["用户管理"])
@router.get("", response_model=List[UserResponse])
async def list_users(
role: Optional[str] = None,
is_active: Optional[bool] = None,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(require_role("admin")),
):
stmt = select(User).order_by(User.id)
if role:
stmt = stmt.where(User.role == role)
if is_active is not None:
stmt = stmt.where(User.is_active == is_active)
result = await db.execute(stmt)
return result.scalars().all()
@router.post("", response_model=UserResponse, status_code=201)
async def create_user(
data: UserCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(require_role("admin")),
):
exists = await db.execute(select(User).where(User.username == data.username))
if exists.scalar_one_or_none():
raise HTTPException(status_code=400, detail="用户名已存在")
user = User(
username=data.username,
display_name=data.display_name,
email=data.email,
phone=data.phone,
role=data.role,
hashed_password=hash_password(data.password),
)
db.add(user)
await db.commit()
await db.refresh(user)
return user
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
user_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(require_role("admin")),
):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="用户不存在")
return user
@router.put("/{user_id}", response_model=UserResponse)
async def update_user(
user_id: int,
data: UserUpdate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(require_role("admin")),
):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="用户不存在")
update_data = data.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(user, key, value)
await db.commit()
await db.refresh(user)
return user
@router.delete("/{user_id}")
async def delete_user(
user_id: int,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(require_role("admin")),
):
if user_id == current_user.id:
raise HTTPException(status_code=400, detail="不能删除自己")
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="用户不存在")
await db.delete(user)
await db.commit()
return {"message": "用户已删除"}