feat(permission): add Chinese verbose_name/help_text to permission models (Phase 4.1 part 6/9)
This commit is contained in:
@@ -6,26 +6,95 @@ from core.models.base import TimeStampedModel
|
||||
|
||||
|
||||
class PermissionDef(TimeStampedModel):
|
||||
code = models.CharField(max_length=150, unique=True)
|
||||
module = models.CharField(max_length=50, choices=PermissionModule.choices)
|
||||
sub_module = models.CharField(max_length=50, blank=True, default="")
|
||||
group_name = models.CharField(max_length=100)
|
||||
name = models.CharField(max_length=200)
|
||||
description = models.TextField(blank=True, default="")
|
||||
value_type = models.CharField(max_length=20, choices=PermissionValueType.choices)
|
||||
scope_choices = models.JSONField(default=list, blank=True)
|
||||
integer_min = models.IntegerField(null=True, blank=True)
|
||||
integer_max = models.IntegerField(null=True, blank=True)
|
||||
default_value = models.JSONField(default=dict)
|
||||
code = models.CharField(
|
||||
max_length=150,
|
||||
unique=True,
|
||||
verbose_name="权限编码",
|
||||
help_text='规则:{module}.{sub_module}.{action}[.{qualifier}]',
|
||||
)
|
||||
module = models.CharField(
|
||||
max_length=50,
|
||||
choices=PermissionModule.choices,
|
||||
verbose_name="一级模块",
|
||||
help_text="home/property/new_house/client/transaction/data/marketing/hr/contract/trinet/system/mobile/smart_store/recharge",
|
||||
)
|
||||
sub_module = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="二级模块",
|
||||
help_text='如「二手&租赁」「商圈精耕」',
|
||||
)
|
||||
group_name = models.CharField(
|
||||
max_length=100,
|
||||
verbose_name="分组标题",
|
||||
help_text='如「私客基础权限」「联系人基础权限」',
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name="显示名称",
|
||||
)
|
||||
description = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="权限作用描述",
|
||||
)
|
||||
value_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=PermissionValueType.choices,
|
||||
verbose_name="权限值类型",
|
||||
help_text="BOOLEAN=开关型 / SCOPE=范围型 / INTEGER=数值型",
|
||||
)
|
||||
scope_choices = models.JSONField(
|
||||
default=list,
|
||||
blank=True,
|
||||
verbose_name="可选范围",
|
||||
help_text='仅 SCOPE 类型有效,可选枚举 code 列表,如 ["none","self","store","company"]',
|
||||
)
|
||||
integer_min = models.IntegerField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="最小值",
|
||||
help_text="仅 INTEGER 类型有效",
|
||||
)
|
||||
integer_max = models.IntegerField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="最大值",
|
||||
help_text="仅 INTEGER 类型有效;NULL=无上限(业务上 0 通常代表不限制)",
|
||||
)
|
||||
default_value = models.JSONField(
|
||||
default=dict,
|
||||
verbose_name="默认值",
|
||||
help_text='系统最小默认值,格式 {"v": <value>}',
|
||||
)
|
||||
max_allowed_categories = ArrayField(
|
||||
models.CharField(max_length=50),
|
||||
default=list,
|
||||
blank=True,
|
||||
verbose_name="可配置角色类别",
|
||||
help_text="允许配置此权限的角色类别列表,空数组=所有类别均可",
|
||||
)
|
||||
sort_order = models.PositiveIntegerField(
|
||||
default=0,
|
||||
verbose_name="排序顺序",
|
||||
help_text="分组内排序",
|
||||
)
|
||||
is_active = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name="是否启用",
|
||||
help_text="下线权限项置 FALSE,历史记录保留",
|
||||
)
|
||||
is_deprecated = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否废弃",
|
||||
help_text="不再推荐使用但保持兼容",
|
||||
)
|
||||
version = models.PositiveIntegerField(
|
||||
default=1,
|
||||
verbose_name="定义版本",
|
||||
help_text="变更时递增,用于缓存失效",
|
||||
)
|
||||
sort_order = models.PositiveIntegerField(default=0)
|
||||
is_active = models.BooleanField(default=True)
|
||||
is_deprecated = models.BooleanField(default=False)
|
||||
version = models.PositiveIntegerField(default=1)
|
||||
|
||||
class Meta:
|
||||
db_table = "permission_defs"
|
||||
|
||||
@@ -5,24 +5,48 @@ from core.models.base import SoftDeleteModel, TimeStampedModel
|
||||
|
||||
|
||||
class Role(SoftDeleteModel):
|
||||
name = models.CharField(max_length=100)
|
||||
category = models.CharField(max_length=30, choices=PermissionRoleCategory.choices)
|
||||
description = models.TextField(blank=True, default="")
|
||||
name = models.CharField(
|
||||
max_length=100,
|
||||
verbose_name="角色名称",
|
||||
)
|
||||
category = models.CharField(
|
||||
max_length=30,
|
||||
choices=PermissionRoleCategory.choices,
|
||||
verbose_name="角色类别",
|
||||
help_text="agent=置业顾问 / store_manager=店管 / director=总经 / operator=运营 / custom=自定义",
|
||||
)
|
||||
description = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="角色描述",
|
||||
)
|
||||
template_role = models.ForeignKey(
|
||||
"fonrey_permission.Role",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="derived_roles",
|
||||
verbose_name="权限模板来源",
|
||||
help_text='PRD「引用该角色配置」列',
|
||||
)
|
||||
is_system_builtin = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否系统内置",
|
||||
help_text='如「最大权限角色」,不可删除、不可改名',
|
||||
)
|
||||
is_active = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name="是否启用",
|
||||
help_text="FALSE=禁用(员工无法继承该角色权限)",
|
||||
)
|
||||
is_system_builtin = models.BooleanField(default=False)
|
||||
is_active = models.BooleanField(default=True)
|
||||
created_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="permission_roles_created",
|
||||
verbose_name="创建人",
|
||||
help_text="角色类别只能由创建者修改",
|
||||
)
|
||||
updated_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
@@ -30,6 +54,8 @@ class Role(SoftDeleteModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="permission_roles_updated",
|
||||
verbose_name="最后修改人",
|
||||
help_text="权限管理审计用",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -61,19 +87,27 @@ class RolePermission(TimeStampedModel):
|
||||
"fonrey_permission.Role",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="permissions",
|
||||
verbose_name="所属角色",
|
||||
help_text="稀疏存储:角色删除时级联清理权限值",
|
||||
)
|
||||
permission_def = models.ForeignKey(
|
||||
"fonrey_permission.PermissionDef",
|
||||
on_delete=models.PROTECT,
|
||||
related_name="role_assignments",
|
||||
verbose_name="权限定义",
|
||||
help_text="RESTRICT 防止删除仍被引用的权限项",
|
||||
)
|
||||
value = models.JSONField(
|
||||
verbose_name="权限值",
|
||||
help_text='统一格式 {"v": <value>}',
|
||||
)
|
||||
value = models.JSONField()
|
||||
updated_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="role_permissions_updated",
|
||||
verbose_name="最后修改人",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -14,23 +14,44 @@ class StaffRole(UUIDPrimaryKeyModel):
|
||||
"org.Staff",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="staff_roles",
|
||||
verbose_name="所属员工",
|
||||
help_text="员工删除时级联删除角色关联",
|
||||
)
|
||||
role = models.ForeignKey(
|
||||
"fonrey_permission.Role",
|
||||
on_delete=models.PROTECT,
|
||||
related_name="staff_links",
|
||||
verbose_name="角色",
|
||||
help_text="角色被员工引用时禁止删除",
|
||||
)
|
||||
is_primary = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否主角色",
|
||||
help_text="每个员工有且仅有一个主角色",
|
||||
)
|
||||
assigned_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="分配时间",
|
||||
)
|
||||
is_primary = models.BooleanField(default=False)
|
||||
assigned_at = models.DateTimeField(auto_now_add=True)
|
||||
assigned_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="staff_role_assignments_made",
|
||||
verbose_name="分配操作人",
|
||||
)
|
||||
valid_from = models.DateField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="生效日",
|
||||
help_text='预留未来「定时生效」功能',
|
||||
)
|
||||
valid_until = models.DateField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="失效日",
|
||||
)
|
||||
valid_from = models.DateField(null=True, blank=True)
|
||||
valid_until = models.DateField(null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "staff_roles"
|
||||
@@ -61,27 +82,44 @@ class StaffPermissionOverride(UUIDPrimaryKeyModel):
|
||||
"org.Staff",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="permission_overrides",
|
||||
verbose_name="所属员工",
|
||||
help_text="员工删除时级联删除覆盖记录",
|
||||
)
|
||||
permission_def = models.ForeignKey(
|
||||
"fonrey_permission.PermissionDef",
|
||||
on_delete=models.PROTECT,
|
||||
related_name="staff_overrides",
|
||||
verbose_name="被覆盖权限项",
|
||||
)
|
||||
value = models.JSONField(
|
||||
verbose_name="个人权限值",
|
||||
help_text='统一格式 {"v": <value>}',
|
||||
)
|
||||
value = models.JSONField()
|
||||
override_mode = models.CharField(
|
||||
max_length=10,
|
||||
choices=PermissionOverrideMode.choices,
|
||||
default=PermissionOverrideMode.REPLACE,
|
||||
verbose_name="覆盖模式",
|
||||
help_text="REPLACE=替换合并值 / RESTRICT=限制上限 / GRANT=仅扩展",
|
||||
)
|
||||
reason = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="备注",
|
||||
help_text="管理员备注,建议强制填写以便审计",
|
||||
)
|
||||
reason = models.TextField(blank=True, default="")
|
||||
modified_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="staff_overrides_modified",
|
||||
verbose_name="修改人",
|
||||
)
|
||||
modified_at = models.DateTimeField(
|
||||
auto_now=True,
|
||||
verbose_name="最近修改时间",
|
||||
)
|
||||
modified_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "staff_permission_overrides"
|
||||
@@ -103,10 +141,14 @@ class StaffDataScope(UUIDPrimaryKeyModel):
|
||||
"org.Staff",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="data_scopes",
|
||||
verbose_name="所属员工",
|
||||
help_text="员工删除时级联删除范围记录",
|
||||
)
|
||||
scope_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=PermissionDataScopeType.choices,
|
||||
verbose_name="范围类型",
|
||||
help_text="self=本人 / group=本组 / store=本门店 / area=本区域 / region=本大区 / company=全公司 / custom_unit=指定节点",
|
||||
)
|
||||
org_unit = models.ForeignKey(
|
||||
"org.OrgUnit",
|
||||
@@ -114,19 +156,40 @@ class StaffDataScope(UUIDPrimaryKeyModel):
|
||||
blank=True,
|
||||
on_delete=models.PROTECT,
|
||||
related_name="data_scope_grants",
|
||||
verbose_name="组织节点",
|
||||
help_text="scope_type=custom_unit 时必填,其他类型为 NULL",
|
||||
)
|
||||
is_readable = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name="可读",
|
||||
)
|
||||
is_writable = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="可写",
|
||||
help_text="默认只读",
|
||||
)
|
||||
is_readable = models.BooleanField(default=True)
|
||||
is_writable = models.BooleanField(default=False)
|
||||
granted_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="data_scopes_granted",
|
||||
verbose_name="授权操作人",
|
||||
)
|
||||
granted_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="授权时间",
|
||||
)
|
||||
expires_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="临时授权失效时间",
|
||||
)
|
||||
reason = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="授予原因",
|
||||
)
|
||||
granted_at = models.DateTimeField(auto_now_add=True)
|
||||
expires_at = models.DateTimeField(null=True, blank=True)
|
||||
reason = models.TextField(blank=True, default="")
|
||||
|
||||
class Meta:
|
||||
db_table = "staff_data_scopes"
|
||||
@@ -147,14 +210,20 @@ class PermissionChangeLog(UUIDPrimaryKeyModel):
|
||||
target_type = models.CharField(
|
||||
max_length=30,
|
||||
choices=PermissionChangeTargetType.choices,
|
||||
verbose_name="变更对象类型",
|
||||
help_text="role / role_permission / staff_role / staff_override / staff_scope",
|
||||
)
|
||||
target_id = models.UUIDField(
|
||||
verbose_name="变更对象 ID",
|
||||
)
|
||||
target_id = models.UUIDField()
|
||||
staff = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="permission_change_logs_affecting",
|
||||
verbose_name="被影响员工",
|
||||
help_text="target 是 staff_role/staff_override/staff_scope 时必填",
|
||||
)
|
||||
role = models.ForeignKey(
|
||||
"fonrey_permission.Role",
|
||||
@@ -162,20 +231,58 @@ class PermissionChangeLog(UUIDPrimaryKeyModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="change_logs",
|
||||
verbose_name="被影响角色",
|
||||
)
|
||||
permission_code = models.CharField(
|
||||
max_length=150,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="权限编码",
|
||||
help_text="用 code 而非 FK,避免 PermissionDef 删除后日志丢失",
|
||||
)
|
||||
action = models.CharField(
|
||||
max_length=20,
|
||||
choices=PermissionChangeAction.choices,
|
||||
verbose_name="操作动作",
|
||||
help_text="create / update / delete / assign / revoke",
|
||||
)
|
||||
old_value = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="变更前快照",
|
||||
)
|
||||
new_value = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="变更后快照",
|
||||
)
|
||||
permission_code = models.CharField(max_length=150, blank=True, default="")
|
||||
action = models.CharField(max_length=20, choices=PermissionChangeAction.choices)
|
||||
old_value = models.JSONField(null=True, blank=True)
|
||||
new_value = models.JSONField(null=True, blank=True)
|
||||
operator = models.ForeignKey(
|
||||
"org.Staff",
|
||||
on_delete=models.PROTECT,
|
||||
related_name="permission_changes_operated",
|
||||
verbose_name="操作人",
|
||||
)
|
||||
operator_ip = models.GenericIPAddressField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="操作来源 IP",
|
||||
)
|
||||
user_agent = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="操作终端 UA",
|
||||
)
|
||||
reason = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="操作原因",
|
||||
help_text="批量设置角色等场景强制填写",
|
||||
)
|
||||
operated_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="操作时间",
|
||||
help_text="append-only 流水,分区键",
|
||||
)
|
||||
operator_ip = models.GenericIPAddressField(null=True, blank=True)
|
||||
user_agent = models.TextField(blank=True, default="")
|
||||
reason = models.TextField(blank=True, default="")
|
||||
operated_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "permission_change_logs"
|
||||
|
||||
Reference in New Issue
Block a user