From 8a12707616d269a64656098ec2e4377ae79e42bf Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 15 Sep 2026 13:34:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(sdk):=20=E8=A1=A5=E7=94=A8=E6=88=B7-?= =?UTF-8?q?=E8=A7=92=E8=89=B2/URD=20=E8=81=8C=E5=8A=A1/=E8=81=8C=E5=8A=A1?= =?UTF-8?q?=E5=90=8D/=E9=83=A8=E9=97=A8=E5=90=8D=E7=9A=84=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=9F=A5=E8=AF=A2=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RoleManager.GetUserRolesByUUIDs:批量取 UserRole 行;PositionManager.GetUrdPositionRowsForUrds:一次取多个 URD 的职务子表行;PositionManager.GetPositionNameMap 与 DepartmentManager.GetDepartmentNameMap:批量 UUID→名称映射(字节键,避免 UUIDObj/bytes hash 不等)。 均为列表页批量富化所需的低层原语,供子项目替代逐个 filter 与手写映射循环。 --- auth/managers.py | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/auth/managers.py b/auth/managers.py index c1447ee..8f7ca82 100644 --- a/auth/managers.py +++ b/auth/managers.py @@ -147,6 +147,28 @@ class RoleManager: return UserRole.objects.none() return UserRole.objects.filter(CompanyUUID=comp_bytes) + @staticmethod + def GetUserRolesByUUIDs(UserRoleUUIDs): + """批量按 UUID 取「用户-角色」关联行(无效项自动跳过) + + Args: + UserRoleUUIDs: UserRoleUUID 集合(bytes/str/UUIDObj 均可) + + Returns: + list[UserRole] + """ + uuids = [] + for u in (UserRoleUUIDs or []): + if not u: + continue + try: + uuids.append(UUIDObj(u).bytes) + except Exception: + continue + if not uuids: + return [] + return list(UserRole.objects.filter(UserRoleUUID__in=uuids)) + @staticmethod def AssignPermission(RoleUUID, PermUUID, CompanyUUID): """为角色分配权限(指定公司)""" @@ -1219,6 +1241,58 @@ class PositionManager: ).values_list('PositionUUID', flat=True) ) + @staticmethod + def GetUrdPositionRowsForUrds(URDUUIDs): + """批量取多个 URD 的职务子表行(无效项自动跳过) + + Args: + URDUUIDs: UserRoleDepartmentUUID 集合(bytes/str/UUIDObj 均可) + + Returns: + list[UserRoleDepartmentPosition] + """ + urd_uuids = [] + for u in (URDUUIDs or []): + if not u: + continue + try: + urd_uuids.append(UUIDObj(u).bytes) + except Exception: + continue + if not urd_uuids: + return [] + return list( + UserRoleDepartmentPosition.objects.filter(UserRoleDepartmentUUID__in=urd_uuids) + ) + + @staticmethod + def GetPositionNameMap(PositionUUIDs): + """批量获取 PositionUUID(bytes) → PositionName 映射(仅含存在的职务) + + Args: + PositionUUIDs: UUID 集合(bytes/str/UUIDObj 混合均可) + + Returns: + dict[bytes, str]:键为 UUID 的 16 字节形式,与调用方字节键对齐 + """ + uuids = [] + for u in (PositionUUIDs or []): + if not u: + continue + try: + uuids.append(UUIDObj(u).bytes) + except Exception: + continue + if not uuids: + return {} + result = {} + for p in Position.objects.filter(PositionUUID__in=uuids): + try: + result[p.PositionUUID.bytes] = p.PositionName + except AttributeError: + result[UUIDObj(p.PositionUUID).bytes] = p.PositionName + return result + @staticmethod def GetHeldPositionUUIDs(): """所有员工当前持有的职务 UUID bytes 集合(UserRoleDepartmentPosition 引用) @@ -2606,6 +2680,34 @@ class DepartmentManager: return Department.objects.none() return Department.objects.filter(CompanyUUID=comp_bytes) + @staticmethod + def GetDepartmentNameMap(DeptUUIDs): + """批量获取 DeptUUID(bytes) → DeptName 映射(仅含存在的部门) + + Args: + DeptUUIDs: UUID 集合(bytes/str/UUIDObj 混合均可) + + Returns: + dict[bytes, str]:键为 UUID 的 16 字节形式,与调用方字节键对齐 + """ + uuids = [] + for u in (DeptUUIDs or []): + if not u: + continue + try: + uuids.append(UUIDObj(u).bytes) + except Exception: + continue + if not uuids: + return {} + result = {} + for d in Department.objects.filter(DeptUUID__in=uuids): + try: + result[d.DeptUUID.bytes] = d.DeptName + except AttributeError: + result[UUIDObj(d.DeptUUID).bytes] = d.DeptName + return result + @staticmethod def GetDepartmentsForUser(UserUUID): """获取用户部门列表(UserRole → UserRoleDepartment → Department,去重)"""