dict_data.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. """字典数据 CRUD(sys_dict_data)"""
  2. from __future__ import annotations
  3. import math
  4. from datetime import datetime
  5. from typing import Any, Dict, List, Optional, Tuple
  6. from sqlalchemy import and_, func, or_
  7. from sqlalchemy.orm import Session
  8. from app.core.delete_guard import assert_row_deletable_by_creator
  9. from app.core.utils import generate_uuid
  10. from app.models.models import SysDictData
  11. def _row_to_dict(d: SysDictData) -> Dict[str, Any]:
  12. return {
  13. "id": d.id,
  14. "dictLabel": d.dict_label,
  15. "dictValue": d.dict_value,
  16. "tagType": d.tag_type or "",
  17. "dictType": d.dict_type,
  18. "tenantNo": d.tenant_no,
  19. "orderNum": d.order_num if d.order_num is not None else 0,
  20. "remark": d.remark or "",
  21. "createBy": d.create_by or "",
  22. "createTime": d.create_time.strftime("%Y-%m-%d %H:%M:%S") if d.create_time else "",
  23. "updateTime": d.update_time.strftime("%Y-%m-%d %H:%M:%S") if d.update_time else "",
  24. }
  25. def list_dict_data(
  26. db: Session,
  27. *,
  28. page: int = 1,
  29. page_size: int = 10,
  30. dict_type_code: Optional[str] = None,
  31. keyword: Optional[str] = None,
  32. tenant_no: Optional[str] = None,
  33. user_info=None,
  34. ) -> Tuple[List[Dict[str, Any]], int]:
  35. def _filtered():
  36. q0 = db.query(SysDictData).filter(SysDictData.del_flag == 0)
  37. if tenant_no:
  38. q0 = q0.filter(SysDictData.tenant_no == tenant_no)
  39. if dict_type_code:
  40. q0 = q0.filter(SysDictData.dict_type == dict_type_code)
  41. kw = (keyword or "").strip()
  42. if kw:
  43. like = f"%{kw}%"
  44. q0 = q0.filter(SysDictData.dict_label.like(like))
  45. # 字典数据为租户主数据;管理列表也不按 create_by 过滤,避免普通管理员看不到字典项
  46. return q0
  47. total = _filtered().order_by(None).with_entities(func.count(SysDictData.id)).scalar() or 0
  48. page = max(1, page)
  49. page_size = min(max(1, page_size), 500)
  50. rows = (
  51. _filtered()
  52. .order_by(SysDictData.create_time.desc())
  53. .offset((page - 1) * page_size)
  54. .limit(page_size)
  55. .all()
  56. )
  57. return [_row_to_dict(x) for x in rows], int(total)
  58. def get_dict_data(db: Session, data_id: str) -> Optional[SysDictData]:
  59. return (
  60. db.query(SysDictData)
  61. .filter(and_(SysDictData.id == data_id, SysDictData.del_flag == 0))
  62. .first()
  63. )
  64. def create_dict_data(
  65. db: Session,
  66. *,
  67. dict_label: str,
  68. dict_value: str,
  69. dict_type: str,
  70. tenant_no: str,
  71. order_num: Optional[int] = None,
  72. remark: Optional[str] = None,
  73. user_id: Optional[str] = None,
  74. tag_type: Optional[str] = None,
  75. ) -> SysDictData:
  76. obj = SysDictData(
  77. id=generate_uuid(),
  78. dict_label=(dict_label or "").strip(),
  79. dict_value=(dict_value or "").strip(),
  80. dict_type=(dict_type or "").strip(),
  81. tag_type=(tag_type or "").strip(),
  82. tenant_no=tenant_no,
  83. order_num=order_num if order_num is not None else 0,
  84. remark=(remark or "").strip() or None,
  85. create_by=user_id,
  86. create_dept_id="",
  87. create_time=datetime.now(),
  88. update_by=user_id,
  89. update_time=datetime.now(),
  90. del_flag=0,
  91. )
  92. db.add(obj)
  93. db.commit()
  94. db.refresh(obj)
  95. return obj
  96. def update_dict_data(
  97. db: Session,
  98. data_id: str,
  99. *,
  100. dict_label: Optional[str] = None,
  101. dict_value: Optional[str] = None,
  102. order_num: Optional[int] = None,
  103. remark: Optional[str] = None,
  104. user_id: Optional[str] = None,
  105. tag_type: Optional[str] = None,
  106. ) -> SysDictData:
  107. obj = get_dict_data(db, data_id)
  108. if not obj:
  109. raise ValueError("字典数据不存在")
  110. if dict_label is not None:
  111. obj.dict_label = (dict_label or "").strip()
  112. if dict_value is not None:
  113. obj.dict_value = (dict_value or "").strip()
  114. if tag_type is not None:
  115. obj.tag_type = (tag_type or "").strip()
  116. if order_num is not None:
  117. obj.order_num = order_num
  118. if remark is not None:
  119. obj.remark = (remark or "").strip() or None
  120. obj.update_by = user_id
  121. obj.update_time = datetime.now()
  122. db.add(obj)
  123. db.commit()
  124. db.refresh(obj)
  125. return obj
  126. def soft_delete_dict_data(db: Session, data_id: str, *, user_info: dict = None) -> None:
  127. obj = get_dict_data(db, data_id)
  128. if not obj:
  129. raise ValueError("字典数据不存在")
  130. assert_row_deletable_by_creator(obj, user_info)
  131. obj.del_flag = 1
  132. obj.update_time = datetime.now()
  133. db.add(obj)
  134. db.commit()
  135. def list_dict_data_options(
  136. db: Session,
  137. *,
  138. dict_type_code: str,
  139. tenant_no: Optional[str] = None,
  140. user_info=None,
  141. ) -> List[Dict[str, str]]:
  142. """字典下拉选项:租户主数据,忽略数据范围(user_info 保留兼容调用方,不参与过滤)。"""
  143. _ = user_info
  144. q = db.query(SysDictData).filter(
  145. and_(SysDictData.dict_type == dict_type_code, SysDictData.del_flag == 0)
  146. )
  147. if tenant_no:
  148. q = q.filter(SysDictData.tenant_no == tenant_no)
  149. rows = q.order_by(SysDictData.create_time.desc()).all()
  150. return [{"label": r.dict_label, "value": r.dict_value, "tagType": r.tag_type or ""} for r in rows]
  151. def total_pages(total: int, page_size: int) -> int:
  152. if total <= 0:
  153. return 0
  154. return int(math.ceil(total / float(page_size)))