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.

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()