You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
6.0 KiB

# -*- coding:utf-8 -*-
"""
@Created on : 2023/6/30 10:09
@Author: hxl
@Des:
"""
import hashlib
from fastapi import APIRouter, Depends
from pydantic import BaseModel, constr
from starlette.requests import Request
from tortoise.queryset import QuerySet, Q
from conf import setting
from endpoints.cab.user import UserDrawersEdit
from helper import respond_to, login_required
from helper.log import logger_wrapper, record_log
from helper.utils import encrypt_md5
from models import User, PlatformSecurity, Role, Drawer, Department
from models import User, PasswordSecureMode
router = APIRouter(prefix='/users', dependencies=[Depends(login_required)])
class UserEdit(BaseModel):
username: str
name: str
role_id: int
# department_id: str | None
# sex: int | None
phone: str | None
password: str
# email: str | None
locked: bool | None
class UpdatePassword(BaseModel):
password: str
class SignUp(BaseModel):
username: constr(strip_whitespace=True)
name: str
# department_id: str | None
role_id: int
# sex: int | None
phone: str | None
# email: str | None
# locked: bool
drawers: list = []
@router.post('', summary='创建账号')
async def create(request: Request, model: SignUp):
if len(model.username) < 4:
return respond_to(code=400, desc='用户名长度不能小于4位')
user = await User.get_or_none(username=model.username)
if user:
return respond_to(code=409, desc='账号已注册')
password_digest = encrypt_md5(setting.REGISTER_INIT_PASSWORD)
user = await User.create(**model.dict(), password_digest=password_digest)
record = {
"user_id": request.state.current_user.id,
"users": request.state.current_user.name,
"kind": "用户",
"comment": f"{request.state.current_user.name}创建用户{model.name},创建用户成功"
}
await record_log(**record)
return respond_to(data=user.as_json())
@router.get('/{id}', summary='获取个人信息')
async def show(id: str):
user = await User.get(id=id)
role = await Role.get(id=user.role_id)
result = user.as_json()
return respond_to(data=result)
@router.post("/{user_id}", summary='更新人脸信息')
async def process_face_feature(user_id: str, request: Request):
# 在此处对接收到的人脸特征进行处理
face_blob = await request.body()
user = await User.get(id=user_id)
md5 = hashlib.md5()
md5.update(face_blob)
encrypted_face = md5.hexdigest()
print(encrypted_face)
user.face = face_blob
await user.save()
return respond_to()
@router.get('', summary='用户列表')
async def index(request: Request, page_no: int = 1, page_size: int = 20, username: str = None, name: str = None,
role_id: int = None):
"""
用户列表隐藏admin账号
"""
offset = (page_no - 1) * page_size
current_role_id = request.state.current_user.role_id
query = QuerySet(User)
if username:
query = query.filter(Q(username__contains=username) | Q(name__contains=username))
if name:
query = query.filter(name__contains=name)
if role_id:
query = query.filter(role_id=role_id)
count = await query.count()
users_objs = await query.limit(page_size).offset(offset).order_by('-created_at').values(
"id", "username", "locked", "sex", "phone", "email", "role_id", "department_id", "name", "created_at", "last_login_at")
user_list = list()
for user in users_objs:
role_obj = await Role.get_or_none(id=user.get("role_id"))
department_obj = await Department.get_or_none(id=user.get("department_id"))
user["role_name"] = role_obj.name
user["department_name"] = department_obj.name if department_obj else None
user_list.append(user)
return respond_to(data=dict(count=count, users=users_objs))
@router.put('/{user_id}', summary='修改用户信息')
@logger_wrapper
async def update(user_id: str, post: UserEdit):
"""修改用户信息"""
user = await User.get(id=user_id)
user.username = post.username
user.name = post.name
user.role_id = post.role_id
if post.password:
if encrypt_md5(post.password) == user.password_digest:
return respond_to(code=403, desc='新密码不可与原密码相同')
if not await PasswordSecureMode.verify(post.password):
mode = await PasswordSecureMode.get(checked=True)
return respond_to(code=403, desc=f'密码安全等级不足,{mode.comment}')
user.password_digest = encrypt_md5(post.password)
user.login_frozen_count = 0
user.last_attempt_at = None
await user.save()
return respond_to(200, desc=f"修改[{user.name}]用户信息成功")
@router.patch('/{user_id}', summary='修改密码')
@logger_wrapper
async def destroy(request: Request, user_id: str, post: UpdatePassword):
"""锁定账号"""
source = await PlatformSecurity.all().first()
user = await User.get(id=user_id)
user.password_digest = encrypt_md5(post.password)
user.login_frozen_count = 0
user.last_attempt_at = None
# user.password_expired_at = timezone_now() + timedelta(days=source.reset_password_duration)
await user.save()
return respond_to(200)
@router.put('/{id}/drawers', summary="更新柜体权限")
@logger_wrapper
async def update(request: Request, id: str, model: UserDrawersEdit):
"""更新柜体权限"""
user = await User.get(id=id)
drawers = model.drawers
cabinet_id = model.cabinet_id
current_drawers_query = Drawer.filter(cabinet_id=cabinet_id).values('id')
current_drawers_set = {str(drawer['id']) async for drawer in current_drawers_query}
db_drawers_set = set(user.drawers)
other_drawers_set = db_drawers_set - current_drawers_set
updated_drawers = set(drawers) | other_drawers_set
user.drawers = list(updated_drawers)
await user.save(update_fields=['drawers'])
return respond_to()
@router.get('/{id}/drawers', summary="获取柜体权限")
async def show(request: Request, id: str):
user = await User.get(id=id)
return respond_to(data=user.drawers)