class PrivGrant(BaseModel): priv_grant_id = models.AutoField(primary_key=True, verbose_name='授权标识') priv = models.ForeignKey(Privilege, on_delete=models.CASCADE, verbose_name='权限标识') grant_obj_type = models.CharField(max_length=10, verbose_name='授权对象类型', choices=get_attr_values( 'PrivGrant', 'GRANT_OBJ_TYPE')) grant_obj_id = models.IntegerField(verbose_name='授权对象标识') oper_type = models.CharField(max_length=4, verbose_name='授权操作类型', choices=get_attr_values( 'PrivGrant', 'GRANT_OPER_TYPE')) class Meta: db_table = 'priv_grant' verbose_name_plural = "授权" verbose_name = "授权" # 获取授权对象 def grant_obj(self): obj = None if self.grant_obj_type == GRANT_OBJ_TYPE_SYSTEM_USER: # 系统用户 obj = SystemUser.objects.get(sys_user_id=self.grant_obj_id) elif self.grant_obj_type == GRANT_OBJ_TYPE_SYSTEM_POST: # 系统岗位 obj = SystemPost.objects.get(sys_user_id=self.grant_obj_id) elif self.grant_obj_type == GRANT_OBJ_TYPE_SYSTEM_ROLES: # 系统角色 obj = SystemRoles.objects.get(sys_user_id=self.grant_obj_id) return obj grant_obj.short_description = u'授权对象' # 添加授权 @staticmethod def add_priv_grant(priv_id, grant_obj_id, grant_obj_type): priv_grant = PrivGrant() priv_grant.priv_id = priv_id priv_grant.grant_obj_id = grant_obj_id priv_grant.grant_obj_type = grant_obj_type priv_grant.oper_type = GRANT_OPER_TYPE_ALLOW priv_grant.save() # 获取系统用户配置的权限(全部) @staticmethod def get_priv_grants(grant_obj_id, grant_obj_type): priv_grants = PrivGrant.objects.filter(grant_obj_id=grant_obj_id, status_cd=STATUS_ACTIVE, grant_obj_type=grant_obj_type) return priv_grants
class Privilege(BaseModel): priv_id = models.AutoField(primary_key=True, verbose_name='权限标识') priv_code = models.CharField(max_length=30, verbose_name='权限编码', blank=True) priv_name = models.CharField(max_length=250, verbose_name='权限名称') priv_type = models.CharField( max_length=6, verbose_name='权限类型', choices=get_attr_values('Privilege', 'PRIV_TYPE'), default=get_attr_default_value('Privilege', 'PRIV_TYPE')) priv_desc = models.CharField(max_length=250, verbose_name='权限描述', blank=True, null=True) def __str__(self): return u'%s' % self.priv_name class Meta: db_table = 'privilege' verbose_name_plural = "权限" verbose_name = "权限" # 保存 def save(self): if not self.priv_code: # 如果未设置,则将权限编码默认为当前时间戳 self.priv_code = datetime.datetime.strftime( datetime.datetime.now(), '%Y%m%d%H%M%S') super(Privilege, self).save()
class SystemRoles(BaseModel): sys_role_id = models.AutoField(primary_key=True, verbose_name='系统角色标识') sys_role_name = models.CharField(max_length=50, verbose_name='系统角色名称') sys_role_code = models.CharField(max_length=30, verbose_name='系统角色编码', null=True, blank=True) sys_role_desc = models.CharField(max_length=250, verbose_name='系统角色描述', null=True, blank=True) init_flag = models.IntegerField(verbose_name='是否系统初始数据', choices=get_attr_values( 'BaseModel', 'TRUE_OR_FALSE'), null=True, blank=True, default=FALSE) class Meta: db_table = 'system_roles' verbose_name_plural = "系统角色" verbose_name = "系统角色" def __str__(self): return u'%s' % self.sys_role_name
class Organization(MPTTModel, BaseModel): org_id = models.AutoField(primary_key=True, verbose_name='组织标识') org_name = models.CharField(max_length=250, verbose_name='组织名称') org_type = models.CharField( max_length=4, verbose_name='组织类型', choices=get_attr_values('Organization', 'ORG_TYPE'), default=get_attr_default_value('Organization', 'ORG_TYPE')) org_level = models.PositiveIntegerField(verbose_name='组织级别', default=1) org_index = models.PositiveIntegerField(verbose_name='组织排序', default=1) parent_org = TreeForeignKey('self', on_delete=models.CASCADE, verbose_name='上级组织标识', blank=True, null=True, related_name='children') region = models.ForeignKey(CommonRegion, on_delete=models.CASCADE, verbose_name='所在地区', null=True) # def __init__(self, *args, **kwargs): # super().__init__(*args, **kwargs) # self.fields['org_type'].choices = get_attr_values('Organization', 'ORG_TYPE') # self.fields['org_type'].default = get_attr_default_value('Organization', 'ORG_TYPE') def __str__(self): return u'%s' % self.org_name class Meta: db_table = 'organization' verbose_name_plural = "组织" verbose_name = "组织" class MPTTMeta: parent_attr = 'parent_org' level_attr = 'org_level' order_insertion_by = ['org_index']
class SystemUserPost(BaseModel): sys_user_post_id = models.AutoField(primary_key=True, verbose_name='系统角色标识') sys_post = models.ForeignKey(SystemPost, on_delete=models.CASCADE, verbose_name='系统岗位标识') sys_user = models.ForeignKey(SystemUser, on_delete=models.CASCADE, verbose_name='系统用户标识') org = TreeForeignKey(Organization, on_delete=models.CASCADE, verbose_name='隶属组织') host_flag = models.IntegerField(verbose_name='是否主岗位', choices=get_attr_values( 'BaseModel', 'TRUE_OR_FALSE'), null=True, blank=True, default=TRUE) class Meta: db_table = 'system_user_post' verbose_name_plural = "系统用户任职岗位" verbose_name = "系统用户任职岗位"
class FuncMenu(MPTTModel, BaseModel): menu_id = models.AutoField(primary_key=True, verbose_name='菜单标识') menu_name = models.CharField(max_length=50, db_index=True, verbose_name='菜单名称') menu_type = models.CharField(max_length=4, verbose_name='菜单类型', choices=get_attr_values( 'FuncMenu', 'MENU_TYPE')) menu_level = models.PositiveIntegerField(verbose_name='菜单级别', default=1) menu_index = models.PositiveIntegerField(verbose_name='菜单排序', default=1) par_menu = TreeForeignKey('self', on_delete=models.CASCADE, verbose_name='上级菜单', blank=True, null=True, related_name='children') url_addr = models.CharField(max_length=250, verbose_name='菜单地址', blank=True) # 菜单URL地址 menu_desc = models.CharField(max_length=250, verbose_name='菜单描述', blank=True) icon = models.CharField(max_length=50, db_index=True, verbose_name='菜单图标', default=DEFAULT_MENU_ICON) def __str__(self): return u'%s' % self.menu_name class Meta: db_table = 'func_menu' verbose_name_plural = "菜单" # 复数形式,如果只设置verbose_name,在Admin会显示为“菜单s” verbose_name = "菜单" ordering = ('menu_index', ) class MPTTMeta: parent_attr = 'par_menu' level_attr = 'menu_level' # 获取菜单 @classmethod def get_menus(self, user): # 先从缓存中取 cache_key = CACHE_USER_PRIVS % user.sys_user_id menus = read_from_cache(cache_key) if menus: return menus # 取不到再查 menus = [] par_menus = self.objects.filter( par_menu_id=None, status_cd=STATUS_ACTIVE).order_by('menu_index') if len(par_menus) > 0: for menu in par_menus: # 判断是否有目录权限 if user.has_perm_by_priv_id(menu.menu_id) is False: continue # 添加目录 child_datas = [] par_data = { 'name': menu.menu_name, 'icon': menu.icon, 'models': child_datas } menus.append(par_data) # 添加菜单 childs = menu.children.filter( status_cd=STATUS_ACTIVE).order_by('menu_index') if len(childs) > 0: for child in childs: # 判断是否有菜单权限 if user.has_perm_by_priv_id(child.menu_id) is False: continue child_data = { 'name': child.menu_name, 'url': child.url_addr, 'icon': child.icon } child_datas.append(child_data) write_to_cache(cache_key, menus, CACHE_TIMEOUT_ONE_DAY) return menus # 获取权限编码 def get_priv_code(menu_id): priv_code = None priv_func_rel = PrivFuncRel.objects.filter( priv_ref_id=menu_id, priv_ref_type=PRIV_REL_TYPE_MENU, status_cd=STATUS_ACTIVE).first() if priv_func_rel and priv_func_rel.priv: priv_code = priv_func_rel.priv.priv_code return priv_code # 保存 def save(self): # 保存功能菜单 super(FuncMenu, self).save() privilege = None if self._state.adding is True: # 权限表 privilege = Privilege() # 权限包含功能表 priv_func_rel = PrivFuncRel() else: priv_func_rels = PrivFuncRel.objects.filter( priv_ref_id=self.menu_id, priv_ref_type=PRIV_REL_TYPE_MENU) if len(priv_func_rels) > 0: priv_func_rel = priv_func_rels[0] privilege = priv_func_rel.priv else: priv_func_rel = PrivFuncRel() privilege = Privilege() # 保存权限表 privilege.priv_name = self.menu_name privilege.priv_type = PRIV_TYPE_FUNC # 当菜单为叶子节点(即页面时),设置编码跟django的权限编码对应上, if self.menu_type == MENU_TYPE_PAGE: url_addr = self.url_addr.split('/') privilege.priv_code = url_addr[0] + '.view_' + url_addr[1] privilege.save() # 保存权限包含功能表 priv_func_rel.priv_id = privilege.priv_id priv_func_rel.priv_ref_id = self.menu_id priv_func_rel.priv_ref_type = PRIV_REL_TYPE_MENU priv_func_rel.save()
class Staff(BaseModel): staff_id = models.AutoField(primary_key=True, verbose_name='员工标识') staff_code = models.CharField(max_length=250, verbose_name='员工编号', null=True) staff_type = models.CharField( max_length=10, verbose_name='员工类型', choices=get_attr_values('Staff', 'STAFF_TYPE'), default=get_attr_default_value('Staff', 'STAFF_TYPE')) staff_name = models.CharField(max_length=250, verbose_name='员工姓名') org = TreeForeignKey(Organization, on_delete=models.CASCADE, verbose_name='隶属组织') region = TreeForeignKey(CommonRegion, on_delete=models.CASCADE, verbose_name='所在地区', null=True) class Meta: db_table = 'staff' verbose_name_plural = "员工" verbose_name = "员工" def __str__(self): return u'%s' % self.staff_name # 获取完整的区域名称 def whole_region_name(self): region_name = '' if self.region: region_name = self.region.whole_region_name return region_name whole_region_name.short_description = u'所在区域' # 获取员工的系统用户 def get_system_user(self): from ops.models.system_user import SystemUser systemuser = SystemUser.objects.filter(staff_id=self.staff_id).first() return systemuser # 系统用户任职岗位名称 def post_name(self): system_user_post = self.get_system_user().get_system_user_post( self.org_id) if system_user_post is not None: return system_user_post.sys_post.sys_post_name return '' post_name.short_description = u'岗位' # 系统用户角色名称 def role_name(self): name = '' system_user_roles = self.get_system_user().get_system_user_roles() if system_user_roles is None or len(system_user_roles) == 0: return name for system_user_role in system_user_roles: name = name + system_user_role.sys_role.sys_role_name + ',' name = name.rstrip(',') return name role_name.short_description = u'角色'
class CommonRegion(MPTTModel, BaseModel): common_region_id = models.AutoField(primary_key=True, verbose_name='公共管理区域标识') region_name = models.CharField(max_length=250, verbose_name='区域名称', db_index=True) region_py_name = models.CharField(max_length=250, verbose_name='区域拼音名称', null=True, blank=True) region_nbr = models.CharField(max_length=30, verbose_name='区域编码', null=True, blank=True) region_type = models.CharField(max_length=6, verbose_name='区域类型', choices=get_attr_values( 'CommonRegion', 'REGION_TYPE'), null=True) par_region = TreeForeignKey('self', on_delete=models.CASCADE, verbose_name='上级区域标识', blank=True, null=True, related_name='children') region_level = models.PositiveIntegerField(verbose_name='区域级别') province_nbr = models.CharField(max_length=32, verbose_name='省份编码', null=True, blank=True) remark = models.CharField(max_length=250, verbose_name='备注', null=True, blank=True) def __str__(self): return u'%s' % self.region_name # 获取完成区域名称,如 中国/福建省/厦门市/湖里区 @property def whole_region_name(self): region_name = '' regions = [] regions.append(self.region_name) par_region = self.par_region while par_region: regions.append(par_region.region_name) par_region = par_region.par_region if len(regions) > 0: region_name = "/".join( map(str, [region for region in reversed(regions)])) return region_name # 保存 def save(self): # 自动设置区域拼音名称 region_name = re.sub('省|市|区|县|自治|回族|', '', self.region_name) words = pinyin(region_name, style=Style.NORMAL) if len(words) > 0: self.region_py_name = "".join( map(str, [v.capitalize() for sub in words for v in sub])) # 自动设置区域类型 region_type = { '0': REGION_TYPE_COUNTRY, '1': REGION_TYPE_PROVINCE, '2': REGION_TYPE_CITY, '3': REGION_TYPE_COUNTY, } if self.par_region: self.region_type = region_type.get( str(self.par_region.region_level + 1)) else: self.region_type = region_type.get(str(self.region_level)) # 保存 super(CommonRegion, self).save() class Meta: db_table = 'common_region' verbose_name_plural = u'公共管理区域' verbose_name = u'公共管理区域' class MPTTMeta: parent_attr = 'par_region' level_attr = 'region_level' order_insertion_by = ['region_nbr']