class Resource(BaseModel): __tablename__ = 'resources' code = db.Column(db.String(50), unique=True) url = db.Column(db.String(50)) method = db.Column(db.String(10)) # get post put delete order = db.Column(db.Integer) level = db.Column(db.Integer) icon = db.Column(db.String(50)) enable = db.Column(db.SmallInteger, server_default='1') parentCode = db.Column(db.String(50), db.ForeignKey('resources.code')) tabs = db.Column(db.SmallInteger) children = db.relationship('Resource', cascade='all, delete-orphan') parent = db.relationship('Resource', remote_side=[code]) service = db.Column(db.String(50))
class Resource(BaseModel): __tablename__ = 'resources' code = db.Column(db.String(50), unique=True) # 资源唯一标识, 前端根据code的内容来翻译 url = db.Column(db.String(50)) # 资源url method = db.Column(db.String(10)) # 请求方法 get post put delete order = db.Column(db.Integer) # 显示顺序,只对菜单类型有效 level = db.Column(db.Integer) # 资源级别:一级、二级、三级 icon = db.Column(db.String(50)) # 一级菜单图标 enable = db.Column(db.SmallInteger, server_default='1') # 是否启用该资源 parentCode = db.Column(db.String(50), db.ForeignKey('resources.code')) # 上级资源Code tabs = db.Column(db.SmallInteger) # 是否包含tabs children = db.relationship('Resource', cascade='all, delete-orphan') # 子资源 parent = db.relationship('Resource', remote_side=[code]) service = db.Column(db.String(50)) # resource 所属服务
class Group(BaseModel): __tablename__ = 'groups' groupID = db.Column(db.String(6), default=random_group_uid, unique=True) groupName = db.Column(db.String(50)) description = db.Column(db.String(300)) userIntID = db.Column(db.Integer, db.ForeignKey('users.id')) devices = db.relationship('Device', secondary=GroupDevice, lazy='dynamic') # group devices
class Cert(BaseModel): __tablename__ = 'certs' certName = db.Column(db.String) enable = db.Column(db.SmallInteger, default=1) CN = db.Column(db.String(36)) key = db.Column(db.Text) # key file string cert = db.Column(db.Text) # cert file string devices = db.relationship('Device', secondary=CertDevice, lazy='dynamic') # cert devices userIntID = db.Column(db.Integer, db.ForeignKey('users.id'))
class Gateway(Device): __tablename__ = 'gateways' id = db.Column(db.Integer, db.ForeignKey('devices.id', onupdate="CASCADE", ondelete="CASCADE"), primary_key=True) devices = db.relationship('EndDevice', foreign_keys="EndDevice.gateway", lazy='dynamic') # 设备 __mapper_args__ = {'polymorphic_identity': 2}
class Device(BaseModel): __tablename__ = 'devices' deviceName = db.Column(db.String(50)) deviceType = db.Column(db.Integer) # 1:end_device 2:gateway deviceID = db.Column(db.String(50)) deviceUsername = db.Column(db.String(50)) token = db.Column(db.String(50), default=generate_uuid(size=36)) authType = db.Column(db.SmallInteger, server_default='1') # 1:token 2:cert lastConnection = db.Column(db.DateTime) blocked = db.Column(db.SmallInteger, server_default='0') # 0:false 1:true deviceStatus = db.Column(db.SmallInteger, server_default='0') # 0:offline 1:online 2:sleep location = db.Column(db.String(300)) longitude = db.Column(db.Float) latitude = db.Column(db.Float) softVersion = db.Column(db.String(50)) hardwareVersion = db.Column(db.String(50)) manufacturer = db.Column(db.String(50)) serialNumber = db.Column(db.String(100)) deviceConsoleIP = db.Column(db.String(50)) deviceConsoleUsername = db.Column(db.String(50)) deviceConsolePort = db.Column(db.Integer, server_default='22') carrier = db.Column(db.Integer, server_default='1') upLinkNetwork = db.Column(db.Integer) # 1:2G, 2:3G..... description = db.Column(db.String(300)) mac = db.Column(db.String(50)) metaData = db.Column(JSONB) # meta data groups = db.relationship('Group', secondary=GroupDevice, lazy='dynamic') # device groups certs = db.relationship('Cert', secondary=CertDevice, lazy='dynamic') # device certs productID = db.Column(db.String, db.ForeignKey('products.productID')) userIntID = db.Column(db.Integer, db.ForeignKey('users.id')) tenantID = db.Column( db.String, db.ForeignKey('tenants.tenantID', onupdate="CASCADE", ondelete="CASCADE")) __mapper_args__ = {'polymorphic_on': deviceType}
class Product(BaseModel): """ cloudProtocol: 1:MQTT,2:CoAp,3:LwM2M,4:LoRaWAN,5:HTTP,6:WebSocket """ __tablename__ = 'products' productID = db.Column(db.String(6), default=random_product_uid, unique=True) # 产品标识 productName = db.Column(db.String(50)) # 产品名称 description = db.Column(db.String(300)) # 产品描述 cloudProtocol = db.Column(db.SmallInteger, server_default='1') # 云端协议, 网关类型产品显示为上联协议 gatewayProtocol = db.Column(db.Integer) # 网关协议 productType = db.Column(db.SmallInteger, server_default='1') # 产品类型1:设备,2:网关 userIntID = db.Column(db.Integer, db.ForeignKey('users.id')) devices = db.relationship('Device', backref='products', lazy='dynamic')
class Application(BaseModel): __tablename__ = 'applications' appID = db.Column(db.String(6), default=random_app_uid, unique=True) appName = db.Column(db.String(50)) appToken = db.Column(db.String(100), default=generate_uuid) # 32-bit expiredAt = db.Column(db.DateTime) # app token expired time description = db.Column(db.String(300)) appStatus = db.Column(db.Integer) # 0:blocked,1:run userIntID = db.Column(db.Integer, db.ForeignKey('users.id')) roleIntID = db.Column(db.Integer, db.ForeignKey('roles.id')) # app role id groups = db.relationship('Group', secondary=ApplicationGroup, lazy='dynamic')
class DataStream(BaseModel): __tablename__ = 'data_streams' streamID = db.Column(db.String(50)) # data stream identifier streamName = db.Column(db.String(50)) streamType = db.Column(db.SmallInteger) # 1:deviceUp, 2:deviceDown topic = db.Column(db.String(500)) description = db.Column(db.String(300)) dataPoints = db.relationship('DataPoint', secondary=StreamPoint, backref=db.backref('dataStreams', lazy='dynamic')) tenantID = db.Column(db.String, db.ForeignKey('tenants.tenantID', onupdate="CASCADE", ondelete="CASCADE")) productID = db.Column(db.String, db.ForeignKey('products.productID')) userIntID = db.Column(db.Integer, db.ForeignKey('users.id', onupdate="CASCADE", ondelete="CASCADE"))
class Rule(BaseModel): __tablename__ = 'rules' ruleName = db.Column(db.String(50)) remark = db.Column(db.String(50)) enable = db.Column(db.SmallInteger, default=1) sql = db.Column(db.String) fromTopics = db.Column(JSONB) scopeData = db.Column(JSONB) ruleType = db.Column(db.SmallInteger) userIntID = db.Column(db.Integer, db.ForeignKey('users.id')) tenantID = db.Column( db.String, db.ForeignKey('tenants.tenantID', onupdate="CASCADE", ondelete="CASCADE")) actions = db.relationship('Action', secondary=RuleAction, backref=db.backref('rules', lazy='dynamic'))
class User(BaseModel): __tablename__ = 'users' username = db.Column(db.String(50)) # 用户名 nickname = db.Column(db.String(50)) # 昵称 email = db.Column(db.String(50), unique=True) # 邮箱 department = db.Column(db.String(50)) # 部门 phone = db.Column(db.String(50)) # 电话 enable = db.Column(db.SmallInteger, server_default='1') # 是否能登录 _password = db.Column('password', db.String(100)) # 密码 lastRequestTime = db.Column(db.DateTime) # 最后访问时间 loginTime = db.Column(db.DateTime) # 登录时间 expiresAt = db.Column(db.DateTime) # 到期时间 userAuthType = db.Column(db.Integer, server_default='1') # 用户验证类型(1 基于角色 2 基于角色和分组) groups = db.relationship('Group', secondary=UserGroup, lazy='dynamic') # user groups roleIntID = db.Column(db.Integer, db.ForeignKey('roles.id')) # 角色ID tenantID = db.Column(db.String, db.ForeignKey('tenants.tenantID')) # 租户ID外键 @property def password(self): return self._password @password.setter def password(self, raw): bcrypt_rounds = current_app.config.get('BCRYPT_ROUNDS') bcrypt_prefix = current_app.config.get('BCRYPT_PREFIX').encode() raw_password = self._str_to_bytes(raw) bcrypt_password = bcrypt.hashpw( raw_password, bcrypt.gensalt(rounds=bcrypt_rounds, prefix=bcrypt_prefix)) self._password = self._byte_to_str(bcrypt_password) def check_password(self, raw): if not self._password: return False password = self._str_to_bytes(raw) hashed_password = self._str_to_bytes(self._password) return bcrypt.checkpw(password, hashed_password) def generate_auth_token(self, remember=False): if remember: expires_in = current_app.config['TOKEN_LIFETIME_REMEMBER'] else: expires_in = current_app.config['TOKEN_LIFETIME'] s = JWT(current_app.config['SECRET_KEY'], expires_in=expires_in) token = s.dumps({ 'user_id': self.id, 'role_id': self.roleIntID, 'tenant_uid': self.tenantID }) return self._byte_to_str(token) @staticmethod def _str_to_bytes(raw_string): if isinstance(raw_string, str): bytes_object = raw_string.encode('utf-8') else: bytes_object = raw_string return bytes_object @staticmethod def _byte_to_str(row_byte): if isinstance(row_byte, bytes): row_str = row_byte.decode('utf-8') else: row_str = row_byte return row_str