You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iTi-System/iti_system/models/sys/sys_user_attribute.py

109 lines
3.3 KiB
Python

from iti.applications.extensions import db
from iti.applications.common.crud import BaseModelMixin
from iti.applications.common.utils import BaseSchema
from apiflask.fields import String, Integer
class SysUserAttribute(BaseModelMixin):
"""
用户扩展属性表 (Key-Value 列存储模式)
"""
__tablename__ = "sys_user_attribute"
user_id = db.Column(
db.String(36),
db.ForeignKey("sys_user.id", ondelete="CASCADE"),
nullable=False,
index=True,
comment="用户ID",
)
attr_group = db.Column(
db.String(64), nullable=False, index=True, comment="属性分组(如: erp, custom)"
)
attr_key = db.Column(db.String(128), nullable=False, comment="属性键")
attr_value = db.Column(db.Text, nullable=True, comment="属性值")
attr_type = db.Column(
db.String(32),
nullable=False,
default="string",
comment="值类型(string/int/float/bool/json/encrypted)",
)
description = db.Column(db.String(255), nullable=True, comment="属性描述")
sort = db.Column(db.Integer, nullable=False, default=0, comment="排序")
# 关系
user = db.relationship("User", back_populates="user_attributes")
# 联合唯一索引:一个用户的同一分组下不能有重复的键
__table_args__ = (
db.Index("idx_user_group_key", "user_id", "attr_group", "attr_key"),
db.UniqueConstraint(
"user_id", "attr_group", "attr_key", name="uk_user_group_key"
),
)
def get_typed_value(self):
"""
根据 attr_type 返回类型化的值
"""
if self.attr_value is None:
return None
if self.attr_type == "int":
try:
return int(self.attr_value)
except (ValueError, TypeError):
return None
elif self.attr_type == "float":
try:
return float(self.attr_value)
except (ValueError, TypeError):
return None
elif self.attr_type == "bool":
return self.attr_value.lower() in ("true", "1", "yes", "on")
elif self.attr_type == "json":
import json
try:
return json.loads(self.attr_value)
except (ValueError, TypeError):
return None
elif self.attr_type == "encrypted":
# 加密字段,返回时不解密(需要时在业务层处理)
return "******"
else: # string
return self.attr_value
def set_typed_value(self, value):
"""
根据 attr_type 设置类型化的值
"""
if value is None:
self.attr_value = None
return
if self.attr_type == "json":
import json
self.attr_value = json.dumps(value, ensure_ascii=False)
elif self.attr_type == "bool":
self.attr_value = "true" if value else "false"
else:
self.attr_value = str(value)
class SysUserAttributeSchema(BaseSchema):
"""
用户扩展属性 Schema
"""
id = String()
user_id = String(data_key="userId")
attr_group = String(data_key="attrGroup")
attr_key = String(data_key="attrKey")
attr_value = String(data_key="attrValue")
attr_type = String(data_key="attrType")
description = String()
sort = Integer()