qc_sms_notification.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. """样本质检短信通知 API"""
  2. from typing import Optional
  3. from fastapi import APIRouter, Depends, Query
  4. from pydantic import BaseModel, ConfigDict, Field
  5. from sqlalchemy.orm import Session
  6. from app.core.database import get_db
  7. from app.core.menu_guard import require_any_menu_code
  8. from app.core.response import error_response, success_response
  9. from app.crud import qc_sms_notification as svc
  10. from app.crud.collection_protocol import total_pages
  11. from app.models.models import SysUser
  12. router = APIRouter(prefix="/web/admin", tags=["样本质检短信通知"])
  13. _QC_SMS_MENU = require_any_menu_code(
  14. "cell-storage:sample-info:list",
  15. )
  16. def _get_tenant_no(db: Session, user: dict) -> str:
  17. user_id = user.get("user_id")
  18. if not user_id:
  19. raise PermissionError("用户身份信息缺失,无法确定租户")
  20. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  21. if not sys_user or not sys_user.tenant_no:
  22. raise PermissionError("用户租户信息缺失")
  23. return sys_user.tenant_no
  24. def _get_current_user_id(user: dict) -> str:
  25. user_id = user.get("user_id")
  26. if not user_id:
  27. raise PermissionError("用户身份信息缺失")
  28. return str(user_id)
  29. def _page_payload(items: list, total: int, page: int, page_size: int) -> dict:
  30. return {
  31. "list": items,
  32. "total": total,
  33. "page": page,
  34. "pageSize": page_size,
  35. "totalPages": total_pages(total, page_size),
  36. }
  37. class ToggleStatusBody(BaseModel):
  38. model_config = ConfigDict(populate_by_name=True)
  39. sms_notified: int = Field(..., alias="smsNotified")
  40. qc_work_order_id: Optional[str] = Field(None, alias="qcWorkOrderId")
  41. protocol_sample_id: Optional[str] = Field(None, alias="protocolSampleId")
  42. @router.get("/qc-sms-notifications/list")
  43. async def list_notifications(
  44. page: int = Query(1, ge=1),
  45. pageSize: int = Query(10, ge=1, le=100),
  46. keyword: Optional[str] = None,
  47. qcStatus: Optional[str] = None,
  48. qcConclusion: Optional[str] = None,
  49. smsNotified: Optional[int] = None,
  50. qcCompleteTimeStart: Optional[str] = Query(None, alias="qcCompleteTimeStart"),
  51. qcCompleteTimeEnd: Optional[str] = Query(None, alias="qcCompleteTimeEnd"),
  52. db: Session = Depends(get_db),
  53. user: dict = Depends(_QC_SMS_MENU),
  54. ):
  55. try:
  56. tenant_no = _get_tenant_no(db, user)
  57. items, total = svc.list_notifications(
  58. db,
  59. page=page,
  60. page_size=pageSize,
  61. tenant_no=tenant_no,
  62. keyword=keyword,
  63. qc_status=qcStatus,
  64. qc_conclusion=qcConclusion,
  65. sms_notified=smsNotified,
  66. qc_complete_time_start=qcCompleteTimeStart,
  67. qc_complete_time_end=qcCompleteTimeEnd,
  68. user_info=user,
  69. )
  70. return success_response(_page_payload(items, total, page, pageSize))
  71. except PermissionError as e:
  72. return error_response(403, str(e))
  73. except Exception as e:
  74. return error_response(400, str(e))
  75. @router.put("/qc-sms-notifications/{notification_id}/toggle-status")
  76. async def toggle_status(
  77. notification_id: str,
  78. body: ToggleStatusBody,
  79. db: Session = Depends(get_db),
  80. user: dict = Depends(_QC_SMS_MENU),
  81. ):
  82. try:
  83. tenant_no = _get_tenant_no(db, user)
  84. user_id = _get_current_user_id(user)
  85. result = svc.toggle_notification_status(
  86. db,
  87. notification_id=notification_id,
  88. tenant_no=tenant_no,
  89. sms_notified=body.sms_notified,
  90. user_id=user_id,
  91. qc_work_order_id=body.qc_work_order_id,
  92. protocol_sample_id=body.protocol_sample_id,
  93. )
  94. if not result:
  95. return error_response(404, "通知记录不存在")
  96. return success_response(None)
  97. except PermissionError as e:
  98. return error_response(403, str(e))
  99. except Exception as e:
  100. return error_response(400, str(e))
  101. @router.post("/qc-sms-notifications/{notification_id}/generate-sms")
  102. async def generate_sms(
  103. notification_id: str,
  104. qcWorkOrderId: Optional[str] = Query(None),
  105. protocolSampleId: Optional[str] = Query(None),
  106. db: Session = Depends(get_db),
  107. user: dict = Depends(_QC_SMS_MENU),
  108. ):
  109. try:
  110. tenant_no = _get_tenant_no(db, user)
  111. user_id = _get_current_user_id(user)
  112. content = svc.generate_sms_content(
  113. db,
  114. notification_id=notification_id,
  115. tenant_no=tenant_no,
  116. qc_work_order_id=qcWorkOrderId,
  117. protocol_sample_id=protocolSampleId,
  118. user_id=user_id,
  119. )
  120. if content is None:
  121. return error_response(404, "通知记录不存在")
  122. return success_response({"smsContent": content})
  123. except PermissionError as e:
  124. return error_response(403, str(e))
  125. except Exception as e:
  126. return error_response(400, str(e))