# !/usr/bin/env python3 # -*- encoding : utf-8 -*- # @Filename : views.py # @Software : VSCode # @Datetime : 2021/11/03 17:24:24 # @Author : leo liu # @Version : 1.0 # @Description : from typing import Any, List, Optional, Union from datetime import datetime, timedelta from fastapi import APIRouter, Depends, Header, Request from sqlalchemy.orm.session import Session from sqlalchemy.sql.functions import count from core.settings import config from core import security from utils import response_code from utils.messages import msg from utils import custom_exc from db.session import get_db from models import User, Menu from extensions import logger from .schemas import user_schema, role_schema, menu_schema from .crud.user import CRUDUser from .crud.role import crud_role from .crud.menu import crud_menu router = APIRouter() def get_current_user( db: Session = Depends(get_db), token: Optional[str] = Header(None) ) -> User: """ 根据header中token 获取当前用户 :param db: :param token: :return: """ if not token: raise custom_exc.TokenAuthError(err_desc='headers not found token') crud_user = CRUDUser(User) token_data = security.check_jwt_token(token) user = crud_user.get(db, id=token_data.sub) if not user: raise custom_exc.UserNotFound(err_desc="user not found") return user @router.post("/auth/login", summary="登录") async def auth_login( *, db: Session = Depends(get_db), user_info: user_schema.UserAuth, request: Request ) -> Any: crud_user = CRUDUser(User) # 验证用户 user = crud_user.authenticate(db, username=user_info.username, password=user_info.password, ip=request.client.host) if not user: return response_code.resp_200(message=msg.MSG_WRONG_USERINFO) elif not crud_user.is_active(user): return response_code.resp_200(message=msg.MSG_USER_INACTIVE) elif crud_user.is_delete(user): return response_code.resp_200(message=msg.MSG_USER_UNSIGNUP) access_token_expires = timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES) logger.info(f"用户[{user.username}]登录成功") return response_code.resp_200(data={ "message": msg.MSG_USER_LOGIN_SUCCESS, "token": security.create_access_token(user.id, expires_delta=access_token_expires), }) @router.post("/auth/userinfo", summary="个人信息") async def auth_info( *, current_user: User = Depends(get_current_user) ) -> Any: """ 获取用户信息 :param db: :param current_user: :return: """ menus = [] roles = [] for role in current_user.roles: for menu in role.menus: menus.append(menu.path) roles.append(role.name) return response_code.resp_200(data={ "username": current_user.username, "nickname": current_user.nickname, "email": current_user.email, "avatar": current_user.avatar, "roles": roles, "menus": menus }) @router.post("/auth/logout", summary="登出") async def auth_logout( *, current_user: User = Depends(get_current_user) ): """ 用户退出 :param current_user: """ logger.info(f"用户[{current_user.username}]退出登录") return response_code.resp_200(message="logout success") @router.post("/auth/users", summary="用户列表") async def user_list( *, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), query: user_schema.UserQuery = None ): """ 用户列表 """ crud_user = CRUDUser(User) is_accessable = False for role in current_user.roles: for menu in role.menus: if menu.path == "/system/auth/user": is_accessable = True break if not is_accessable: logger.info(f"无权查询用户列表->用户id:{current_user.username}") return response_code.resp_200(data=None) else: logger.info(f"查询用户列表->用户id:{current_user.username}当前页{query.page}长度{query.page_size}") response_result = crud_user.query_all(db, col_val=query.col_val, is_delete=query.is_delete, role=query.role, page=query.page, page_size=query.page_size, order_by=query.order_by, is_desc=query.is_desc) return response_code.resp_200(data=response_result) @router.post("/auth/roles", summary="角色列表") async def role_list( *, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), query: role_schema.RoleQuery = None ): """ 角色列表 """ is_accessable = False for role in current_user.roles: for menu in role.menus: if menu.path == "/system/auth/role": is_accessable = True break if not is_accessable: logger.info(f"无权查询角色列表->用户id:{current_user.username}") return response_code.resp_200(data=None) else: logger.info(f"查询角色列表->用户id:{current_user.username}当前页{query.page}长度{query.page_size}") response_result = crud_role.query_all(db, col_val=query.col_val, is_delete=query.is_delete, page=query.page, page_size=query.page_size, order_by=query.order_by, is_desc=query.is_desc) return response_code.resp_200(data=response_result) @router.post("/auth/newuser", summary="创建用户") async def new_user( *, db: Session = Depends(get_db), # token: Optional[str] = Header(None), user: user_schema.UserCreate ) -> Any: """ 创建用户 """ # logger.info(f"创建新用户->用户id:{user.username}") crud_user = CRUDUser(User) if (crud_user.is_exist(db, user_in=user)): logger.info(f"创建新用户失败,用户已存在->帐号:{user.username}") return response_code.resp_5010(message="user already exist") user = crud_user.create(db, obj_in=user) if (user): logger.info(f"创建新用户成功->帐号:{user.username}") return response_code.resp_200(data=user, message="success created user") else: logger.info(f"创建新用户失败->帐号:{user.username}") return response_code.resp_5010(data=None, message="failed created user") @router.post("/auth/updateuser", summary="修改用户/逻辑删除用户") async def update_user( *, db: Session = Depends(get_db), token: Optional[str] = Header(None), user: user_schema.UserUpdate ) -> Any: """ 创建用户 """ # logger.info(f"创建新用户->用户id:{user.username}") crud_user = CRUDUser(User) if (not crud_user.is_exist(db, user)): logger.info(f"修改用户失败,用户不存在->用户id:{user.username}") return response_code.resp_5010(message="user not exist") user = crud_user.update(db, obj_in=user) if (user): logger.info(f"修改用户成功->用户id:{user.username}") return response_code.resp_200(data=user, message="success updated user") else: logger.info(f"修改用户失败->用户id:{user.username}") return response_code.resp_5010(data=None, message="failed updated user") @router.post("/auth/newrole", summary="创建角色") async def new_role( *, db: Session = Depends(get_db), token: Optional[str] = Header(None), role: role_schema.RoleCreate ) -> Any: """ 创建角色 """ if (crud_role.is_exist(db, role_in=role)): logger.info(f"创建新角色失败,角色已存在->角色名称:{role.name}") return response_code.resp_5010(message="role already exist") role = crud_role.create(db, obj_in=role) if (role): logger.info(f"创建新角色成功->角色标题:{role.title}") return response_code.resp_200(data=role, message="success created role") else: logger.info(f"创建新角色失败->角色标题:{role.title}") return response_code.resp_5010(data=None, message="failed created role") @router.post("/auth/roleinfo", summary="角色信息") async def role_info( *, db: Session = Depends(get_db), token: Optional[str] = Header(None), query: role_schema.BaseRole ) -> Any: """ 获取角色信息 :param db: :param token: :param role_id: :return: """ role = crud_role.get_by_id(db=db, role_id=query.role_id) if(role): return response_code.resp_200(data={ "role_id": query.role_id, "name": role.name, "title": role.title, "menus": role.menus, "is_delete": role.is_delete }) return response_code.resp_200(data=None) @router.post("/auth/updaterole", summary="修改角色/逻辑删除角色") async def update_role( *, db: Session = Depends(get_db), token: Optional[str] = Header(None), role: role_schema.RoleUpdate ) -> Any: """ 修改角色 """ role = crud_role.update(db, obj_in=role) if (role): logger.info(f"修改角色成功->角色名:{role.name}") return response_code.resp_200(data=role, message="success updated role") else: logger.info(f"修改角色失败->角色名:{role.name}") return response_code.resp_5010(data=None, message="failed updated role") @router.post("/auth/menus", summary="菜单列表") async def menu_list( *, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), query: menu_schema.MenuQuery = None ): """ 菜单列表 """ logger.info(f"查询菜单列表->用户id:{current_user.username}当前页{query.page}长度{query.page_size}") response_result = crud_menu.query_all(db, col_val=query.col_val, is_delete=query.is_delete, page=query.page, page_size=query.page_size, order_by=query.order_by, is_desc=query.is_desc) return response_code.resp_200(data=response_result) @router.post("/auth/syncmenus", summary="同步菜单") async def sync_menus( *, db: Session = Depends(get_db), token: Optional[str] = Header(None), data: List = None ): if (data and data.count): crud_menu.sync_menus(db, obj_arr = data) response_result = crud_menu.query_all(db, is_delete=0) return response_code.resp_200(data=response_result)