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.

216 lines
6.9 KiB

3 years ago
# !/usr/bin/env python3
# -*- encoding : utf-8 -*-
# @Filename : user.py
# @Software : VSCode
# @Datetime : 2021/11/04 21:25:44
# @Author : leo liu
# @Version : 1.0
# @Description :
from datetime import datetime
from typing import Optional
from loguru import logger
from pydantic.types import conint
from sqlalchemy import func, desc
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import and_, or_, join
from core.security import get_password_hash, verify_password
from extensions.curd_base import CRUDBase
from models import User, Role, LoginHistory
from .role import crud_role
from ..schemas import user_schema
class CRUDUser(CRUDBase[User, user_schema.UserCreate, user_schema.UserUpdate]):
@staticmethod
def query_all(db: Session, *, col_val: str = "", is_delete: int = 0, role: str = "", page: int = 1, page_size: conint(le=50) = 20, order_by: str = "id", is_desc: bool = False) -> dict:
"""
查询用户列表
:param db:
:param page:
:param page_size:
:return:
"""
temp_page = (page - 1) * page_size
search = None
order_type = None
# 处理多个字段的模糊查询username、nickname、email
if col_val:
search = and_(User.is_delete == is_delete, or_(User.username.like('%' + col_val + "%"), User.nickname.like('%' + col_val + "%"), User.email.like('%' + col_val + "%")))
else:
search = User.is_delete == is_delete
# 处理角色查询role
if role:
search = and_(search, Role.role_id == role)
# 处理排序方式
# 利用属性名反射类属性
if is_desc:
order_type = desc(User.getAttrFromName(User, order_by))
else:
order_type = User.getAttrFromName(User, order_by)
# 查询数量
total = db.query(func.count(User.user_id)).outerjoin(User.roles).filter(search).scalar()
# 查询结果集
if page > 0: # page > 0 分页查询
query_obj = db.query(User).outerjoin(User.roles).filter(search).order_by(order_type).offset(temp_page).limit(page_size).all()
else: # page <= 0 全量查询
query_obj = db.query(User).outerjoin(User.roles).filter(search).order_by(order_type).all()
items = [{
"id": obj.id,
"user_id": obj.user_id,
"username": obj.username,
"nickname": obj.nickname,
"email": obj.email,
"avatar": obj.avatar,
"phone": obj.phone,
"gender": obj.gender,
"register_time": obj.register_time,
"last_login_time": obj.last_login_time,
"last_login_ip": obj.last_login_ip,
"wechat_openid": obj.wechat_openid,
"country": obj.country,
"province": obj.province,
"city": obj.city,
"roles": obj.roles,
"is_delete": obj.is_delete,
"update_time": obj.update_time
} for obj in query_obj]
return {
"items": items,
"total": total
}
@staticmethod
def get_by_email(db: Session, *, email: str) -> Optional[User]:
"""
通过email获取用户
参数里面的* 表示 后面调用的时候 要用指定参数的方法调用
正确调用方式
curd_user.get_by_email(db, email="xxx")
错误调用方式
curd_user.get_by_email(db, "xxx")
:param db:
:param email:
:return:
"""
return db.query(User).filter(User.email == email).first()
@staticmethod
def get_by_username(db: Session, *, username: str) -> Optional[User]:
"""
通过用户名获取用户
"""
return db.query(User).filter(User.username == username).first()
def authenticate(self, db: Session, *, username: str, password: str, ip: str) -> Optional[User]:
user = self.get_by_username(db, username=username)
if not user:
return None
if not verify_password(password, user.hashed_password):
return None
user.last_login_time = datetime.now()
user.last_login_ip = ip
login_history = LoginHistory(
user_id = user.user_id,
username = user.username,
login_time = user.last_login_time,
login_ipv4 = user.last_login_ip
)
user.login_histories.append(login_history)
db.commit()
db.refresh(user)
return user
def authenticate_by_email(self, db: Session, *, email: str, password: str) -> Optional[User]:
user = self.get_by_email(db, email=email)
if not user:
return None
if not verify_password(password, user.hashed_password):
return None
return user
@staticmethod
def is_active(user: User) -> bool:
return user.is_active == 1
@staticmethod
def is_delete(user: User) -> bool:
return user.is_delete == 1
@staticmethod
def is_exist(db: Session, user_in: user_schema.UserCreate) -> bool:
user = db.query(User).filter(User.username == user_in.username).first()
if user:
return True
else:
return False
@staticmethod
def create(db: Session, *, obj_in: user_schema.UserCreate) -> User:
db_user = User(
username=obj_in.username,
nickname=obj_in.nickname,
email=obj_in.email,
hashed_password=get_password_hash(obj_in.password),
q_limit_day=obj_in.q_limit_day,
tokens_limit=obj_in.tokens_limit,
# avatar=obj_in.avatar,
is_active=obj_in.is_active
)
for role_id in obj_in.roles:
role = crud_role.get_by_id(db, role_id=role_id)
if (role):
db_user.roles.append(role)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
@staticmethod
def update(db: Session, *, obj_in: user_schema.UserUpdate) -> User:
db_obj = db.query(User).filter(User.username == obj_in.username).first()
if db_obj:
db_obj.nickname = obj_in.nickname
db_obj.email = obj_in.email
db_obj.hashed_password = get_password_hash(obj_in.password) if obj_in.password else db_obj.hashed_password
if obj_in.q_day_limit >= 0:
db_obj.q_day_limit = obj_in.q_day_limit
if obj_in.tokens_limit >= 0:
db_obj.tokens_limit = obj_in.tokens_limit
db_obj.roles.clear()
for role_id in obj_in.roles:
role = crud_role.get_by_id(db, role_id=role_id)
if (role):
db_obj.roles.append(role)
db_obj.is_active = obj_in.is_active
db_obj.is_delete = obj_in.is_delete
db.commit()
db.refresh(db_obj)
return db_obj