You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
4.5 KiB
Python
137 lines
4.5 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session, selectinload
|
|
|
|
from iti.auth import require_permission
|
|
from iti.db import get_db
|
|
from iti.exceptions import BizError
|
|
from iti.responses import ok, page
|
|
|
|
from iti_system.models import Role, User
|
|
from iti_system.schemas import PasswordUpdate, UserCreate, UserQuery, UserUpdate
|
|
from iti_system.services import (
|
|
apply_keyword,
|
|
assert_unique_user,
|
|
bind_depts,
|
|
bind_roles,
|
|
current_user,
|
|
dump_user,
|
|
get_or_404,
|
|
paginate_query,
|
|
)
|
|
|
|
|
|
router = APIRouter(prefix="/sys/user", tags=["system.user"])
|
|
|
|
|
|
@router.get("/current")
|
|
def get_current_user(user: User = Depends(current_user)):
|
|
return ok(dump_user(user))
|
|
|
|
|
|
@router.get("/list", dependencies=[Depends(require_permission("system:user:list"))])
|
|
def list_user(query: UserQuery = Depends(), db: Session = Depends(get_db)):
|
|
stmt = _query_users(query)
|
|
return ok([dump_user(user) for user in db.scalars(stmt).all()])
|
|
|
|
|
|
@router.get("/page", dependencies=[Depends(require_permission("system:user:list"))])
|
|
def page_user(query: UserQuery = Depends(), db: Session = Depends(get_db)):
|
|
result = paginate_query(db, _query_users(query), page=query.page, size=query.size)
|
|
return page([dump_user(user) for user in result["items"]], result["page"])
|
|
|
|
|
|
@router.post("", dependencies=[Depends(require_permission("system:user:create"))])
|
|
def create_user(payload: UserCreate, db: Session = Depends(get_db)):
|
|
assert_unique_user(
|
|
db,
|
|
username=payload.username,
|
|
phone=payload.phone,
|
|
email=payload.email,
|
|
)
|
|
user = User(
|
|
username=payload.username,
|
|
phone=payload.phone,
|
|
email=payload.email,
|
|
realname=payload.realname,
|
|
desc=payload.desc,
|
|
avatar=payload.avatar,
|
|
gender=payload.gender,
|
|
status=payload.status,
|
|
roles=bind_roles(db, payload.roles),
|
|
depts=bind_depts(db, payload.depts),
|
|
)
|
|
user.set_password(payload.password or "123456")
|
|
db.add(user)
|
|
db.commit()
|
|
db.refresh(user)
|
|
return ok(dump_user(user))
|
|
|
|
|
|
@router.put("/password", dependencies=[Depends(require_permission("system:user:resetpwd"))])
|
|
def update_password(payload: PasswordUpdate, user: User = Depends(current_user), db: Session = Depends(get_db)):
|
|
if payload.type == "updateByOldPassword" and not user.check_password(payload.old_password or ""):
|
|
raise BizError("密码错误")
|
|
user.set_password(payload.new_password)
|
|
db.commit()
|
|
return ok()
|
|
|
|
|
|
@router.put("/{id}", dependencies=[Depends(require_permission("system:user:edit"))])
|
|
def update_user(id: str, payload: UserUpdate, db: Session = Depends(get_db)):
|
|
user = get_or_404(db, User, id, "用户不存在")
|
|
values = payload.model_dump(exclude_unset=True)
|
|
assert_unique_user(
|
|
db,
|
|
user_id=id,
|
|
username=values.get("username"),
|
|
phone=values.get("phone"),
|
|
email=values.get("email"),
|
|
)
|
|
for key in ("username", "phone", "email", "realname", "desc", "avatar", "gender", "status"):
|
|
if key in values:
|
|
setattr(user, key, values[key])
|
|
if values.get("roles") is not None:
|
|
user.roles = bind_roles(db, values["roles"])
|
|
if values.get("depts") is not None:
|
|
user.depts = bind_depts(db, values["depts"])
|
|
db.commit()
|
|
db.refresh(user)
|
|
return ok(dump_user(user))
|
|
|
|
|
|
@router.delete("/{id}", dependencies=[Depends(require_permission("system:user:delete"))])
|
|
def delete_user(id: str, db: Session = Depends(get_db)):
|
|
user = get_or_404(db, User, id, "用户不存在")
|
|
db.delete(user)
|
|
db.commit()
|
|
return ok()
|
|
|
|
|
|
def _query_users(query: UserQuery):
|
|
stmt = (
|
|
select(User)
|
|
.options(
|
|
selectinload(User.roles).selectinload(Role.menus),
|
|
selectinload(User.depts),
|
|
selectinload(User.attributes),
|
|
)
|
|
.order_by(User.created_at.desc())
|
|
)
|
|
stmt = apply_keyword(stmt, query.keyword, User.username, User.phone, User.email, User.realname)
|
|
if query.username:
|
|
stmt = stmt.where(User.username.like(f"%{query.username}%"))
|
|
if query.phone:
|
|
stmt = stmt.where(User.phone.like(f"%{query.phone}%"))
|
|
if query.email:
|
|
stmt = stmt.where(User.email.like(f"%{query.email}%"))
|
|
if query.realname:
|
|
stmt = stmt.where(User.realname.like(f"%{query.realname}%"))
|
|
if query.gender:
|
|
stmt = stmt.where(User.gender == query.gender)
|
|
if query.status:
|
|
stmt = stmt.where(User.status == query.status)
|
|
return stmt
|