organization_service.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. """组织树查询与祖先保留。"""
  2. from __future__ import annotations
  3. from sqlalchemy import select
  4. from dms.common.enums import EnabledStatus
  5. from dms.common.errors import InvalidArgumentError
  6. from dms.common.response import serialize_id
  7. from dms.extensions import db
  8. from dms.models import Organization
  9. def organization_tree(
  10. *, keyword: str | None, status: str | None
  11. ) -> list[dict[str, object]]:
  12. organizations = db.session.scalars(
  13. select(Organization)
  14. .where(Organization.is_deleted.is_(False))
  15. .order_by(Organization.sort_no.asc(), Organization.id.asc())
  16. ).all()
  17. by_id = {item.id: item for item in organizations}
  18. if status:
  19. try:
  20. normalized_status = EnabledStatus(status).value
  21. except ValueError as exc:
  22. raise InvalidArgumentError("status必须是ENABLED或DISABLED") from exc
  23. else:
  24. normalized_status = EnabledStatus.ENABLED.value
  25. base_ids = {item.id for item in organizations if item.status == normalized_status}
  26. if keyword and keyword.strip():
  27. needle = keyword.strip().casefold()
  28. base_ids = {
  29. item.id
  30. for item in organizations
  31. if item.id in base_ids
  32. and (needle in item.org_name.casefold() or needle in item.org_code.casefold())
  33. }
  34. included_ids = set(base_ids)
  35. for item_id in tuple(base_ids):
  36. parent_id = by_id[item_id].parent_id
  37. while parent_id is not None and parent_id in by_id:
  38. included_ids.add(parent_id)
  39. parent_id = by_id[parent_id].parent_id
  40. nodes = {
  41. item.id: {
  42. "id": serialize_id(item.id),
  43. "parentId": serialize_id(item.parent_id),
  44. "orgCode": item.org_code,
  45. "orgName": item.org_name,
  46. "orgPath": item.org_path,
  47. "sortNo": item.sort_no,
  48. "status": item.status,
  49. "children": [],
  50. }
  51. for item in organizations
  52. if item.id in included_ids
  53. }
  54. roots: list[dict[str, object]] = []
  55. for item in organizations:
  56. if item.id not in nodes:
  57. continue
  58. node = nodes[item.id]
  59. if item.parent_id in nodes:
  60. nodes[item.parent_id]["children"].append(node)
  61. else:
  62. roots.append(node)
  63. return roots