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.
120 lines
4.7 KiB
120 lines
4.7 KiB
from tortoise import fields, models
|
|
|
|
from helper.mask import Mask
|
|
from helper.utils import timezone_now
|
|
from models import Role, ModuleMenu
|
|
|
|
|
|
class User(models.Model):
|
|
id = fields.UUIDField(pk=True)
|
|
username = fields.CharField(max_length=255, unique=True, description='账号')
|
|
password_digest = fields.CharField(max_length=255, description='密码')
|
|
name = fields.CharField(max_length=255, description='姓名')
|
|
locked = fields.BooleanField(default=False, description='是否锁定')
|
|
# role_id = fields.IntField(description='用户角色')
|
|
role = fields.ForeignKeyField('rms.Role', description='用户角色')
|
|
department = fields.ForeignKeyField('rms.Department', on_delete=fields.CASCADE, null=True, description='所属部门')
|
|
login_frozen_count = fields.SmallIntField(default=0, description='登录失败次数')
|
|
last_attempt_at = fields.DatetimeField(null=True, description='最后尝试时间')
|
|
last_login_at = fields.DatetimeField(null=True, description='最后登录时间')
|
|
password_expired_at = fields.DatetimeField(null=True, description='密码时效期')
|
|
face = fields.BinaryField(null=True, description='人脸二进制')
|
|
drawers = fields.JSONField(null=True, default=[], description='可访问抽屉')
|
|
sex = fields.IntField(default=0, null=True, description='0未知 1男 2女')
|
|
phone = fields.CharField(null=True, description="手机号", max_length=11)
|
|
email = fields.CharField(max_length=255, null=True, description='邮箱')
|
|
created_at = fields.DatetimeField(auto_now_add=True)
|
|
updated_at = fields.DatetimeField(auto_now=True)
|
|
login_key = fields.CharField(null=True,max_length=255, description='账号标识')
|
|
raw = fields.CharField(null=True,max_length=255, description='卡片登录')
|
|
keys = fields.JSONField(null=True, description='钥匙权限')
|
|
|
|
class Meta:
|
|
table = 'users'
|
|
table_description = '用户表'
|
|
|
|
def as_json(self):
|
|
return dict(id=self.id, username=self.username, name=self.name, role_id=self.role_id, locked=self.locked,
|
|
sex=self.sex, phone=self.phone, emali=self.email,raw=self.raw
|
|
)
|
|
|
|
# @classmethod
|
|
# async def fetch(cls, id: str, reload: bool = False, expire: int = 1800):
|
|
# key = f'rms_user_{id}'
|
|
|
|
# user = await User.get_or_none(id = id)
|
|
|
|
# await redis.hset(key, mapping = user.as_json())
|
|
|
|
# print(await redis.hgetall(key))
|
|
|
|
# if reload:
|
|
# await redis.delete(key)
|
|
|
|
# cache = await redis.get(key)
|
|
# if not cache:
|
|
# user = await User.get_or_none(id = id)
|
|
# if not user:
|
|
# return None
|
|
# await redis.set(key, json.dumps(user.as_json()), ex = expire)
|
|
# return user.as_json()
|
|
# return cache
|
|
|
|
@property
|
|
async def profile(self):
|
|
"""登录用户信息"""
|
|
permission = await self.permission
|
|
role = await Role.get(id=self.role_id)
|
|
|
|
return dict(id=self.id, name=self.name, username=self.username, permission=permission, protion=role.portion,
|
|
password_expired=self.password_expired, grade=role.grade)
|
|
|
|
def __str__(self):
|
|
return 'User(id={0.id} username={0.username}, name={0.name}, role.id={0.role_id})'.format(self)
|
|
|
|
# @property
|
|
# def frozen(self) -> bool:
|
|
# '''是否被冻结'''
|
|
# return setting.LOGIN_FROZEN_COUNT > 0 and self.login_frozen_count >= setting.LOGIN_FROZEN_COUNT
|
|
|
|
@property
|
|
def password_expired(self) -> bool:
|
|
'''密码是否已过期'''
|
|
if self.password_expired_at is None:
|
|
return True
|
|
return self.password_expired_at < timezone_now()
|
|
|
|
@property
|
|
def nickname(self):
|
|
'''用户昵称'''
|
|
return self.name or self.username
|
|
|
|
async def cabinets(self):
|
|
'''用户可见柜体'''
|
|
pass
|
|
|
|
@property
|
|
async def permission(self):
|
|
'''用户可见模块权限'''
|
|
role = await Role.get(id=self.role_id)
|
|
masks = role.masks
|
|
menu = await ModuleMenu.all().order_by("rank")
|
|
map = {str(m.id): m.name for m in menu}
|
|
return [{'id': int(k), 'name': v, 'mask': masks[k]} for k, v in map.items() if k in masks]
|
|
|
|
async def permit(self, menu_id: str, mask: Mask):
|
|
'''用户对指定模块是否有动作权限'''
|
|
role = await Role.get(id=self.role_id)
|
|
masks = role.masks
|
|
return (int(masks.get(menu_id, 0)) & mask) == mask
|
|
|
|
@staticmethod
|
|
async def parse_id_user(user_ids: list):
|
|
"""用户id列表转换为用户名"""
|
|
user_name_list = list()
|
|
for user_id in user_ids:
|
|
user_obj = await User.get_or_none(id=user_id)
|
|
user_name = user_obj.name if user_obj else ""
|
|
user_name_list.append(user_name)
|
|
return ",".join(user_name_list)
|