diff --git a/gvsds/apps/gerp/form_service.py b/gvsds/apps/gerp/form_service.py index 7d332f41..a6e02907 100644 --- a/gvsds/apps/gerp/form_service.py +++ b/gvsds/apps/gerp/form_service.py @@ -277,17 +277,14 @@ class FormService(FormServiceBase): return IsSuperAdmin(user=user, role_uuid=self.current_role_uuid) def get_tables(self): + # 表行数委托 SDK 的带缓存计数(TTL 300 秒),避免每次列表请求对每张表各发一次 COUNT tables = [] for name, model in self.TABLE_MAP.items(): - try: - count = model.objects.count() - except Exception: - count = -1 tables.append({ 'name': name, 'title': translate_table(name), 'titleEn': name, - 'count': count, + 'count': self.CachedTableCount(name, model), 'type': 'dynamic', 'source': 'model', }) @@ -1581,39 +1578,23 @@ class FormService(FormServiceBase): # 走"用户→角色"级联:从 (用户, 角色) 解析 UserRole 关联(同公司约束) if not urw_user or not urw_role: return {'error': f'必须指定用户、角色和{target_label}', 'field': 'UserRoleUUID'} - from gvsdsdk.model_utils import UUIDObj as _UO7 try: - urw_user_bytes = urw_user.bytes if hasattr(urw_user, 'bytes') else _UO7(str(urw_user)).bytes + ur_obj = RoleManager.GetUserRoleRelation(urw_user, urw_role, urw_company) except Exception: - urw_user_bytes = urw_user - try: - urw_role_bytes = urw_role.bytes if hasattr(urw_role, 'bytes') else _UO7(str(urw_role)).bytes - except Exception: - urw_role_bytes = urw_role - ur_qs = UserRole.objects.filter(UserUUID=urw_user_bytes, RoleUUID=urw_role_bytes) - if urw_company is not None: - ur_qs = ur_qs.filter(CompanyUUID=urw_company) - ur_obj = ur_qs.first() + ur_obj = None if ur_obj is None: return {'error': '该用户未绑定所选角色(或角色不属于目标公司),无法新增', 'field': 'RoleUUID'} urw_ur = ur_obj.UserRoleUUID create_data['UserRoleUUID'] = urw_ur if urw_target is None: return {'error': f'必须指定{target_label}', 'field': 'WorkgroupUUID' if table_name == 'UserRoleWorkgroup' else 'DeptUUID'} - from gvsdsdk.model_utils import UUIDObj as _UO3 - try: - urw_ur_bytes = urw_ur.bytes if hasattr(urw_ur, 'bytes') else _UO3(str(urw_ur)).bytes - except Exception: - urw_ur_bytes = urw_ur - if not UserRole.objects.filter(UserRoleUUID=urw_ur_bytes).exists(): + if RoleManager.GetUserRoleByUUID(urw_ur) is None: return {'error': '所选用户-角色关联不存在', 'field': 'UserRoleUUID'} if table_name == 'UserRoleWorkgroup': - dup_qs = UserRoleWorkgroup.objects.filter(UserRoleUUID=urw_ur_bytes, WorkgroupUUID=urw_target) + _dup = RoleManager.HasUserRoleWorkgroup(urw_ur, urw_target, urw_company) else: - dup_qs = UserRoleDepartment.objects.filter(UserRoleUUID=urw_ur_bytes, DeptUUID=urw_target) - if urw_company is not None: - dup_qs = dup_qs.filter(CompanyUUID=urw_company) - if dup_qs.exists(): + _dup = RoleManager.HasUserRoleDepartment(urw_ur, urw_target, urw_company) + if _dup: return {'error': f'该用户-角色对已在此{target_label}中', 'field': 'UserRoleUUID'} # UserRoleDepartment / UserRoleWorkgroup 职务多值化(身兼数职):PositionUUID 不在主表 # 字段(部门 0034 迁移删列;工作组 0043 迁移删列,职务复用公司员工关系子表), @@ -1733,22 +1714,16 @@ class FormService(FormServiceBase): _urd = None if _ur_pk and _dept_val: try: - _dept_bytes = _dept_val.bytes if hasattr(_dept_val, 'bytes') else uuid.UUID(str(_dept_val)).bytes + _dept_bytes = UUIDObj(_dept_val).bytes except Exception: - _dept_bytes = _dept_val - _urd = UserRoleDepartment.objects.filter(UserRoleUUID=_ur_pk).first() - if _urd is None: - _urd = UserRoleDepartment.objects.create( - UserRoleDepartmentUUID=uuid.uuid4().bytes, - UserRoleUUID=_ur_pk, - DeptUUID=_dept_bytes, - TenantUUID=self.current_tenant_uuid or getattr(obj, 'TenantUUID', None), - CompanyUUID=_ur_company, - RoleType=0, - ) - else: - _urd.DeptUUID = _dept_bytes - _urd.save(update_fields=['DeptUUID']) + _dept_bytes = None + if _dept_bytes is None: + return {'error': '无效的部门 UUID', 'field': 'DeptUUID'} + _urd = RoleManager.EnsureUserRoleDepartment( + _ur_pk, _dept_bytes, + TenantUUID=self.current_tenant_uuid or getattr(obj, 'TenantUUID', None), + CompanyUUID=_ur_company, + ) if _urd is not None and _raw_pos: from gvsdsdk.auth.managers import PositionManager for _pos in _raw_pos: @@ -1934,15 +1909,10 @@ class FormService(FormServiceBase): new_user = getattr(obj, 'UserUUID', None) new_role = getattr(obj, 'RoleUUID', None) if new_user is not None and new_role is not None: - from gvsdsdk.model_utils import UUIDObj as _UO5 - try: - new_user_bytes = new_user.bytes if hasattr(new_user, 'bytes') else _UO5(str(new_user)).bytes - except Exception: - new_user_bytes = new_user - dup_qs = UserRole.objects.filter(UserUUID=new_user_bytes, RoleUUID=new_role) - if model._meta.pk is not None: - dup_qs = dup_qs.exclude(**{model._meta.pk.name: getattr(obj, model._meta.pk.name)}) - if dup_qs.exists(): + if RoleManager.UserRoleRelationExists( + new_user, new_role, + ExcludeUserRoleUUID=getattr(obj, 'UserRoleUUID', None), + ): return {'error': '该用户已绑定此角色,请勿重复设置', 'field': 'RoleUUID'} # 工单状态流转:Status 变化时自动维护时间戳(UpdateTime/CloseTime), # 并向创建人/指派人发送站内信通知(MsgType=2 工单通知,排除操作者本人) @@ -1972,30 +1942,21 @@ class FormService(FormServiceBase): if table_name == 'UserRole' and ('DeptUUID' in data or 'PositionUUID' in data or 'PositionUUID_id' in data): _ur_pk = getattr(obj, 'UserRoleUUID', None) _ur_company = getattr(obj, 'CompanyUUID', None) - _urd = None - if _ur_pk: - _urd_qs = UserRoleDepartment.objects.filter(UserRoleUUID=_ur_pk) - if _ur_company: - _urd_qs = _urd_qs.filter(CompanyUUID=_ur_company) - _urd = _urd_qs.first() + _urd = RoleManager.GetUserRoleDepartmentForCompany(_ur_pk, _ur_company) if _ur_pk else None _dept_val = data.get('DeptUUID') or data.get('DeptUUID_id') if _dept_val: try: - _dept_bytes = _dept_val.bytes if hasattr(_dept_val, 'bytes') else uuid.UUID(str(_dept_val)).bytes + _dept_bytes = UUIDObj(_dept_val).bytes except Exception: - _dept_bytes = _dept_val - if _urd is None: - _urd = UserRoleDepartment.objects.create( - UserRoleDepartmentUUID=uuid.uuid4().bytes, - UserRoleUUID=_ur_pk, - DeptUUID=_dept_bytes, - TenantUUID=self.current_tenant_uuid or getattr(obj, 'TenantUUID', None), - CompanyUUID=_ur_company, - RoleType=0, - ) - else: - _urd.DeptUUID = _dept_bytes - _urd.save(update_fields=['DeptUUID']) + _dept_bytes = None + if _dept_bytes is None: + return {'error': '无效的部门 UUID', 'field': 'DeptUUID'} + _urd = RoleManager.EnsureUserRoleDepartment( + _ur_pk, _dept_bytes, + TenantUUID=self.current_tenant_uuid or getattr(obj, 'TenantUUID', None), + CompanyUUID=_ur_company, + MatchCompany=True, + ) if _urd is not None and ('PositionUUID' in data or 'PositionUUID_id' in data): _raw_pos = data.get('PositionUUID', data.get('PositionUUID_id', '')) if isinstance(_raw_pos, str): @@ -2113,12 +2074,7 @@ class FormService(FormServiceBase): return True # 部门删除:有成员(UserRoleDepartment 关联)则友好拦截,防止静默删除成员关系 if table_name == 'Department': - try: - dept_bytes = obj.DeptUUID - dept_bytes = dept_bytes.bytes if hasattr(dept_bytes, 'bytes') else uuid.UUID(str(dept_bytes)).bytes - except Exception: - dept_bytes = obj.DeptUUID - member_count = UserRoleDepartment.objects.filter(DeptUUID=dept_bytes).count() + member_count = len(RoleManager.GetUserRoleDepartmentsByDeptUUIDs([getattr(obj, 'DeptUUID', None)])) if member_count: return {'error': f'该部门下仍有 {member_count} 名成员,请先在"部门员工"中移除成员后再删除', 'field': 'PK'} # UserRoleDepartment 删除时级联清理职务子表(身兼数职,委托 SDK ClearUrdPositions) @@ -2213,21 +2169,21 @@ class FormService(FormServiceBase): # Department / Workgroup:列表页选中部门/工作组 → 解析其全部成员行) urd_objs = [] if table_name == 'UserRoleDepartment': - urd_objs = list(UserRoleDepartment.objects.filter(UserRoleDepartmentUUID__in=pks)) + urd_objs = RoleManager.GetUserRoleDepartmentsByUUIDs(pks) elif table_name == 'UserRoleWorkgroup': - for _urw in UserRoleWorkgroup.objects.filter(UserRoleWorkgroupUUID__in=pks): + for _urw in RoleManager.GetUserRoleWorkgroupsByUUIDs(pks): _urd = self._ResolvePrimaryUrd(_urw.UserRoleUUID, company_ctx) if _urd: urd_objs.append(_urd) elif table_name == 'UserRole': # 公司页员工行 - for _ur in UserRole.objects.filter(UserRoleUUID__in=pks): + for _ur in RoleManager.GetUserRolesByUUIDs(pks): _urd = self._ResolvePrimaryUrd(_ur.UserRoleUUID, company_ctx) if _urd: urd_objs.append(_urd) elif table_name == 'Department': # 部门列表页:选中的部门 → 其全部 UserRoleDepartment 成员 - urd_objs = list(UserRoleDepartment.objects.filter(DeptUUID__in=pks)) + urd_objs = RoleManager.GetUserRoleDepartmentsByDeptUUIDs(pks) else: # Workgroup 工作组列表页:选中的工作组 → 其全部成员(职务复用公司员工关系主关联) - for _urw in UserRoleWorkgroup.objects.filter(WorkgroupUUID__in=pks): + for _urw in RoleManager.GetUserRoleWorkgroupsByWorkgroupUUIDs(pks): _urd = self._ResolvePrimaryUrd(_urw.UserRoleUUID, company_ctx) if _urd: urd_objs.append(_urd)