前后端全面升级

This commit is contained in:
pycook
2023-07-10 17:42:15 +08:00
parent c444fed436
commit 109d4f1a2e
629 changed files with 97789 additions and 23995 deletions

View File

@@ -1,4 +1,4 @@
# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
from .cmdb import *

View File

@@ -13,6 +13,8 @@ from api.extensions import db
from api.lib.database import CRUDModel
from api.lib.database import Model
from api.lib.database import SoftDeleteMixin
from api.lib.perm.acl.const import ACL_QUEUE
from api.lib.perm.acl.const import OperateType
class App(Model):
@@ -30,10 +32,13 @@ class UserQuery(BaseQuery):
def authenticate(self, login, password):
user = self.filter(db.or_(User.username == login,
User.email == login)).filter(User.deleted.is_(False)).first()
User.email == login)).filter(User.deleted.is_(False)).filter(User.block == 0).first()
if user:
current_app.logger.info(user)
authenticated = user.check_password(password)
if authenticated:
from api.tasks.acl import op_record
op_record.apply_async(args=(None, login, OperateType.LOGIN, ["ACL"]), queue=ACL_QUEUE)
else:
authenticated = False
@@ -56,9 +61,11 @@ class UserQuery(BaseQuery):
ldap_conn.protocol_version = 3
ldap_conn.set_option(ldap.OPT_REFERRALS, 0)
if '@' in username:
email = username
who = '{0}@{1}'.format(username.split('@')[0], current_app.config.get('LDAP_DOMAIN'))
else:
who = '{0}@{1}'.format(username, current_app.config.get('LDAP_DOMAIN'))
email = who
username = username.split('@')[0]
user = self.get_by_username(username)
@@ -71,7 +78,10 @@ class UserQuery(BaseQuery):
if not user:
from api.lib.perm.acl.user import UserCRUD
user = UserCRUD.add(username=username, email=who)
user = UserCRUD.add(username=username, email=email)
from api.tasks.acl import op_record
op_record.apply_async(args=(None, username, OperateType.LOGIN, ["ACL"]), queue=ACL_QUEUE)
return user, True
except ldap.INVALID_CREDENTIALS:
@@ -80,28 +90,33 @@ class UserQuery(BaseQuery):
def search(self, key):
query = self.filter(db.or_(User.email == key,
User.nickname.ilike('%' + key + '%'),
User.username.ilike('%' + key + '%'))).filter(User.deleted.is_(False))
User.username.ilike('%' + key + '%')))
return query
def get_by_username(self, username):
user = self.filter(User.username == username).filter(User.deleted.is_(False)).first()
user = self.filter(User.username == username).first()
return user
def get_by_nickname(self, nickname):
user = self.filter(User.nickname == nickname).filter(User.deleted.is_(False)).first()
user = self.filter(User.nickname == nickname).first()
return user
def get_by_wxid(self, wx_id):
user = self.filter(User.wx_id == wx_id).first()
return user
def get(self, uid):
user = self.filter(User.uid == uid).filter(User.deleted.is_(False)).first()
user = self.filter(User.uid == uid).first()
return copy.deepcopy(user)
class User(CRUDModel, SoftDeleteMixin):
__tablename__ = 'users'
# __bind_key__ = "user"
__bind_key__ = "user"
query_class = UserQuery
uid = db.Column(db.Integer, primary_key=True, autoincrement=True)
@@ -119,7 +134,9 @@ class User(CRUDModel, SoftDeleteMixin):
block = db.Column(db.Boolean, default=False)
has_logined = db.Column(db.Boolean, default=False)
wx_id = db.Column(db.String(32))
employee_id = db.Column(db.String(16), index=True)
avatar = db.Column(db.String(128))
# apps = db.Column(db.JSON)
def __str__(self):
return self.username
@@ -145,16 +162,65 @@ class User(CRUDModel, SoftDeleteMixin):
def check_password(self, password):
if self.password is None:
return False
return self.password == password
return self.password == password or self.password == hashlib.md5(password.encode('utf-8')).hexdigest()
class RoleQuery(BaseQuery):
def _join(self, *args, **kwargs):
super(RoleQuery, self)._join(*args, **kwargs)
def authenticate(self, login, password):
role = self.filter(Role.name == login).first()
if role:
authenticated = role.check_password(password)
if authenticated:
from api.tasks.acl import op_record
op_record.apply_async(args=(None, login, OperateType.LOGIN, ["ACL"]), queue=ACL_QUEUE)
else:
authenticated = False
return role, authenticated
def authenticate_with_key(self, key, secret, args, path):
role = self.filter(Role.key == key).filter(Role.deleted.is_(False)).first()
if not role:
return None, False
if role and hashlib.sha1('{0}{1}{2}'.format(
path, role.secret, "".join(args)).encode("utf-8")).hexdigest() == secret:
authenticated = True
else:
authenticated = False
return role, authenticated
class Role(Model):
__tablename__ = "acl_roles"
query_class = RoleQuery
name = db.Column(db.Text, nullable=False)
name = db.Column(db.String(64), index=True, nullable=False)
is_app_admin = db.Column(db.Boolean, default=False)
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
uid = db.Column(db.Integer, db.ForeignKey("users.uid"))
uid = db.Column(db.Integer)
_password = db.Column("password", db.String(80))
key = db.Column(db.String(32))
secret = db.Column(db.String(32))
def _get_password(self):
return self._password
def _set_password(self, password):
if password:
self._password = hashlib.md5(password.encode('utf-8')).hexdigest()
password = db.synonym("_password", descriptor=property(_get_password, _set_password))
def check_password(self, password):
if self.password is None:
return False
return self.password == password or self.password == hashlib.md5(password.encode('utf-8')).hexdigest()
class RoleRelation(Model):
@@ -162,6 +228,7 @@ class RoleRelation(Model):
parent_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
child_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
class ResourceType(Model):
@@ -177,18 +244,24 @@ class ResourceGroup(Model):
name = db.Column(db.String(64), index=True, nullable=False)
resource_type_id = db.Column(db.Integer, db.ForeignKey("acl_resource_types.id"))
uid = db.Column(db.Integer, index=True)
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
resource_type = db.relationship("ResourceType", backref='acl_resource_groups.resource_type_id')
class Resource(Model):
__tablename__ = "acl_resources"
name = db.Column(db.String(128), nullable=False)
resource_type_id = db.Column(db.Integer, db.ForeignKey("acl_resource_types.id"))
uid = db.Column(db.Integer, index=True)
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
resource_type = db.relationship("ResourceType", backref='acl_resources.resource_type_id')
class ResourceGroupItems(Model):
__tablename__ = "acl_resource_group_items"
@@ -196,6 +269,8 @@ class ResourceGroupItems(Model):
group_id = db.Column(db.Integer, db.ForeignKey('acl_resource_groups.id'), nullable=False)
resource_id = db.Column(db.Integer, db.ForeignKey('acl_resources.id'), nullable=False)
resource = db.relationship("Resource", backref='acl_resource_group_items.resource_id')
class Permission(Model):
__tablename__ = "acl_permissions"
@@ -213,5 +288,90 @@ class RolePermission(Model):
resource_id = db.Column(db.Integer, db.ForeignKey('acl_resources.id'))
group_id = db.Column(db.Integer, db.ForeignKey('acl_resource_groups.id'))
perm_id = db.Column(db.Integer, db.ForeignKey('acl_permissions.id'))
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
perm = db.relationship("Permission", backref='acl_role_permissions.perm_id')
class Trigger(Model):
__tablename__ = "acl_triggers"
name = db.Column(db.String(128))
wildcard = db.Column(db.Text)
uid = db.Column(db.Text) # TODO
resource_type_id = db.Column(db.Integer, db.ForeignKey('acl_resource_types.id'))
roles = db.Column(db.Text) # TODO
permissions = db.Column(db.Text) # TODO
enabled = db.Column(db.Boolean, default=True)
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
class OperationRecord(Model):
__tablename__ = "acl_operation_records"
app = db.Column(db.String(32), index=True)
rolename = db.Column(db.String(32), index=True)
operate = db.Column(db.Enum(*OperateType.all()), nullable=False)
obj = db.Column(db.JSON)
class AuditRoleLog(Model):
__tablename__ = "acl_audit_role_logs"
app_id = db.Column(db.Integer, index=True)
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
operate_type = db.Column(db.String(32), comment='操作类型', index=True)
scope = db.Column(db.String(16), comment='范围')
link_id = db.Column(db.Integer, comment='资源id', index=True)
origin = db.Column(db.JSON, default=dict(), comment='原始数据')
current = db.Column(db.JSON, default=dict(), comment='当前数据')
extra = db.Column(db.JSON, default=dict(), comment='其他内容')
source = db.Column(db.String(16), default='', comment='来源')
class AuditResourceLog(Model):
__tablename__ = "acl_audit_resource_logs"
app_id = db.Column(db.Integer, index=True)
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
operate_type = db.Column(db.String(16), comment='操作类型', index=True)
scope = db.Column(db.String(16), comment='范围')
link_id = db.Column(db.Integer, comment='资源名', index=True)
origin = db.Column(db.JSON, default=dict(), comment='原始数据')
current = db.Column(db.JSON, default=dict(), comment='当前数据')
extra = db.Column(db.JSON, default=dict(), comment='权限名')
source = db.Column(db.String(16), default='', comment='来源')
class AuditPermissionLog(Model):
__tablename__ = "acl_audit_permission_logs"
app_id = db.Column(db.Integer, index=True)
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
operate_type = db.Column(db.String(16), comment='操作类型', index=True)
rid = db.Column(db.Integer, comment='角色id', index=True)
resource_type_id = db.Column(db.Integer, comment='资源类型id', index=True)
resource_ids = db.Column(db.JSON, default=[], comment='资源')
group_ids = db.Column(db.JSON, default=[], comment='资源组')
permission_ids = db.Column(db.JSON, default=[], comment='权限')
source = db.Column(db.String(16), comment='来源')
class AuditTriggerLog(Model):
__tablename__ = "acl_audit_trigger_logs"
app_id = db.Column(db.Integer, index=True)
trigger_id = db.Column(db.Integer, comment='trigger', index=True)
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
operate_type = db.Column(db.String(16), comment='操作类型', index=True)
origin = db.Column(db.JSON, default=dict(), comment='原始数据')
current = db.Column(db.JSON, default=dict(), comment='当前数据')
extra = db.Column(db.JSON, default=dict(), comment='权限名')
source = db.Column(db.String(16), default='', comment='来源')

