import enum from django.db import models from django.contrib.auth.models import AbstractUser from apps.utils.models import CommonAModel, CommonBModel, BaseModel class DataFilter(models.IntegerChoices): ALL = 10, '全部' SAMELEVE_AND_BELOW = 30, '同级及以下' THISLEVEL_AND_BELOW = 40, '本级及以下' THISLEVEL = 50, '本级' MYSELF = 60, '仅本人' class Permission(BaseModel): """ 功能权限:目录,菜单,按钮 """ PERM_TYPE_LIST = 10 PERM_TYPE_MENU = 20 PERM_TYPE_BUTTON = 30 menu_type_choices = ( (PERM_TYPE_LIST, '目录'), (PERM_TYPE_MENU, '菜单'), (PERM_TYPE_BUTTON, '按钮') ) name = models.CharField('名称', max_length=30) type = models.PositiveSmallIntegerField('类型', choices=menu_type_choices, default=30) sort = models.PositiveSmallIntegerField('排序标记', default=1) parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父') codes = models.JSONField('权限标识', default=list, null=True, blank=True) def __str__(self): return self.name class Meta: verbose_name = '功能权限表' verbose_name_plural = verbose_name ordering = ['sort'] class Dept(CommonAModel): """ 部门 """ name = models.CharField('名称', max_length=60) type = models.CharField('类型', max_length=20, default='dept') parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父') sort = models.PositiveSmallIntegerField('排序标记', default=1) third_info = models.JSONField('三方系统信息', default=dict) class Meta: verbose_name = '部门' verbose_name_plural = verbose_name ordering = ['sort'] def __str__(self): return self.name class Role(CommonAModel): """ 角色 """ name = models.CharField('名称', max_length=32) code = models.CharField('角色标识', max_length=32, null=True, blank=True) perms = models.ManyToManyField(Permission, blank=True, verbose_name='功能权限', related_name='role_perms') description = models.CharField('描述', max_length=50, blank=True, null=True) class Meta: verbose_name = '角色' verbose_name_plural = verbose_name ordering = ['code'] def __str__(self): return self.name class Post(CommonAModel): """ 职位/岗位 """ name = models.CharField('名称', max_length=32) code = models.CharField('岗位标识', max_length=32, null=True, blank=True) description = models.CharField('描述', max_length=50, blank=True, null=True) parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父') min_hour = models.PositiveSmallIntegerField('最小在岗时间', default=0) max_hour = models.PositiveSmallIntegerField('最长在岗时间', default=12) class Meta: verbose_name = '职位/岗位' verbose_name_plural = verbose_name ordering = ['create_time'] def __str__(self): return self.name class PostRole(BaseModel): """ 岗位角色关系 """ data_range = models.PositiveSmallIntegerField('数据权限范围', choices=DataFilter.choices, default=DataFilter.THISLEVEL_AND_BELOW) post = models.ForeignKey(Post, verbose_name='关联岗位', on_delete=models.CASCADE, null=True, blank=True) role = models.ForeignKey(Role, verbose_name='关联角色', on_delete=models.CASCADE, null=True, blank=True) class User(AbstractUser, CommonBModel): """ 用户 """ type = models.CharField('账号类型', max_length=10, default='employee') name = models.CharField('姓名', max_length=20, null=True, blank=True) phone = models.CharField('手机号', max_length=11, null=True, blank=True) avatar = models.CharField( '头像', default='/media/default/avatar.png', max_length=100, null=True, blank=True) superior = models.ForeignKey( 'self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='上级主管') posts = models.ManyToManyField(Post, through='system.userpost', related_name='user_posts') depts = models.ManyToManyField(Dept, through='system.userpost') roles = models.ManyToManyField(Role, verbose_name='关联角色') class Meta: verbose_name = '用户信息' verbose_name_plural = verbose_name ordering = ['create_time'] def __str__(self): return self.username class UserPost(BaseModel): """ 用户岗位关系表 """ name = models.CharField('名称', max_length=20, null=True, blank=True) user = models.ForeignKey(User, on_delete=models.CASCADE) post = models.ForeignKey(Post, on_delete=models.CASCADE) dept = models.ForeignKey(Dept, on_delete=models.CASCADE) sort = models.PositiveSmallIntegerField('排序', default=1) class Meta: verbose_name = '用户岗位关系表' verbose_name_plural = verbose_name ordering = ['sort', 'create_time'] class DictType(CommonAModel): """ 数据字典类型 """ name = models.CharField('名称', max_length=30) code = models.CharField('标识', max_length=30) parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父') class Meta: verbose_name = '字典类型' verbose_name_plural = verbose_name ordering = ['-create_time'] def __str__(self): return self.name class Dictionary(CommonAModel): """ 数据字典 """ name = models.CharField('名称', max_length=60) value = models.CharField('值', max_length=10) code = models.CharField('标识', max_length=30, null=True, blank=True) description = models.TextField('描述', blank=True, null=True) type = models.ForeignKey( DictType, on_delete=models.CASCADE, verbose_name='类型') sort = models.PositiveSmallIntegerField('排序', default=1) parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='父') is_used = models.BooleanField('是否有效', default=True) class Meta: verbose_name = '字典' verbose_name_plural = verbose_name unique_together = ('name', 'is_used', 'type') ordering = ['sort'] def __str__(self): return self.name class File(CommonAModel): """ 文件存储表,业务表根据具体情况选择是否外键关联 """ FILE_TYPE_DOC = 10 FILE_TYPE_VIDEO = 20 FILE_TYPE_AUDIO = 30 FILE_TYPE_PIC = 40 FILE_TYPE_OTHER = 50 name = models.CharField('名称', max_length=100, null=True, blank=True) size = models.IntegerField('文件大小', default=1, null=True, blank=True) file = models.FileField('文件', upload_to='%Y/%m/%d/') type_choices = ( (FILE_TYPE_DOC, '文档'), (FILE_TYPE_VIDEO, '视频'), (FILE_TYPE_AUDIO, '音频'), (FILE_TYPE_PIC, '图片'), (FILE_TYPE_OTHER, '其它') ) mime = models.CharField('文件格式', max_length=120, null=True, blank=True) type = models.CharField('文件类型', max_length=50, choices=type_choices, default='文档') path = models.CharField('地址', max_length=200, null=True, blank=True) class Meta: verbose_name = '文件库' verbose_name_plural = verbose_name def __str__(self): return self.name