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.

323 lines
10 KiB

3 years ago
# !/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)