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:
1 parent
042b9ed989
commit
34a7e21c2b
1 file changed
+4
-177
@@ -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'):
|
||||
|
||||
Reference in new issue
Block a user