From b0bdd78d3b45580634ca62e255a7d8016dad4b35 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 13 Aug 2026 17:52:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor(models):=20=E6=A8=A1=E5=9E=8B=E5=8F=8C?= =?UTF-8?q?=E8=BD=A8=E6=94=B6=E6=95=9B=E2=80=94=E2=80=94gerp=20=E4=BE=A7?= =?UTF-8?q?=2031=20=E5=A4=84=20ForeignKey=20=E6=94=B9=20UUIDField=EF=BC=8C?= =?UTF-8?q?=E4=B8=8E=20SDK=20=E6=98=A0=E5=B0=84=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - models.py: Tenant/Company/Dept/WorkOrder/Message/Menu 等 31 处 FK→UUIDField(db_column 不变) - 8 张有 CompanyUUID 的表补齐 TenantUUID(Dept/Workgroup/FileAsset/Menu/WorkgroupRole/UserRoleWorkgroup/UserRoleDepartment/CompanyApp) - 迁移 0028 扩展回填全 8 表;迁移 0029 AlterField 对齐字段类型(DB 列无实际变化) - 消除 select_related/_id 行为差异,SDK 与主库模型字段类型统一 --- .../migrations/0028_tenant_uuid_backfill.py | 64 +++++-- .../gerp/migrations/0029_fk_to_uuidfield.py | 172 ++++++++++++++++++ gvsds/apps/gerp/models.py | 67 +++---- 3 files changed, 256 insertions(+), 47 deletions(-) create mode 100644 gvsds/apps/gerp/migrations/0029_fk_to_uuidfield.py diff --git a/gvsds/apps/gerp/migrations/0028_tenant_uuid_backfill.py b/gvsds/apps/gerp/migrations/0028_tenant_uuid_backfill.py index f128b6f3..9d16ec7c 100644 --- a/gvsds/apps/gerp/migrations/0028_tenant_uuid_backfill.py +++ b/gvsds/apps/gerp/migrations/0028_tenant_uuid_backfill.py @@ -1,30 +1,32 @@ -"""Add TenantUUID to Dept / Workgroup (backfill from Company.TenantUUID) +"""Add TenantUUID to organization tables (backfill from Company.TenantUUID) -组织表补齐租户 UUID,消除跨租户查询的反射补偿: -- Dept.TenantUUID 回填 = CompanyUUID → Company.TenantUUID -- Workgroup.TenantUUID 回填 = CompanyUUID → Company.TenantUUID +组织/关联表补齐租户 UUID,消除跨租户查询的反射补偿与跨表过滤: +- Dept / Workgroup / FileAsset / Menu / WorkgroupRole / + UserRoleWorkgroup / UserRoleDepartment / CompanyApp + TenantUUID 回填 = CompanyUUID → Company.TenantUUID """ from django.db import migrations import gvsds.apps.core.models +#: 需要回填 TenantUUID 的表(均通过 CompanyUUID 关联 Company) +_BACKFILL_TABLES = ( + 'Department', 'Workgroup', 'FileAsset', 'Menu', + 'WorkgroupRole', 'UserRoleWorkgroup', 'UserRoleDepartment', 'CompanyApp', +) + def backfill_tenant_uuid(apps, schema_editor): - """从关联 Company 的 TenantUUID 回填 Dept/Workgroup.TenantUUID""" + """从关联 Company 的 TenantUUID 回填各表 TenantUUID""" Company = apps.get_model('gerp', 'Company') - Department = apps.get_model('gerp', 'Department') - Workgroup = apps.get_model('gerp', 'Workgroup') - company_tenant = dict( Company.objects.exclude(TenantUUID__isnull=True).values_list('CompanyUUID', 'TenantUUID') ) - for dept in Department.objects.select_related('CompanyUUID').only('DeptUUID', 'CompanyUUID').iterator(): - tenant = company_tenant.get(dept.CompanyUUID_id) - if tenant: - Department.objects.filter(DeptUUID=dept.DeptUUID).update(TenantUUID=tenant) - for wg in Workgroup.objects.select_related('CompanyUUID').only('WorkgroupUUID', 'CompanyUUID').iterator(): - tenant = company_tenant.get(wg.CompanyUUID_id) - if tenant: - Workgroup.objects.filter(WorkgroupUUID=wg.WorkgroupUUID).update(TenantUUID=tenant) + for name in _BACKFILL_TABLES: + model = apps.get_model('gerp', name) + for obj in model.objects.exclude(CompanyUUID__isnull=True).only('pk', 'CompanyUUID').iterator(): + tenant = company_tenant.get(obj.CompanyUUID_id) + if tenant: + model.objects.filter(pk=obj.pk).update(TenantUUID=tenant) class Migration(migrations.Migration): @@ -44,5 +46,35 @@ class Migration(migrations.Migration): name='TenantUUID', field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), ), + migrations.AddField( + model_name='fileasset', + name='TenantUUID', + field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), + ), + migrations.AddField( + model_name='menu', + name='TenantUUID', + field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), + ), + migrations.AddField( + model_name='workgrouprole', + name='TenantUUID', + field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), + ), + migrations.AddField( + model_name='userroleworkgroup', + name='TenantUUID', + field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), + ), + migrations.AddField( + model_name='userroledepartment', + name='TenantUUID', + field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), + ), + migrations.AddField( + model_name='companyapp', + name='TenantUUID', + field=gvsds.apps.core.models.UUIDField(blank=True, null=True, verbose_name='租户UUID'), + ), migrations.RunPython(backfill_tenant_uuid, migrations.RunPython.noop), ] diff --git a/gvsds/apps/gerp/migrations/0029_fk_to_uuidfield.py b/gvsds/apps/gerp/migrations/0029_fk_to_uuidfield.py new file mode 100644 index 00000000..ecd0bf16 --- /dev/null +++ b/gvsds/apps/gerp/migrations/0029_fk_to_uuidfield.py @@ -0,0 +1,172 @@ +"""Convert ForeignKey fields to UUIDField (align with gvsdsdk mapping models) + +模型双轨收敛:gerp 侧业务表字段与 gvsdsdk 映射模型对齐, +全部 ForeignKey 改为 UUIDField(db_column 不变,数据库列无实际变化)。 +""" +from django.db import migrations +import gvsds.apps.core.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gerp', '0028_tenant_uuid_backfill'), + ] + + operations = [ + migrations.AlterField( + model_name='companyinfo', + name='tenant_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='TenantUUID', verbose_name='租户UUID'), + ), + migrations.AlterField( + model_name='company', + name='tenant_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='TenantUUID', verbose_name='租户UUID'), + ), + migrations.AlterField( + model_name='company', + name='parent_company_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='ParentCompanyUUID', verbose_name='上级公司UUID'), + ), + migrations.AlterField( + model_name='department', + name='company_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='department', + name='parent_dept_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='ParentDeptUUID', verbose_name='上级部门UUID'), + ), + migrations.AlterField( + model_name='fileasset', + name='company_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='workorder', + name='creator_uuid', + field=gvsds.apps.core.models.UUIDField(db_index=True, db_column='CreatorUUID', verbose_name='创建人UUID'), + ), + migrations.AlterField( + model_name='workorder', + name='assignee_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='AssigneeUUID', verbose_name='指派人UUID'), + ), + migrations.AlterField( + model_name='message', + name='sender_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='SenderUUID', verbose_name='发送者UUID'), + ), + migrations.AlterField( + model_name='message', + name='receiver_uuid', + field=gvsds.apps.core.models.UUIDField(db_index=True, db_column='ReceiverUUID', verbose_name='接收者UUID'), + ), + migrations.AlterField( + model_name='menu', + name='company_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='menu', + name='parent_menu_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='ParentMenuUUID', verbose_name='上级菜单UUID'), + ), + migrations.AlterField( + model_name='workgroup', + name='CompanyUUID', + field=gvsds.apps.core.models.UUIDField(db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='workgrouprole', + name='WorkgroupUUID', + field=gvsds.apps.core.models.UUIDField(db_column='WorkgroupUUID', verbose_name='工作组UUID'), + ), + migrations.AlterField( + model_name='workgrouprole', + name='CompanyUUID', + field=gvsds.apps.core.models.UUIDField(db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='userroleworkgroup', + name='WorkgroupUUID', + field=gvsds.apps.core.models.UUIDField(db_column='WorkgroupUUID', verbose_name='工作组UUID'), + ), + migrations.AlterField( + model_name='userroleworkgroup', + name='CompanyUUID', + field=gvsds.apps.core.models.UUIDField(db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='userroledepartment', + name='DeptUUID', + field=gvsds.apps.core.models.UUIDField(db_column='DeptUUID', verbose_name='部门UUID'), + ), + migrations.AlterField( + model_name='userroledepartment', + name='CompanyUUID', + field=gvsds.apps.core.models.UUIDField(db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='backpack', + name='user_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='UserUUID', verbose_name='用户UUID'), + ), + migrations.AlterField( + model_name='backpack', + name='item_template_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='ItemTemplateUUID', verbose_name='物品模板UUID'), + ), + migrations.AlterField( + model_name='usersettings', + name='UserUUID', + field=gvsds.apps.core.models.UUIDField(unique=True, db_column='UserUUID', verbose_name='用户UUID'), + ), + migrations.AlterField( + model_name='auditlog', + name='tenant_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='TenantUUID', verbose_name='租户UUID'), + ), + migrations.AlterField( + model_name='auditlog', + name='company_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='auditlog', + name='user_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='UserUUID', verbose_name='操作人UUID'), + ), + migrations.AlterField( + model_name='abnormaluserlog', + name='tenant_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='TenantUUID', verbose_name='租户UUID'), + ), + migrations.AlterField( + model_name='abnormaluserlog', + name='company_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID'), + ), + migrations.AlterField( + model_name='abnormaluserlog', + name='user_uuid', + field=gvsds.apps.core.models.UUIDField(null=True, blank=True, db_column='UserUUID', verbose_name='用户UUID'), + ), + migrations.AlterField( + model_name='usermailbox', + name='user_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='UserUUID', db_index=True, verbose_name='用户UUID'), + ), + migrations.AlterField( + model_name='mailcontact', + name='user_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='UserUUID', db_index=True, verbose_name='归属用户UUID'), + ), + migrations.AlterField( + model_name='usergiteaaccount', + name='user_uuid', + field=gvsds.apps.core.models.UUIDField(db_column='UserUUID', db_index=True, verbose_name='用户UUID'), + ), + ] diff --git a/gvsds/apps/gerp/models.py b/gvsds/apps/gerp/models.py index 65b3105e..af3b4093 100644 --- a/gvsds/apps/gerp/models.py +++ b/gvsds/apps/gerp/models.py @@ -51,7 +51,7 @@ class CompanyInfo(QModel): """企业信息表——工商注册与企业详情""" CompanyInfoUUID = UUIDField(primary_key=True, verbose_name='企业信息UUID') - TenantUUID = models.ForeignKey('Tenant', on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='TenantUUID', verbose_name='租户UUID') + TenantUUID = UUIDField(null=True, blank=True, db_column='TenantUUID', verbose_name='租户UUID') EnterpriseName = models.CharField(max_length=256, verbose_name='企业全称') EnterpriseShortName = models.CharField(max_length=100, verbose_name='企业简称') CreditCode = models.CharField(max_length=64, unique=True, verbose_name='统一社会信用代码') @@ -140,8 +140,8 @@ class Company(QModel): """公司表——系统内组织机构""" CompanyUUID = UUIDField(primary_key=True, verbose_name='公司UUID') - TenantUUID = models.ForeignKey('Tenant', on_delete=models.CASCADE, related_name='+', db_column='TenantUUID', verbose_name='租户UUID') - ParentCompanyUUID = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='ParentCompanyUUID', verbose_name='上级公司UUID') + TenantUUID = UUIDField(db_column='TenantUUID', verbose_name='租户UUID') + ParentCompanyUUID = UUIDField(null=True, blank=True, db_column='ParentCompanyUUID', verbose_name='上级公司UUID') CompanyName = models.CharField(max_length=256, verbose_name='公司全称') CompanyShort = models.CharField(max_length=100, verbose_name='公司简称') CompanyIcon = models.CharField(max_length=512, null=True, blank=True, db_column='CompanyIcon', verbose_name='公司图标') @@ -164,8 +164,8 @@ class Department(QModel): DeptUUID = UUIDField(primary_key=True, verbose_name='部门UUID') TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.CASCADE, related_name='department_set', db_column='CompanyUUID', verbose_name='公司UUID') - ParentDeptUUID = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='children', db_column='ParentDeptUUID', verbose_name='上级部门UUID') + CompanyUUID = UUIDField(db_column='CompanyUUID', verbose_name='公司UUID') + ParentDeptUUID = UUIDField(null=True, blank=True, db_column='ParentDeptUUID', verbose_name='上级部门UUID') DeptName = models.CharField(max_length=256, verbose_name='部门名称') DeptSort = models.IntegerField(default=0, verbose_name='排序') DeptStatus = models.SmallIntegerField(default=1, verbose_name='部门状态') @@ -186,7 +186,8 @@ class FileAsset(QModel): """文件资产表——文件存储与引用管理""" AssetUUID = UUIDField(primary_key=True, verbose_name='资产UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.SET_NULL, null=True, blank=True, related_name='fileasset_set', db_column='CompanyUUID', verbose_name='公司UUID') + TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') + CompanyUUID = UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID') FileName = models.CharField(max_length=256, verbose_name='文件名') FileSHA1 = models.CharField(max_length=40, unique=True, verbose_name='文件SHA1') FileSize = models.IntegerField(verbose_name='文件大小') @@ -213,8 +214,8 @@ class WorkOrder(QModel): Category = models.CharField(max_length=64, default='other', verbose_name='分类') Priority = models.SmallIntegerField(default=0, verbose_name='优先级') Status = models.SmallIntegerField(default=0, verbose_name='状态') - CreatorUUID = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+', db_index=True, db_column='CreatorUUID', verbose_name='创建人UUID') - AssigneeUUID = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='AssigneeUUID', verbose_name='指派人UUID') + CreatorUUID = UUIDField(db_index=True, db_column='CreatorUUID', verbose_name='创建人UUID') + AssigneeUUID = UUIDField(null=True, blank=True, db_column='AssigneeUUID', verbose_name='指派人UUID') Resolution = models.CharField(max_length=4096, default='', verbose_name='解决方案') CreateTime = models.DateTimeField(default=datetime.datetime.utcnow, verbose_name='创建时间') UpdateTime = models.DateTimeField(null=True, blank=True, verbose_name='更新时间') @@ -232,8 +233,8 @@ class Message(QModel): """消息表——系统通知与站内信""" MessageUUID = UUIDField(primary_key=True, verbose_name='消息UUID') - SenderUUID = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='SenderUUID', verbose_name='发送者UUID') - ReceiverUUID = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+', db_index=True, db_column='ReceiverUUID', verbose_name='接收者UUID') + SenderUUID = UUIDField(null=True, blank=True, db_column='SenderUUID', verbose_name='发送者UUID') + ReceiverUUID = UUIDField(db_index=True, db_column='ReceiverUUID', verbose_name='接收者UUID') Title = models.CharField(max_length=256, verbose_name='标题') Content = models.TextField(default='', verbose_name='内容') MsgType = models.SmallIntegerField(default=0, verbose_name='消息类型') @@ -254,8 +255,8 @@ class Menu(QModel): """菜单表——系统导航与功能入口""" MenuUUID = UUIDField(primary_key=True, verbose_name='菜单UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.SET_NULL, null=True, blank=True, related_name='menu_set', db_column='CompanyUUID', verbose_name='公司UUID') - ParentMenuUUID = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='children', db_column='ParentMenuUUID', verbose_name='上级菜单UUID') + CompanyUUID = UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID') + ParentMenuUUID = UUIDField(null=True, blank=True, db_column='ParentMenuUUID', verbose_name='上级菜单UUID') MenuName = models.CharField(max_length=128, verbose_name='菜单名称') MenuTitle = models.CharField(max_length=128, verbose_name='菜单标题') MenuIcon = models.CharField(max_length=128, default='', verbose_name='菜单图标') @@ -308,7 +309,7 @@ class Workgroup(QModel): WorkgroupUUID = UUIDField(primary_key=True, verbose_name='工作组UUID') TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.CASCADE, related_name='+', db_column='CompanyUUID', verbose_name='公司UUID') + CompanyUUID = UUIDField(db_column='CompanyUUID', verbose_name='公司UUID') WorkgroupName = models.CharField(max_length=256, verbose_name='工作组名称') WorkgroupEnglishName = models.CharField(max_length=256, verbose_name='工作组英文名') WorkgroupIntroduction = models.CharField(max_length=1024, verbose_name='工作组介绍') @@ -331,9 +332,10 @@ class WorkgroupRole(QModel): """ WorkgroupRoleUUID = UUIDField(primary_key=True, verbose_name='关联UUID') - WorkgroupUUID = models.ForeignKey('Workgroup', on_delete=models.CASCADE, related_name='+', db_column='WorkgroupUUID', verbose_name='工作组UUID') + WorkgroupUUID = UUIDField(db_column='WorkgroupUUID', verbose_name='工作组UUID') RoleUUID = UUIDField(verbose_name='角色UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.CASCADE, related_name='+', db_column='CompanyUUID', verbose_name='公司UUID') + TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') + CompanyUUID = UUIDField(db_column='CompanyUUID', verbose_name='公司UUID') RoleType = models.SmallIntegerField(default=0, verbose_name='角色类型') CreateTime = models.DateTimeField(default=datetime.datetime.utcnow, verbose_name='创建时间') @@ -356,8 +358,9 @@ class UserRoleWorkgroup(QModel): UserRoleWorkgroupUUID = UUIDField(primary_key=True, verbose_name='关联UUID') UserRoleUUID = UUIDField(verbose_name='用户-角色关联UUID') - WorkgroupUUID = models.ForeignKey('Workgroup', on_delete=models.CASCADE, related_name='+', db_column='WorkgroupUUID', verbose_name='工作组UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.CASCADE, related_name='+', db_column='CompanyUUID', verbose_name='公司UUID') + WorkgroupUUID = UUIDField(db_column='WorkgroupUUID', verbose_name='工作组UUID') + TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') + CompanyUUID = UUIDField(db_column='CompanyUUID', verbose_name='公司UUID') RoleType = models.SmallIntegerField(default=0, verbose_name='角色类型') CreateTime = models.DateTimeField(default=datetime.datetime.utcnow, verbose_name='创建时间') @@ -381,8 +384,9 @@ class UserRoleDepartment(QModel): UserRoleDepartmentUUID = UUIDField(primary_key=True, verbose_name='关联UUID') UserRoleUUID = UUIDField(verbose_name='用户-角色关联UUID') - DeptUUID = models.ForeignKey('Department', on_delete=models.CASCADE, related_name='+', db_column='DeptUUID', verbose_name='部门UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.CASCADE, related_name='+', db_column='CompanyUUID', verbose_name='公司UUID') + DeptUUID = UUIDField(db_column='DeptUUID', verbose_name='部门UUID') + TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') + CompanyUUID = UUIDField(db_column='CompanyUUID', verbose_name='公司UUID') RoleType = models.SmallIntegerField(default=0, verbose_name='角色类型') CreateTime = models.DateTimeField(default=datetime.datetime.utcnow, verbose_name='创建时间') @@ -416,8 +420,8 @@ class Backpack(QModel): """背包表——用户物品栏""" BackpackItemUUID = UUIDField(primary_key=True, verbose_name='背包物品UUID') - UserUUID = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+', db_column='UserUUID', verbose_name='用户UUID') - ItemTemplateUUID = models.ForeignKey('ItemReference', on_delete=models.CASCADE, related_name='+', db_column='ItemTemplateUUID', verbose_name='物品模板UUID') + UserUUID = UUIDField(db_column='UserUUID', verbose_name='用户UUID') + ItemTemplateUUID = UUIDField(db_column='ItemTemplateUUID', verbose_name='物品模板UUID') _ItemName = models.CharField(max_length=128, null=True, blank=True, verbose_name='物品名称缓存') _ItemIcon = models.CharField(max_length=512, null=True, blank=True, verbose_name='物品图标缓存') _ItemIconColor = models.CharField(max_length=6, null=True, blank=True, verbose_name='图标颜色缓存') @@ -616,7 +620,7 @@ class PersonalPage(QModel): class UserSettings(QModel): """用户设置表——存储每位用户的个性化系统设置""" - UserUUID = models.ForeignKey(User, on_delete=models.CASCADE, unique=True, db_column='UserUUID', verbose_name='用户UUID') + UserUUID = UUIDField(unique=True, db_column='UserUUID', verbose_name='用户UUID') SettingsData = models.TextField(default='', verbose_name='设置数据') class Meta: @@ -635,9 +639,9 @@ class AuditLog(QModel): """ AuditLogUUID = UUIDField(primary_key=True, verbose_name='日志UUID') - TenantUUID = models.ForeignKey('Tenant', on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='TenantUUID', verbose_name='租户UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='CompanyUUID', verbose_name='公司UUID') - UserUUID = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='UserUUID', verbose_name='操作人UUID') + TenantUUID = UUIDField(null=True, blank=True, db_column='TenantUUID', verbose_name='租户UUID') + CompanyUUID = UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID') + UserUUID = UUIDField(null=True, blank=True, db_column='UserUUID', verbose_name='操作人UUID') TableName = models.CharField(max_length=64, db_index=True, verbose_name='表名') Action = models.CharField(max_length=16, verbose_name='操作类型') TargetUUID = UUIDField(null=True, blank=True, verbose_name='目标记录UUID') @@ -665,9 +669,9 @@ class AbnormalUserLog(QModel): """ LogUUID = UUIDField(primary_key=True, verbose_name='日志UUID') - TenantUUID = models.ForeignKey('Tenant', on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='TenantUUID', verbose_name='租户UUID') - CompanyUUID = models.ForeignKey('Company', on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='CompanyUUID', verbose_name='公司UUID') - UserUUID = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='+', db_column='UserUUID', verbose_name='用户UUID') + TenantUUID = UUIDField(null=True, blank=True, db_column='TenantUUID', verbose_name='租户UUID') + CompanyUUID = UUIDField(null=True, blank=True, db_column='CompanyUUID', verbose_name='公司UUID') + UserUUID = UUIDField(null=True, blank=True, db_column='UserUUID', verbose_name='用户UUID') AccountID = models.CharField(max_length=64, default='', db_index=True, verbose_name='账号标识') IPAddress = models.CharField(max_length=64, default='', db_index=True, verbose_name='客户端IP') RealIP = models.CharField(max_length=64, default='', verbose_name='真实IP') @@ -702,7 +706,7 @@ class UserMailbox(QModel): """ UserMailboxUUID = UUIDField(primary_key=True, verbose_name='邮箱记录UUID') - UserUUID = models.ForeignKey(User, on_delete=models.CASCADE, db_column='UserUUID', db_index=True, verbose_name='用户UUID') + UserUUID = UUIDField(db_column='UserUUID', db_index=True, verbose_name='用户UUID') MailboxName = models.CharField(max_length=256, unique=True, verbose_name='邮箱名称') PrincipalId = models.IntegerField(null=True, blank=True, verbose_name='Stalwart账户ID') QuotaMB = models.IntegerField(default=1024, verbose_name='配额(MB)') @@ -728,7 +732,7 @@ class MailContact(QModel): """ MailContactUUID = UUIDField(primary_key=True, default=_NewUuidBytes, verbose_name='联系人UUID') - UserUUID = models.ForeignKey(User, on_delete=models.CASCADE, db_column='UserUUID', db_index=True, verbose_name='归属用户UUID') + UserUUID = UUIDField(db_column='UserUUID', db_index=True, verbose_name='归属用户UUID') ContactName = models.CharField(max_length=128, default='', blank=True, verbose_name='联系人名称') ContactEmail = models.CharField(max_length=256, db_index=True, verbose_name='联系人邮箱') CreateTime = models.DateTimeField(default=datetime.datetime.utcnow, verbose_name='创建时间') @@ -756,7 +760,7 @@ class UserGiteaAccount(QModel): """ UserGiteaAccountUUID = UUIDField(primary_key=True, verbose_name='Gitea记录UUID') - UserUUID = models.ForeignKey(User, on_delete=models.CASCADE, db_column='UserUUID', db_index=True, verbose_name='用户UUID') + UserUUID = UUIDField(db_column='UserUUID', db_index=True, verbose_name='用户UUID') GiteaLogin = models.CharField(max_length=256, unique=True, verbose_name='Gitea用户名') GiteaUserId = models.IntegerField(null=True, blank=True, verbose_name='Gitea用户ID') Email = models.CharField(max_length=256, default='', blank=True, db_column='Email', verbose_name='工作邮箱') @@ -848,6 +852,7 @@ class CompanyApp(QModel): """ CompanyAppUUID = UUIDField(primary_key=True, verbose_name='公司安装记录UUID') + TenantUUID = UUIDField(null=True, blank=True, verbose_name='租户UUID') CompanyUUID = UUIDField(db_column='CompanyUUID', verbose_name='公司UUID') AppUUID = UUIDField(db_column='AppUUID', verbose_name='应用UUID') InstallStatus = models.SmallIntegerField(default=1, verbose_name='安装状态(1启用/0停用)')