dict_data.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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.utils import generate_uuid
  9. from app.models.models import SysDictData
  10. def _row_to_dict(d: SysDictData) -> Dict[str, Any]:
  11. return {
  12. "id": d.id,
  13. "dictLabel": d.dict_label,
  14. "dictValue": d.dict_value,
  15. "dictType": d.dict_type,
  16. "tenantNo": d.tenant_no,
  17. "orderNum": d.order_num if d.order_num is not None else 0,
  18. "remark": d.remark or "",
  19. "createTime": d.create_time.strftime("%Y-%m-%d %H:%M:%S") if d.create_time else "",
  20. "updateTime": d.update_time.strftime("%Y-%m-%d %H:%M:%S") if d.update_time else "",
  21. }
  22. def list_dict_data(
  23. db: Session,
  24. *,
  25. page: int = 1,
  26. page_size: int = 10,
  27. dict_type_code: Optional[str] = None,
  28. keyword: Optional[str] = None,
  29. tenant_no: Optional[str] = None,
  30. user_info=None,
  31. ) -> Tuple[List[Dict[str, Any]], int]:
  32. def _filtered():
  33. q0 = db.query(SysDictData).filter(SysDictData.del_flag == 0)
  34. if tenant_no:
  35. q0 = q0.filter(SysDictData.tenant_no == tenant_no)
  36. if dict_type_code:
  37. q0 = q0.filter(SysDictData.dict_type == dict_type_code)
  38. kw = (keyword or "").strip()
  39. if kw:
  40. like = f"%{kw}%"
  41. q0 = q0.filter(SysDictData.dict_label.like(like))
  42. if user_info:
  43. from app.core.data_scope import apply_data_scope
  44. q0 = apply_data_scope(q0, SysDictData, user_info, db, tenant_no)
  45. return q0
  46. total = _filtered().order_by(None).with_entities(func.count(SysDictData.id)).scalar() or 0
  47. page = max(1, page)
  48. page_size = min(max(1, page_size), 100)
  49. rows = (
  50. _filtered()
  51. .order_by(SysDictData.create_time.desc())
  52. .offset((page - 1) * page_size)
  53. .limit(page_size)
  54. .all()
  55. )
  56. return [_row_to_dict(x) for x in rows], int(total)
  57. def get_dict_data(db: Session, data_id: str) -> Optional[SysDictData]:
  58. return (
  59. db.query(SysDictData)
  60. .filter(and_(SysDictData.id == data_id, SysDictData.del_flag == 0))
  61. .first()
  62. )
  63. def create_dict_data(
  64. db: Session,
  65. *,
  66. dict_label: str,
  67. dict_value: str,
  68. dict_type: str,
  69. tenant_no: str,
  70. order_num: Optional[int] = None,
  71. remark: Optional[str] = None,
  72. user_id: Optional[str] = None,
  73. ) -> SysDictData:
  74. obj = SysDictData(
  75. id=generate_uuid(),
  76. dict_label=(dict_label or "").strip(),
  77. dict_value=(dict_value or "").strip(),
  78. dict_type=(dict_type or "").strip(),
  79. tenant_no=tenant_no,
  80. order_num=order_num if order_num is not None else 0,
  81. remark=(remark or "").strip() or None,
  82. create_by=user_id,
  83. create_dept_id="",
  84. create_time=datetime.now(),
  85. update_by=user_id,
  86. update_time=datetime.now(),
  87. del_flag=0,
  88. )
  89. db.add(obj)
  90. db.commit()
  91. db.refresh(obj)
  92. return obj
  93. def update_dict_data(
  94. db: Session,
  95. data_id: str,
  96. *,
  97. dict_label: Optional[str] = None,
  98. dict_value: Optional[str] = None,
  99. order_num: Optional[int] = None,
  100. remark: Optional[str] = None,
  101. user_id: Optional[str] = None,
  102. ) -> SysDictData:
  103. obj = get_dict_data(db, data_id)
  104. if not obj:
  105. raise ValueError("字典数据不存在")
  106. if dict_label is not None:
  107. obj.dict_label = (dict_label or "").strip()
  108. if dict_value is not None:
  109. obj.dict_value = (dict_value or "").strip()
  110. if order_num is not None:
  111. obj.order_num = order_num
  112. if remark is not None:
  113. obj.remark = (remark or "").strip() or None
  114. obj.update_by = user_id
  115. obj.update_time = datetime.now()
  116. db.add(obj)
  117. db.commit()
  118. db.refresh(obj)
  119. return obj
  120. def soft_delete_dict_data(db: Session, data_id: str) -> None:
  121. obj = get_dict_data(db, data_id)
  122. if not obj:
  123. raise ValueError("字典数据不存在")
  124. obj.del_flag = 1
  125. obj.update_time = datetime.now()
  126. db.add(obj)
  127. db.commit()
  128. TRANSFER_TYPE_DICT = "zzfs"
  129. VOID_TYPE_DICT = "xyzflx"
  130. def list_dict_data_options(
  131. db: Session, *, dict_type_code: str, tenant_no: Optional[str] = None
  132. ) -> List[Dict[str, str]]:
  133. q = db.query(SysDictData).filter(
  134. and_(SysDictData.dict_type == dict_type_code, SysDictData.del_flag == 0)
  135. )
  136. if tenant_no:
  137. q = q.filter(SysDictData.tenant_no == tenant_no)
  138. rows = q.order_by(SysDictData.order_num.asc(), SysDictData.create_time.desc()).all()
  139. return [{"label": r.dict_label, "value": r.dict_value} for r in rows]
  140. def is_dict_value_valid(
  141. db: Session,
  142. *,
  143. dict_type_code: str,
  144. value: str,
  145. tenant_no: Optional[str] = None,
  146. ) -> bool:
  147. normalized = (value or "").strip()
  148. if not normalized:
  149. return False
  150. q = db.query(SysDictData.id).filter(
  151. and_(
  152. SysDictData.dict_type == dict_type_code,
  153. SysDictData.dict_value == normalized,
  154. SysDictData.del_flag == 0,
  155. )
  156. )
  157. if tenant_no:
  158. q = q.filter(SysDictData.tenant_no == tenant_no)
  159. return q.first() is not None
  160. def normalize_transfer_type(
  161. db: Session,
  162. *,
  163. value: str,
  164. tenant_no: str,
  165. ) -> str:
  166. normalized = (value or "").strip()
  167. if not normalized:
  168. raise ValueError("请选择转账方式")
  169. if not is_dict_value_valid(
  170. db, dict_type_code=TRANSFER_TYPE_DICT, value=normalized, tenant_no=tenant_no
  171. ):
  172. raise ValueError("转账方式无效")
  173. return normalized
  174. def normalize_void_type(
  175. db: Session,
  176. *,
  177. value: str,
  178. tenant_no: str,
  179. ) -> str:
  180. normalized = (value or "").strip()
  181. if not normalized:
  182. raise ValueError("请选择作废类型")
  183. if not is_dict_value_valid(
  184. db, dict_type_code=VOID_TYPE_DICT, value=normalized, tenant_no=tenant_no
  185. ):
  186. raise ValueError("作废类型无效")
  187. return normalized
  188. def total_pages(total: int, page_size: int) -> int:
  189. if total <= 0:
  190. return 0
  191. return int(math.ceil(total / float(page_size)))