霖雨寺
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import sqlite3
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
|
||||
from app.database import Database
|
||||
from app.schemas import User, UserCreate, UserUpdate
|
||||
|
||||
|
||||
router = APIRouter(prefix="/users", tags=["users"])
|
||||
|
||||
|
||||
def row_to_user(row: sqlite3.Row) -> User:
|
||||
return User(
|
||||
id=row["id"],
|
||||
registered_at=row["registered_at"],
|
||||
name=row["name"],
|
||||
phone=row["phone"],
|
||||
nickname=row["nickname"],
|
||||
avatar=row["avatar"],
|
||||
is_admin=bool(row["is_admin"]),
|
||||
total_spent=float(row["total_spent"]),
|
||||
)
|
||||
|
||||
|
||||
def raise_duplicate_user_error() -> None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Phone already exists",
|
||||
)
|
||||
|
||||
|
||||
@router.get("", response_model=List[User])
|
||||
def list_users(db: Database, phone: str | None = None) -> List[User]:
|
||||
params = []
|
||||
where_clause = ""
|
||||
if phone:
|
||||
where_clause = "WHERE phone LIKE ?"
|
||||
params.append(f"%{phone}%")
|
||||
|
||||
rows = db.execute(
|
||||
f"""
|
||||
SELECT id, registered_at, name, phone, nickname, avatar, is_admin, total_spent
|
||||
FROM users
|
||||
{where_clause}
|
||||
ORDER BY id
|
||||
""",
|
||||
params,
|
||||
).fetchall()
|
||||
return [row_to_user(row) for row in rows]
|
||||
|
||||
|
||||
@router.post("", response_model=User, status_code=status.HTTP_201_CREATED)
|
||||
def create_user(payload: UserCreate, db: Database) -> User:
|
||||
try:
|
||||
cursor = db.execute(
|
||||
"""
|
||||
INSERT INTO users
|
||||
(registered_at, name, phone, nickname, avatar, is_admin, total_spent)
|
||||
VALUES (CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
payload.name,
|
||||
payload.phone,
|
||||
payload.nickname,
|
||||
payload.avatar,
|
||||
int(payload.is_admin),
|
||||
payload.total_spent,
|
||||
),
|
||||
)
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError:
|
||||
raise_duplicate_user_error()
|
||||
|
||||
return get_user(cursor.lastrowid, db)
|
||||
|
||||
|
||||
@router.get("/{user_id}", response_model=User)
|
||||
def get_user(user_id: int, db: Database) -> User:
|
||||
row = db.execute(
|
||||
"""
|
||||
SELECT id, registered_at, name, phone, nickname, avatar, is_admin, total_spent
|
||||
FROM users
|
||||
WHERE id = ?
|
||||
""",
|
||||
(user_id,),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
return row_to_user(row)
|
||||
|
||||
|
||||
@router.patch("/{user_id}", response_model=User)
|
||||
def update_user(user_id: int, payload: UserUpdate, db: Database) -> User:
|
||||
user = get_user(user_id, db)
|
||||
updates = payload.model_dump(exclude_unset=True)
|
||||
|
||||
if not updates:
|
||||
return user
|
||||
|
||||
name = updates.get("name", user.name)
|
||||
phone = updates.get("phone", user.phone)
|
||||
nickname = updates.get("nickname", user.nickname)
|
||||
avatar = updates.get("avatar", user.avatar)
|
||||
is_admin = updates.get("is_admin", user.is_admin)
|
||||
total_spent = updates.get("total_spent", user.total_spent)
|
||||
|
||||
try:
|
||||
db.execute(
|
||||
"""
|
||||
UPDATE users
|
||||
SET name = ?, phone = ?, nickname = ?, avatar = ?, is_admin = ?, total_spent = ?
|
||||
WHERE id = ?
|
||||
""",
|
||||
(name, phone, nickname, avatar, int(is_admin), total_spent, user_id),
|
||||
)
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError:
|
||||
raise_duplicate_user_error()
|
||||
|
||||
return get_user(user_id, db)
|
||||
|
||||
|
||||
@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def delete_user(user_id: int, db: Database) -> None:
|
||||
cursor = db.execute("DELETE FROM users WHERE id = ?", (user_id,))
|
||||
db.commit()
|
||||
if cursor.rowcount == 0:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
Reference in New Issue
Block a user