qc_task_result.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. from __future__ import annotations
  2. from datetime import datetime
  3. from typing import Any, Dict, List, Optional, Tuple
  4. from sqlalchemy.orm import Session
  5. from app.core.utils import generate_uuid
  6. from app.crud import qc_item_param as param_svc
  7. from app.crud.qc_task import get_task
  8. from app.models.models import BizQcWorkOrderLabItem, BizQcWorkOrderThirdItem
  9. from app.models.qc_param import BizQcTaskResult
  10. def _row_to_dict(r: BizQcTaskResult) -> Dict[str, Any]:
  11. return {
  12. "id": r.id,
  13. "paramId": r.param_id or "",
  14. "paramName": r.param_name,
  15. "paramCode": r.param_code or "",
  16. "paramUnit": r.param_unit or "",
  17. "paramType": r.param_type or "text",
  18. "paramValue": r.param_value or "",
  19. }
  20. def _list_saved_results_by_task(
  21. db: Session, task_id: str, tenant_no: str, *, user_info=None
  22. ) -> List[Dict[str, Any]]:
  23. q = db.query(BizQcTaskResult).filter(
  24. BizQcTaskResult.task_id == task_id,
  25. BizQcTaskResult.tenant_no == tenant_no,
  26. BizQcTaskResult.del_flag == 0,
  27. )
  28. if user_info:
  29. from app.core.data_scope import apply_data_scope
  30. q = apply_data_scope(q, BizQcTaskResult, user_info, db, tenant_no)
  31. rows = q.order_by(BizQcTaskResult.create_time.asc()).all()
  32. return [_row_to_dict(r) for r in rows]
  33. def _resolve_task_item_ref(db: Session, task) -> Tuple[Optional[str], Optional[str]]:
  34. """返回 (item_source, item_id) 供 biz_qc_item_param 查询。"""
  35. if task.task_type == "sysz":
  36. line = (
  37. db.query(BizQcWorkOrderLabItem)
  38. .filter(
  39. BizQcWorkOrderLabItem.id == task.source_line_id,
  40. BizQcWorkOrderLabItem.del_flag == 0,
  41. )
  42. .first()
  43. )
  44. if line:
  45. return "lab", line.lab_test_item_id
  46. elif task.task_type == "dsfjc":
  47. line = (
  48. db.query(BizQcWorkOrderThirdItem)
  49. .filter(
  50. BizQcWorkOrderThirdItem.id == task.source_line_id,
  51. BizQcWorkOrderThirdItem.del_flag == 0,
  52. )
  53. .first()
  54. )
  55. if line:
  56. return "third_party", line.third_party_item_id
  57. return None, None
  58. def _merge_saved_into_template(
  59. templates: List[Dict[str, Any]], saved: List[Dict[str, Any]]
  60. ) -> List[Dict[str, Any]]:
  61. by_id = {s["paramId"]: s for s in saved if s.get("paramId")}
  62. by_code = {s["paramCode"]: s for s in saved if s.get("paramCode")}
  63. out: List[Dict[str, Any]] = []
  64. for p in templates:
  65. pid = p.get("id") or ""
  66. code = p.get("paramCode") or ""
  67. hit = by_id.get(pid) or (by_code.get(code) if code else None)
  68. saved_value = (hit.get("paramValue") if hit else "") or ""
  69. default_value = (p.get("defaultValue") or "").strip()
  70. param_type = p.get("paramType", "text")
  71. if not saved_value and param_type == "select" and default_value:
  72. saved_value = default_value
  73. out.append(
  74. {
  75. "paramId": pid,
  76. "paramName": p.get("paramName", ""),
  77. "paramCode": code,
  78. "paramUnit": p.get("paramUnit", ""),
  79. "paramType": param_type,
  80. "options": p.get("options", ""),
  81. "defaultValue": default_value,
  82. "paramValue": saved_value,
  83. "requiredFlag": p.get("requiredFlag", "0"),
  84. }
  85. )
  86. return out
  87. def list_saved_results_by_task_ids(
  88. db: Session, task_ids: List[str], tenant_no: str
  89. ) -> Dict[str, List[Dict[str, Any]]]:
  90. """按任务 ID 批量返回已保存检测参数(只读展示用,不合并模板空项)。"""
  91. ids = list({(x or "").strip() for x in task_ids if (x or "").strip()})
  92. if not ids or not tenant_no:
  93. return {}
  94. rows = (
  95. db.query(BizQcTaskResult)
  96. .filter(
  97. BizQcTaskResult.task_id.in_(ids),
  98. BizQcTaskResult.tenant_no == tenant_no,
  99. BizQcTaskResult.del_flag == 0,
  100. )
  101. .order_by(BizQcTaskResult.create_time.asc())
  102. .all()
  103. )
  104. grouped: Dict[str, List[Dict[str, Any]]] = {i: [] for i in ids}
  105. for r in rows:
  106. tid = (r.task_id or "").strip()
  107. if tid in grouped:
  108. grouped[tid].append(_row_to_dict(r))
  109. return grouped
  110. def list_results_by_task(
  111. db: Session, task_id: str, tenant_no: str, *, user_info=None
  112. ) -> List[Dict[str, Any]]:
  113. """返回任务结果填写表单:项目参数模板 + 已保存值(无模板时仅返回已保存记录)。"""
  114. saved = _list_saved_results_by_task(db, task_id, tenant_no, user_info=user_info)
  115. task = get_task(db, task_id, tenant_no=tenant_no)
  116. if not task:
  117. return saved
  118. item_source, item_id = _resolve_task_item_ref(db, task)
  119. if not item_source or not item_id:
  120. return saved
  121. templates = param_svc.list_params_by_item(db, item_source, item_id, tenant_no)
  122. if not templates:
  123. return saved
  124. return _merge_saved_into_template(templates, saved)
  125. def save_results_for_task(
  126. db: Session,
  127. task_id: str,
  128. results: List[Dict[str, Any]],
  129. tenant_no: str,
  130. user_id: Optional[str] = None,
  131. *,
  132. commit: bool = True,
  133. ) -> List[Dict[str, Any]]:
  134. task = get_task(db, task_id, tenant_no=tenant_no)
  135. if not task:
  136. raise ValueError("任务不存在")
  137. now = datetime.now()
  138. db.query(BizQcTaskResult).filter(
  139. BizQcTaskResult.task_id == task_id,
  140. BizQcTaskResult.tenant_no == tenant_no,
  141. BizQcTaskResult.del_flag == 0,
  142. ).update(
  143. {"del_flag": 1, "update_by": user_id, "update_time": now},
  144. synchronize_session="fetch",
  145. )
  146. db.flush()
  147. for res in results:
  148. obj = BizQcTaskResult(
  149. id=generate_uuid(),
  150. task_id=task_id,
  151. param_id=res.get("paramId") or None,
  152. param_name=res.get("paramName", ""),
  153. param_code=res.get("paramCode") or None,
  154. param_unit=res.get("paramUnit") or None,
  155. param_type=res.get("paramType", "text"),
  156. param_value=res.get("paramValue") or None,
  157. tenant_no=tenant_no,
  158. create_by=user_id,
  159. create_dept_id="",
  160. create_time=now,
  161. update_by=user_id,
  162. update_time=now,
  163. del_flag=0,
  164. )
  165. db.add(obj)
  166. if commit:
  167. db.commit()
  168. else:
  169. db.flush()
  170. return list_results_by_task(db, task_id, tenant_no)