class Role(BaseModel, CreationMixin, UpdationMixin): __tablename__ = "sys_role" __table_args__ = ({'comment': "角色表"}) role_id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='角色id') role_name = db.Column(db.String(20), nullable=False, unique=True, comment='角色名称') role_description = db.Column(db.String(50), comment='角色描述') role_state = db.Column(db.String(10), nullable=False, default=ResourceState.active.value, comment='角色状态') users = db.relationship('User', backref='role', primaryjoin='foreign(User.role_id)==Role.role_id') role_permissions = db.relationship( 'RolePermission', backref='role', primaryjoin='foreign(RolePermission.role_id)==Role.role_id') def __str__(self): return self.role_name
class OperationLogMixin(CreationMixin): log_id = db.Column(db.Integer, autoincrement=True, primary_key=True, comment='日志流水号') role_and_situations = [] @declared_attr def user_name(cls): return db.Column(db.String(20), comment='用户名称') @declared_attr def operation(cls): return db.Column(db.String(10), nullable=False, default=constants.Operation.create.value, comment='操作') @declared_attr def object_type(cls): return db.Column(db.String(20), comment='操作对象类型') @declared_attr def object_id(cls): return db.Column(db.String(20), comment='操作对象id') @declared_attr def info(cls): return db.Column(db.String(50), comment='信息') @declared_attr def user_ip(cls): return db.Column(db.String(20), comment='用户ip') def __str__(self): s = f'{self.user_name} {self.operation} {self.object_type}({self.object_id})' if self.info: s += f':{self.info}' return s
class RolePermission(BaseModel, CreationMixin, UpdationMixin): __tablename__ = "dat_role_permission" __table_args__ = ({'comment': '角色权限配置表'}) role_permission_id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='角色权限配置id') role_id = db.Column(db.Integer, nullable=False, comment='角色id') resource_permission_id = db.Column(db.Integer, nullable=False, comment='权限id') role_permission_state = db.Column(db.Boolean, nullable=False, default=True, comment='是否允许') def __str__(self): return f'< Role {self.role} - Resource Permission {self.resource_permission} - {self.role_permission_state}>'
class ResourcePermission(BaseModel, CreationMixin, UpdationMixin): __tablename__ = "dat_resource_permission" __table_args__ = ({'comment': '资源权限配置表'}) resource_permission_id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='资源权限配置id') resource_id = db.Column(db.Integer, nullable=False, comment='资源id') permission_id = db.Column(db.Integer, nullable=False, comment='权限id') role_permissions = db.relationship( 'RolePermission', backref='resource_permission', primaryjoin= 'foreign(RolePermission.resource_permission_id)==ResourcePermission.resource_permission_id' ) def __str__(self): return f'< Role {self.resource} - Permission {self.permission} >'
class Permission(BaseModel, CreationMixin, UpdationMixin): __tablename__ = "sys_permission" __table_args__ = ({'comment': "权限表"}) permission_id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='权限id') permission_name = db.Column(db.String(20), nullable=False, unique=True, comment='权限名称') permission_description = db.Column(db.String(50), comment='权限描述') resource_permissions = db.relationship( 'ResourcePermission', backref='permission', primaryjoin= 'foreign(ResourcePermission.permission_id)==Permission.permission_id') def __str__(self): return self.permission_name
class ResourceModel(BaseModel, CreationMixin, UpdationMixin): __tablename__ = "sys_resource" __table_args__ = ({'comment': "资源表"}) resource_id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='资源id') resource_name = db.Column(db.String(30), nullable=False, unique=True, comment='资源名称') resource_description = db.Column(db.String(50), comment='资源描述') resource_permissions = db.relationship( 'ResourcePermission', backref='resource', primaryjoin= 'foreign(ResourcePermission.resource_id)==ResourceModel.resource_id') def __str__(self): return self.resource_name
def user_ip(cls): return db.Column(db.String(20), comment='用户ip')
def user_name(cls): return db.Column(db.String(20), comment='用户名称')
def updated_by(cls): return db.Column(db.Integer, index=True, comment='更新人')
def operation(cls): return db.Column(db.String(10), nullable=False, default=constants.Operation.create.value, comment='操作')
def created_by(cls): return db.Column(db.Integer, index=True, comment='创建人')
class UpdationMixin: updated_at = db.Column(db.DateTime(timezone=True), onupdate=func.now(), index=True, comment='更新日期') @declared_attr def updated_by(cls): return db.Column(db.Integer, index=True, comment='更新人')
class CreationMixin: created_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), index=True, comment='创建日期') @declared_attr def created_by(cls): return db.Column(db.Integer, index=True, comment='创建人')
class User(BaseModel, CreationMixin, UpdationMixin, UserMixin): __tablename__ = "sys_user" __table_args__ = {'comment': '用户表'} user_id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="用户id") user_name = db.Column(db.String(20), nullable=False, comment="用户名") password = db.Column(db.String(100), nullable=False, comment="用户密码(加密)") email = db.Column(db.String(50), unique=True, nullable=False, comment="邮箱地址") telephone = db.Column(db.String(20), unique=True, nullable=False, comment="电话号码") address = db.Column(db.String(50), nullable=False, comment="联系地址") contact_person = db.Column(db.String(20), nullable=False, comment="联系人") ip = db.Column(db.String(20), nullable=False, comment="注册时的ip") user_state = db.Column(db.String(20), nullable=False, default=constants.UserState.active.value, comment="用户状态") api_key = db.Column(db.String(32), nullable=False, index=True, comment="接口id") secret_key = db.Column(db.String(256), nullable=False, comment="接口密钥(加密)") api_state = db.Column(db.String(10), nullable=False, default=constants.ResourceState.active.value, comment="接口状态") role_id = db.Column(db.Integer, nullable=False, comment="用户角色") create_user = db.relationship( "User", remote_side=[user_id], primaryjoin='foreign(User.created_by)==User.user_id', post_update=True) update_user = db.relationship( "User", remote_side=[user_id], primaryjoin='foreign(User.updated_by)==User.user_id', post_update=True) created_roles = db.relationship( 'Role', backref='create_user', primaryjoin='foreign(Role.created_by)==User.user_id') updated_roles = db.relationship( 'Role', backref='update_user', primaryjoin='foreign(Role.updated_by)==User.user_id') created_demos = db.relationship( 'Demo', backref='create_user', primaryjoin='foreign(Demo.created_by)==User.user_id') updated_demos = db.relationship( 'Demo', backref='update_user', primaryjoin='foreign(Demo.updated_by)==User.user_id') @property def pwd(self): raise AttributeError('password is not a readable attribute') @pwd.setter def pwd(self, value): self.password = generate_password_hash(value) def verify_pwd(self, password): role_and_situation = get_role_and_situation() tables_mapping = { role_and_situation: m for m in [ UserOperationLog, ApiOperationLog, AdminOperationLog, AdminApiOperationLog ] for role_and_situation in m.role_and_situations } try: op = constants.Operation.login.value role = role_and_situation.get('role') situation = role_and_situation.get('situation') log_model = tables_mapping[(role, situation)] log_model(user_name=self.user_name, operation=op, object_type=self.__table_args__.get("comment") or self.__tablename__, object_id=self.user_id, user_ip=request.remote_addr, created_by=self.user_id).save(user=self) except Exception as e: logger.error('', exc_info=e) return check_password_hash(self.password, password) def gen_token(self): return create_token({'user_id': self.user_id}) @property def sk(self): try: return rsa_decrypt(self.secret_key).decode() except ValueError as e: logger.warning(f'secret_key invalid, {e}: {self.pk_id}:') @sk.setter def sk(self, value): self.secret_key = rsa_encrypt(value) @property def api_active(self): return self.api_state == constants.ResourceState.active.value # For Admin def get_id(self): return self.user_id @property def is_active(self): return self.user_state == constants.ResourceState.active.value def has_role(self, role_name): return self.role.role_name == role_name def __str__(self): return self.user_name
def info(cls): return db.Column(db.String(50), comment='信息')
def object_id(cls): return db.Column(db.String(20), comment='操作对象id')
def object_type(cls): return db.Column(db.String(20), comment='操作对象类型')