refactor(form_service): 删除已下沉 SDK 的 entityPicker 两个方法

删除本地重复实现 _get_entity_picker_fields / _enrich_entity_labels(约 170 行),改由 FormServiceBase 继承:调用点更新为 _GetEntityPickerFields / _EnrichEntityLabels(get_table 的 entityPicker 分支),两处注释同步更名。

行为不变:仍按 ENTITY_PICKER_MAP/UUID_FIELD_ENTITY_MAP 识别字段,仍按 db_column 前缀回填 _label 与 extraFields。
This commit is contained in:
TermiNexus committed 2026-09-15 13:31:43 +08:00
1 parent 042b9ed989
commit 34a7e21c2b
1 file changed
+4 -177
+4 -177
View File
@@ -258,179 +258,6 @@ class FormService(FormServiceBase):
from gvsdsdk.auth.admin_service import IsSuperAdmin
return IsSuperAdmin(user=user, role_uuid=self.current_role_uuid)
def _get_entity_picker_fields(self, model):
"""获取模型中所有 entityPicker 类型的字段信息"""
result = []
for f in model._meta.get_fields():
if not hasattr(f, 'name'):
continue
# ForeignKey 字段
if f.__class__.__name__ == 'ForeignKey':
try:
related_model = getattr(f, 'related_model', None)
if related_model:
related_name = related_model.__name__
ep_config = self.ENTITY_PICKER_MAP.get(related_name)
if ep_config:
result.append({
'field_name': f.name,
'label_field': ep_config['labelField'],
'value_field': ep_config['valueField'],
'entity_name': related_name,
'extra_fields': ep_config.get('extraFields', []),
})
except Exception:
pass
# UUIDField 字段(非 ForeignKey)
elif f.__class__.__name__ == 'UUIDField' and not getattr(f, 'primary_key', False):
entity_name = self.UUID_FIELD_ENTITY_MAP.get(f.name)
if entity_name:
ep_config = self.ENTITY_PICKER_MAP.get(entity_name)
if ep_config:
result.append({
'field_name': f.name,
'label_field': ep_config['labelField'],
'value_field': ep_config['valueField'],
'entity_name': entity_name,
'extra_fields': ep_config.get('extraFields', []),
})
return result
def _enrich_entity_labels(self, page_qs, ep_fields, records):
"""为 records 中的 entityPicker 字段添加 _label 后缀字段,以及 extraFields
支持两种字段类型:
- ForeignKey:getattr(obj, field_name) 返回关联模型实例,直接取 label_field
- UUIDField:getattr(obj, field_name) 返回 UUIDObj,需批量查询关联表获取名称
"""
try:
obj_list = list(page_qs)
except Exception:
return records
if not obj_list:
return records
# 预构建 UUIDField 类型的 UUID → label 映射(批量查询优化性能)
# key: (entity_name, label_field), value: {uuid_bytes: label}
uuid_label_cache = {}
uuid_extra_cache = {} # key: (entity_name, extra_field), value: {uuid_bytes: value}
for ep_info in ep_fields:
field_name = ep_info['field_name']
entity_name = ep_info['entity_name']
label_field = ep_info['label_field']
extra_fields = ep_info.get('extra_fields', [])
value_field = ep_info['value_field']
# 判断字段类型
field_obj = None
for f in obj_list[0]._meta.get_fields():
if hasattr(f, 'name') and f.name == field_name:
field_obj = f
break
# 仅对 UUIDField(非主键)类型批量查询;ForeignKey 通过 getattr 直接获取
if not (field_obj and field_obj.__class__.__name__ == 'UUIDField'
and not getattr(field_obj, 'primary_key', False)):
continue
# 收集所有 UUID 值(转为 bytes)
uuid_values = set()
for obj in obj_list:
val = getattr(obj, field_name, None)
if val is not None:
if hasattr(val, 'bytes'):
uuid_values.add(val.bytes)
elif isinstance(val, str):
try:
uuid_values.add(uuid.UUID(val).bytes)
except ValueError:
pass
if not uuid_values:
continue
related_model = self.TABLE_MAP.get(entity_name)
if not related_model:
continue
# 批量查询关联表
try:
related_qs = related_model.objects.filter(**{f'{value_field}__in': uuid_values})
for r in related_qs:
pk_val = getattr(r, value_field, None)
pk_bytes = pk_val.bytes if hasattr(pk_val, 'bytes') else pk_val
if pk_bytes is None:
continue
label = getattr(r, label_field, None)
if label is not None:
uuid_label_cache.setdefault((entity_name, label_field), {})[pk_bytes] = label
for ef in extra_fields:
ef_val = getattr(r, ef, None)
if ef_val is not None:
uuid_extra_cache.setdefault((entity_name, ef), {})[pk_bytes] = ef_val
except Exception:
pass
for i, obj in enumerate(obj_list):
if i >= len(records):
break
for ep_info in ep_fields:
field_name = ep_info['field_name']
label_field = ep_info['label_field']
extra_fields = ep_info.get('extra_fields', [])
entity_name = ep_info['entity_name']
# 判断字段类型
field_obj = None
for f in obj._meta.get_fields():
if hasattr(f, 'name') and f.name == field_name:
field_obj = f
break
try:
# 获取 db_column 作为 key 前缀
db_col = None
for f in obj._meta.get_fields():
if hasattr(f, 'name') and f.name == field_name and hasattr(f, 'db_column'):
db_col = f.db_column or f.name
break
key_prefix = db_col or field_name
is_uuid_field = (field_obj
and field_obj.__class__.__name__ == 'UUIDField'
and not getattr(field_obj, 'primary_key', False))
if is_uuid_field:
# UUIDField 类型:从缓存查找
val = getattr(obj, field_name, None)
if val is None:
continue
val_bytes = val.bytes if hasattr(val, 'bytes') else val
if val_bytes is None:
continue
label = uuid_label_cache.get((entity_name, label_field), {}).get(val_bytes)
if label is not None:
records[i][key_prefix + '_label'] = str(label)
for ef in extra_fields:
ef_val = uuid_extra_cache.get((entity_name, ef), {}).get(val_bytes)
if ef_val is not None:
records[i][key_prefix + '_' + ef] = ef_val
else:
# ForeignKey 类型:直接获取关联实例
related_obj = getattr(obj, field_name, None)
if related_obj is not None:
label = getattr(related_obj, label_field, None)
if label is not None:
records[i][key_prefix + '_label'] = str(label)
for ef in extra_fields:
ef_val = getattr(related_obj, ef, None)
if ef_val is not None:
records[i][key_prefix + '_' + ef] = ef_val
except Exception:
pass
return records
def get_tables(self):
tables = []
for name, model in self.TABLE_MAP.items():
@@ -776,7 +603,7 @@ class FormService(FormServiceBase):
# 编辑表单允许修改覆盖名(仅定制显示名,不破坏角色语义)
col['editable'] = True
col['hideInCreateForm'] = True
# UserRole 列表可读性:UserUUID/RoleUUID 值已由 _enrich_entity_labels 回显为
# UserRole 列表可读性:UserUUID/RoleUUID 值已由 _EnrichEntityLabels 回显为
# 用户名/角色名,列标题直接改"用户名"/"角色名"(避免误导为裸 UUID);
# CompanyUUID 为隔离冗余列,角色成员列表均按公司隔离展示,列表隐藏
if table_name == 'UserRole' and pascal_name == 'UserUUID':
@@ -855,7 +682,7 @@ class FormService(FormServiceBase):
col['entityPicker'] = {**col['entityPicker'], 'dependCompany': True}
# UserRoleDepartment 列表可读性:UserRoleUUID 关联列列表隐藏(表单仍隐藏),
# 用户/角色由下方虚拟列(UserUUID/RoleUUID)分开展示(值经 get_table 反查 UserRole 注入);
# PositionUUID 列标题改"职务"(值为职务名,由 _enrich_entity_labels 回显)
# PositionUUID 列标题改"职务"(值为职务名,由 _EnrichEntityLabels 回显)
if table_name == 'UserRoleDepartment' and pascal_name == 'UserRoleUUID':
col['visible'] = False
if table_name == 'UserRoleDepartment' and pascal_name == 'PositionUUID':
@@ -1345,7 +1172,7 @@ class FormService(FormServiceBase):
start = (page - 1) * page_size
# 识别 entityPicker 字段,使用 select_related 预加载关联实体
# 注意:select_related 只能用于 ForeignKey,UUIDField 类型的 entityPicker 不能预加载
ep_fields = self._get_entity_picker_fields(model)
ep_fields = self._GetEntityPickerFields(model)
if ep_fields:
excluded = {'RoleUUID', 'PermUUID', 'PositionTemplateUUID', 'PositionUUID'}
qs = self.ApplySelectRelated(qs, model, [
@@ -1358,7 +1185,7 @@ class FormService(FormServiceBase):
records = self.BuildRecords(model, obj_list)
# 为 entityPicker 字段附带关联实体的 label
if ep_fields:
records = self._enrich_entity_labels(obj_list, ep_fields, records)
records = self._EnrichEntityLabels(obj_list, ep_fields, records)
# UserRoleWorkgroup / UserRoleDepartment:透传关联 UserRole 的用户 UUID(前端跳转用户详情用),
# 并生成 UserRoleUUID 的展示标签(label=角色名 + UserName=用户名,前端拼为"角色名(用户名)")
if table_name in ('UserRoleWorkgroup', 'UserRoleDepartment'):