View File

@@ -3,11 +3,16 @@
import datetime
from sqlalchemy.dialects.mysql import DOUBLE
from api.extensions import db
from api.lib.cmdb.const import AutoDiscoveryType
from api.lib.cmdb.const import CIStatusEnum
from api.lib.cmdb.const import CITypeOperateType
from api.lib.cmdb.const import ConstraintEnum
from api.lib.cmdb.const import OperateType
from api.lib.cmdb.const import ValueTypeEnum
from api.lib.database import Model
from api.lib.database import Model, Model2
# template
@@ -22,6 +27,7 @@ class CITypeGroup(Model):
__tablename__ = "c_ci_type_groups"
name = db.Column(db.String(32), nullable=False)
order = db.Column(db.Integer, default=0)
class CITypeGroupItem(Model):
@@ -40,18 +46,22 @@ class CIType(Model):
unique_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"), nullable=False)
enabled = db.Column(db.Boolean, default=True, nullable=False)
is_attached = db.Column(db.Boolean, default=False, nullable=False)
icon_url = db.Column(db.String(256), default='', nullable=False)
icon = db.Column(db.Text)
order = db.Column(db.SmallInteger, default=0, nullable=False)
default_order_attr = db.Column(db.String(33))
unique_key = db.relationship("Attribute", backref="c_ci_types.unique_id")
uid = db.Column(db.Integer, index=True)
class CITypeRelation(Model):
__tablename__ = "c_ci_type_relations"
parent_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
child_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
parent_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False) # source
child_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False) # dst
relation_type_id = db.Column(db.Integer, db.ForeignKey("c_relation_types.id"), nullable=False)
constraint = db.Column(db.Enum(*ConstraintEnum.all()), default=ConstraintEnum.One2Many)
parent = db.relationship("CIType", primaryjoin="CIType.id==CITypeRelation.parent_id")
child = db.relationship("CIType", primaryjoin="CIType.id==CITypeRelation.child_id")
@@ -73,6 +83,18 @@ class Attribute(Model):
is_password = db.Column(db.Boolean, default=False)
is_sortable = db.Column(db.Boolean, default=False)
default = db.Column(db.JSON) # {"default": None}
is_computed = db.Column(db.Boolean, default=False)
compute_expr = db.Column(db.Text)
compute_script = db.Column(db.Text)
choice_web_hook = db.Column(db.JSON)
uid = db.Column(db.Integer, index=True)
option = db.Column(db.JSON)
class CITypeAttribute(Model):
__tablename__ = "c_ci_type_attributes"
@@ -102,6 +124,23 @@ class CITypeAttributeGroupItem(Model):
order = db.Column(db.SmallInteger, default=0)
class CITypeTrigger(Model):
# __tablename__ = "c_ci_type_triggers"
__tablename__ = "c_c_t_t"
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'), nullable=False)
attr_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"), nullable=False)
notify = db.Column(db.JSON) # {subject: x, body: x, wx_to: [], mail_to: [], before_days: 0, notify_at: 08:00}
class CITypeUniqueConstraint(Model):
# __tablename__ = "c_ci_type_unique_constraints"
__tablename__ = "c_c_t_u_c"
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'), nullable=False)
attr_ids = db.Column(db.JSON) # [attr_id, ]
# instance
class CI(Model):
@@ -110,6 +149,7 @@ class CI(Model):
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
status = db.Column(db.Enum(*CIStatusEnum.all(), name="status"))
heartbeat = db.Column(db.DateTime, default=lambda: datetime.datetime.now())
is_auto_discovery = db.Column('a', db.Boolean, default=False)
ci_type = db.relationship("CIType", backref="c_cis.type_id")
@@ -132,6 +172,7 @@ class IntegerChoice(Model):
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
value = db.Column(db.Integer, nullable=False)
option = db.Column(db.JSON)
attr = db.relationship("Attribute", backref="c_choice_integers.attr_id")
@@ -140,7 +181,8 @@ class FloatChoice(Model):
__tablename__ = 'c_choice_floats'
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
value = db.Column(db.Float, nullable=False)
value = db.Column(DOUBLE, nullable=False)
option = db.Column(db.JSON)
attr = db.relationship("Attribute", backref="c_choice_floats.attr_id")
@@ -150,6 +192,7 @@ class TextChoice(Model):
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
value = db.Column(db.Text, nullable=False)
option = db.Column(db.JSON)
attr = db.relationship("Attribute", backref="c_choice_texts.attr_id")
@@ -172,7 +215,7 @@ class CIIndexValueFloat(Model):
ci_id = db.Column(db.Integer, db.ForeignKey('c_cis.id'), nullable=False)
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
value = db.Column(db.Float, nullable=False)
value = db.Column(DOUBLE, nullable=False)
ci = db.relationship("CI", backref="c_value_index_floats.ci_id")
attr = db.relationship("Attribute", backref="c_value_index_floats.attr_id")
@@ -222,7 +265,7 @@ class CIValueFloat(Model):
ci_id = db.Column(db.Integer, db.ForeignKey('c_cis.id'), nullable=False)
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
value = db.Column(db.Float, nullable=False)
value = db.Column(DOUBLE, nullable=False)
ci = db.relationship("CI", backref="c_value_floats.ci_id")
attr = db.relationship("Attribute", backref="c_value_floats.attr_id")
@@ -262,7 +305,7 @@ class CIValueJson(Model):
# history
class OperationRecord(Model):
class OperationRecord(Model2):
__tablename__ = "c_records"
uid = db.Column(db.Integer, index=True, nullable=False)
@@ -270,6 +313,8 @@ class OperationRecord(Model):
ticket_id = db.Column(db.String(32), nullable=True)
reason = db.Column(db.Text)
type_id = db.Column(db.Integer, index=True)
class AttributeHistory(Model):
__tablename__ = "c_attribute_histories"
@@ -293,29 +338,151 @@ class CIRelationHistory(Model):
relation_id = db.Column(db.Integer, nullable=False)
class CITypeHistory(Model):
__tablename__ = "c_ci_type_histories"
operate_type = db.Column(db.Enum(*CITypeOperateType.all(), name="operate_type"))
type_id = db.Column(db.Integer, index=True, nullable=False)
attr_id = db.Column(db.Integer)
trigger_id = db.Column(db.Integer)
unique_constraint_id = db.Column(db.Integer)
uid = db.Column(db.Integer, index=True)
change = db.Column(db.JSON)
# preference
class PreferenceShowAttributes(Model):
__tablename__ = "c_preference_show_attributes"
# __tablename__ = "c_preference_show_attributes"
__tablename__ = "c_psa"
uid = db.Column(db.Integer, index=True, nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
attr_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"))
order = db.Column(db.SmallInteger, default=0)
is_fixed = db.Column(db.Boolean, default=False)
ci_type = db.relationship("CIType", backref="c_preference_show_attributes.type_id")
attr = db.relationship("Attribute", backref="c_preference_show_attributes.attr_id")
ci_type = db.relationship("CIType", backref="c_psa.type_id")
attr = db.relationship("Attribute", backref="c_psa.attr_id")
class PreferenceTreeView(Model):
__tablename__ = "c_preference_tree_views"
# __tablename__ = "c_preference_tree_views"
__tablename__ = "c_ptv"
uid = db.Column(db.Integer, index=True, nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
levels = db.Column(db.Text) # TODO: JSON
levels = db.Column(db.JSON)
class PreferenceRelationView(Model):
__tablename__ = "c_preference_relation_views"
# __tablename__ = "c_preference_relation_views"
__tablename__ = "c_prv"
uid = db.Column(db.Integer, index=True, nullable=False)
name = db.Column(db.String(64), index=True, nullable=False)
cr_ids = db.Column(db.TEXT) # [{parent_id: x, child_id: y}] TODO: JSON
cr_ids = db.Column(db.JSON) # [{parent_id: x, child_id: y}]
is_public = db.Column(db.Boolean, default=False)
class PreferenceSearchOption(Model):
__tablename__ = "c_pso"
name = db.Column(db.String(64))
prv_id = db.Column(db.Integer, db.ForeignKey("c_prv.id"))
ptv_id = db.Column(db.Integer, db.ForeignKey("c_ptv.id"))
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"))
uid = db.Column(db.Integer, index=True)
option = db.Column(db.JSON)
# custom
class CustomDashboard(Model):
__tablename__ = "c_c_d"
name = db.Column(db.String(64))
category = db.Column(db.SmallInteger) # 0: 总数统计, 1: 字段值统计, 2: 关系统计
enabled = db.Column(db.Boolean, default=False)
order = db.Column(db.Integer, default=0)
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'))
level = db.Column(db.Integer)
options = db.Column(db.JSON)
class SystemConfig(Model):
__tablename__ = "c_sc"
name = db.Column(db.String(64), index=True)
option = db.Column(db.JSON)
# auto discovery
class AutoDiscoveryRule(Model):
__tablename__ = "c_ad_rules"
name = db.Column(db.String(32))
type = db.Column(db.Enum(*AutoDiscoveryType.all()), index=True)
is_inner = db.Column(db.Boolean, default=False, index=True)
owner = db.Column(db.Integer, index=True)
option = db.Column(db.JSON) # layout
attributes = db.Column(db.JSON)
is_plugin = db.Column(db.Boolean, default=False)
plugin_script = db.Column(db.Text)
unique_key = db.Column(db.String(64))
class AutoDiscoveryCIType(Model):
__tablename__ = "c_ad_ci_types"
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
adr_id = db.Column(db.Integer, db.ForeignKey('c_ad_ci_types.id'))
attributes = db.Column(db.JSON) # {ad_key: cmdb_key}
relation = db.Column(db.JSON) # [{ad_key: {type_id: x, attr_id: x}}]
auto_accept = db.Column(db.Boolean, default=False)
agent_id = db.Column(db.String(8), index=True)
query_expr = db.Column(db.Text)
interval = db.Column(db.Integer) # seconds
cron = db.Column(db.String(128))
extra_option = db.Column(db.JSON)
uid = db.Column(db.Integer, index=True)
class AutoDiscoveryCI(Model):
__tablename__ = "c_ad_ci"
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
adt_id = db.Column(db.Integer, db.ForeignKey('c_ad_ci_types.id'))
unique_value = db.Column(db.String(128), index=True)
instance = db.Column(db.JSON)
ci_id = db.Column(db.Integer, index=True)
is_accept = db.Column(db.Boolean, default=False)
accept_by = db.Column(db.String(64), index=True)
accept_time = db.Column(db.DateTime)
class CIFilterPerms(Model):
__tablename__ = "c_ci_filter_perms"
name = db.Column(db.String(64), index=True)
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
ci_filter = db.Column(db.Text)
attr_filter = db.Column(db.Text)
rid = db.Column(db.Integer, index=True)

View File

@@ -0,0 +1,87 @@
from api.extensions import db
from api.lib.database import Model, TimestampMixin, SoftDeleteMixin, CRUDMixin
class ModelWithoutPK(db.Model, TimestampMixin, SoftDeleteMixin, CRUDMixin):
__table_args__ = {"extend_existing": True}
__abstract__ = True
class Department(ModelWithoutPK):
__tablename__ = 'common_department'
department_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
department_name = db.Column(db.VARCHAR(255), default='', comment='部门名称')
department_director_id = db.Column(
db.Integer, default=0, comment='部门负责人ID')
department_parent_id = db.Column(db.Integer, default=1, comment='上级部门ID')
sort_value = db.Column(db.Integer, default=0, comment='排序值')
acl_rid = db.Column(db.Integer, comment='ACL中rid', default=0)
class Employee(ModelWithoutPK):
__tablename__ = 'common_employee'
employee_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
email = db.Column(db.VARCHAR(255), default='', comment='邮箱')
username = db.Column(db.VARCHAR(255), default='', comment='用户名')
nickname = db.Column(db.VARCHAR(255), default='', comment='姓名')
sex = db.Column(db.VARCHAR(64), default='', comment='性别')
position_name = db.Column(db.VARCHAR(255), default='', comment='职位名称')
mobile = db.Column(db.VARCHAR(255), default='', comment='电话号码')
avatar = db.Column(db.VARCHAR(255), default='', comment='头像')
direct_supervisor_id = db.Column(db.Integer, default=0, comment='直接上级ID')
department_id = db.Column(db.Integer,
db.ForeignKey('common_department.department_id'),
comment='部门ID',
)
acl_uid = db.Column(db.Integer, comment='ACL中uid', default=0)
acl_rid = db.Column(db.Integer, comment='ACL中rid', default=0)
acl_virtual_rid = db.Column(db.Integer, comment='ACL中虚拟角色rid', default=0)
last_login = db.Column(db.TIMESTAMP, nullable=True, comment='上次登录时间')
block = db.Column(db.Integer, comment='锁定状态', default=0)
_department = db.relationship(
'Department', backref='common_employee.department_id',
lazy='joined'
)
class EmployeeInfo(Model):
"""
员工信息
"""
__tablename__ = 'common_employee_info'
info = db.Column(db.JSON, default={}, comment='员工信息')
employee_id = db.Column(db.Integer, db.ForeignKey(
'common_employee.employee_id'), comment='员工ID')
employee = db.relationship(
'Employee', backref='common_employee.employee_id', lazy='joined')
class CompanyInfo(Model):
__tablename__ = "common_company_info_json"
info = db.Column(db.JSON)
class InternalMessage(Model):
"""
内部消息
"""
__tablename__ = "common_internal_message"
title = db.Column(db.VARCHAR(255), nullable=True, comment='标题')
content = db.Column(db.TEXT, nullable=True, comment='内容')
path = db.Column(db.VARCHAR(255), nullable=True, comment='跳转路径')
is_read = db.Column(db.Boolean, default=False, comment='是否已读')
app_name = db.Column(db.VARCHAR(128), nullable=False, comment='应用名称')
category = db.Column(db.VARCHAR(128), nullable=False, comment='分类')
message_data = db.Column(db.JSON, nullable=True, comment='数据')
employee_id = db.Column(db.Integer, db.ForeignKey('common_employee.employee_id'), comment='ID')