|
|
@@ -0,0 +1,210 @@
|
|
|
+"""样本级储存证 / 保险办理 API"""
|
|
|
+from typing import Optional
|
|
|
+
|
|
|
+from fastapi import APIRouter, Depends
|
|
|
+from pydantic import BaseModel, ConfigDict, Field
|
|
|
+from sqlalchemy.orm import Session
|
|
|
+
|
|
|
+from app.core.database import get_db
|
|
|
+from app.core.menu_guard import require_any_menu_code
|
|
|
+from app.core.response import error_response, success_response
|
|
|
+from app.core.utils import parse_datetime
|
|
|
+from app.crud import sample_insurance as insurance_crud
|
|
|
+from app.crud import sample_storage_cert as cert_crud
|
|
|
+from app.models.models import BizProtocolSample, SysUser
|
|
|
+
|
|
|
+router = APIRouter(prefix="/web/admin", tags=["样本储存证保险"])
|
|
|
+
|
|
|
+_MENU = require_any_menu_code("cell-storage:sample-info:list")
|
|
|
+
|
|
|
+
|
|
|
+def _get_tenant_no(db: Session, user: dict) -> str:
|
|
|
+ user_id = user.get("user_id")
|
|
|
+ if not user_id:
|
|
|
+ raise PermissionError("用户身份信息缺失,无法确定租户")
|
|
|
+ sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
|
|
|
+ if not sys_user or not sys_user.tenant_no:
|
|
|
+ raise PermissionError("用户租户信息缺失")
|
|
|
+ return sys_user.tenant_no
|
|
|
+
|
|
|
+
|
|
|
+def _get_current_user_id(user: dict) -> str:
|
|
|
+ user_id = user.get("user_id")
|
|
|
+ if not user_id:
|
|
|
+ raise PermissionError("用户身份信息缺失")
|
|
|
+ return str(user_id)
|
|
|
+
|
|
|
+
|
|
|
+def _resolve_protocol_id(db: Session, tenant_no: str, sample_code: str) -> Optional[str]:
|
|
|
+ row = (
|
|
|
+ db.query(BizProtocolSample)
|
|
|
+ .filter(
|
|
|
+ BizProtocolSample.tenant_no == tenant_no,
|
|
|
+ BizProtocolSample.sample_code == sample_code,
|
|
|
+ BizProtocolSample.del_flag == 0,
|
|
|
+ )
|
|
|
+ .first()
|
|
|
+ )
|
|
|
+ return (row.collection_protocol_id or "").strip() or None if row else None
|
|
|
+
|
|
|
+
|
|
|
+class SampleHandleBody(BaseModel):
|
|
|
+ model_config = ConfigDict(populate_by_name=True)
|
|
|
+
|
|
|
+ handle_time: Optional[str] = Field(None, alias="handleTime")
|
|
|
+ handler_user_id: Optional[str] = Field(None, alias="handlerUserId")
|
|
|
+ cert_image_urls: Optional[str] = Field(None, alias="certImageUrls")
|
|
|
+ insurance_attachments: Optional[str] = Field(None, alias="insuranceAttachments")
|
|
|
+ remark: Optional[str] = None
|
|
|
+ handle_remark: Optional[str] = Field(None, alias="handleRemark")
|
|
|
+ mail_cert_time: Optional[str] = Field(None, alias="mailCertTime")
|
|
|
+ policy_send_time: Optional[str] = Field(None, alias="policySendTime")
|
|
|
+ collection_protocol_id: Optional[str] = Field(None, alias="collectionProtocolId")
|
|
|
+
|
|
|
+
|
|
|
+@router.get("/sample-storage-certs/{sample_code}")
|
|
|
+async def get_sample_storage_cert(
|
|
|
+ sample_code: str,
|
|
|
+ db: Session = Depends(get_db),
|
|
|
+ user: dict = Depends(_MENU),
|
|
|
+):
|
|
|
+ try:
|
|
|
+ tenant_no = _get_tenant_no(db, user)
|
|
|
+ code = (sample_code or "").strip()
|
|
|
+ row = cert_crud.get_by_sample_code(db, tenant_no, code)
|
|
|
+ if row is None:
|
|
|
+ return success_response(
|
|
|
+ {
|
|
|
+ "sampleCode": code,
|
|
|
+ "storageCertHandled": False,
|
|
|
+ "handleTime": "",
|
|
|
+ "handlerUserId": "",
|
|
|
+ "certImageUrls": "",
|
|
|
+ "mailCertTime": "",
|
|
|
+ "remark": "",
|
|
|
+ }
|
|
|
+ )
|
|
|
+ return success_response(cert_crud.row_to_dict(row))
|
|
|
+ except PermissionError as e:
|
|
|
+ return error_response(403, str(e))
|
|
|
+ except Exception as e:
|
|
|
+ return error_response(400, str(e))
|
|
|
+
|
|
|
+
|
|
|
+@router.put("/sample-storage-certs/{sample_code}")
|
|
|
+async def put_sample_storage_cert(
|
|
|
+ sample_code: str,
|
|
|
+ body: SampleHandleBody,
|
|
|
+ db: Session = Depends(get_db),
|
|
|
+ user: dict = Depends(_MENU),
|
|
|
+):
|
|
|
+ try:
|
|
|
+ tenant_no = _get_tenant_no(db, user)
|
|
|
+ user_id = _get_current_user_id(user)
|
|
|
+ code = (sample_code or "").strip()
|
|
|
+ pid = (body.collection_protocol_id or "").strip() or _resolve_protocol_id(
|
|
|
+ db, tenant_no, code
|
|
|
+ )
|
|
|
+ ht = parse_datetime(body.handle_time) if body.handle_time else None
|
|
|
+ mail_raw = body.mail_cert_time
|
|
|
+ update_mail = mail_raw is not None
|
|
|
+ mail_t = parse_datetime(mail_raw) if mail_raw and str(mail_raw).strip() else None
|
|
|
+ row = cert_crud.upsert_handle(
|
|
|
+ db,
|
|
|
+ tenant_no=tenant_no,
|
|
|
+ sample_code=code,
|
|
|
+ collection_protocol_id=pid,
|
|
|
+ user_id=user_id,
|
|
|
+ handle_time=ht,
|
|
|
+ handler_user_id=body.handler_user_id,
|
|
|
+ cert_image_urls=body.cert_image_urls or "",
|
|
|
+ remark=body.remark or "",
|
|
|
+ mail_cert_time=mail_t,
|
|
|
+ update_mail_cert_time=update_mail,
|
|
|
+ )
|
|
|
+ db.commit()
|
|
|
+ return success_response(cert_crud.row_to_dict(row), message="保存成功")
|
|
|
+ except PermissionError as e:
|
|
|
+ db.rollback()
|
|
|
+ return error_response(403, str(e))
|
|
|
+ except ValueError as e:
|
|
|
+ db.rollback()
|
|
|
+ return error_response(400, str(e))
|
|
|
+ except Exception as e:
|
|
|
+ db.rollback()
|
|
|
+ return error_response(400, str(e))
|
|
|
+
|
|
|
+
|
|
|
+@router.get("/sample-insurances/{sample_code}")
|
|
|
+async def get_sample_insurance(
|
|
|
+ sample_code: str,
|
|
|
+ db: Session = Depends(get_db),
|
|
|
+ user: dict = Depends(_MENU),
|
|
|
+):
|
|
|
+ try:
|
|
|
+ tenant_no = _get_tenant_no(db, user)
|
|
|
+ code = (sample_code or "").strip()
|
|
|
+ row = insurance_crud.get_by_sample_code(db, tenant_no, code)
|
|
|
+ if row is None:
|
|
|
+ return success_response(
|
|
|
+ {
|
|
|
+ "sampleCode": code,
|
|
|
+ "insuranceHandled": False,
|
|
|
+ "handleTime": "",
|
|
|
+ "handlerUserId": "",
|
|
|
+ "insuranceAttachments": "",
|
|
|
+ "policySendTime": "",
|
|
|
+ "handleRemark": "",
|
|
|
+ }
|
|
|
+ )
|
|
|
+ return success_response(insurance_crud.row_to_dict(row))
|
|
|
+ except PermissionError as e:
|
|
|
+ return error_response(403, str(e))
|
|
|
+ except Exception as e:
|
|
|
+ return error_response(400, str(e))
|
|
|
+
|
|
|
+
|
|
|
+@router.put("/sample-insurances/{sample_code}")
|
|
|
+async def put_sample_insurance(
|
|
|
+ sample_code: str,
|
|
|
+ body: SampleHandleBody,
|
|
|
+ db: Session = Depends(get_db),
|
|
|
+ user: dict = Depends(_MENU),
|
|
|
+):
|
|
|
+ try:
|
|
|
+ tenant_no = _get_tenant_no(db, user)
|
|
|
+ user_id = _get_current_user_id(user)
|
|
|
+ code = (sample_code or "").strip()
|
|
|
+ pid = (body.collection_protocol_id or "").strip() or _resolve_protocol_id(
|
|
|
+ db, tenant_no, code
|
|
|
+ )
|
|
|
+ ht = parse_datetime(body.handle_time) if body.handle_time else None
|
|
|
+ policy_raw = body.policy_send_time
|
|
|
+ update_policy = policy_raw is not None
|
|
|
+ policy_t = (
|
|
|
+ parse_datetime(policy_raw) if policy_raw and str(policy_raw).strip() else None
|
|
|
+ )
|
|
|
+ row = insurance_crud.upsert_handle(
|
|
|
+ db,
|
|
|
+ tenant_no=tenant_no,
|
|
|
+ sample_code=code,
|
|
|
+ collection_protocol_id=pid,
|
|
|
+ user_id=user_id,
|
|
|
+ handle_time=ht,
|
|
|
+ handler_user_id=body.handler_user_id,
|
|
|
+ insurance_attachments=body.insurance_attachments or "",
|
|
|
+ handle_remark=body.handle_remark or body.remark or "",
|
|
|
+ policy_send_time=policy_t,
|
|
|
+ update_policy_send_time=update_policy,
|
|
|
+ )
|
|
|
+ db.commit()
|
|
|
+ return success_response(insurance_crud.row_to_dict(row), message="保存成功")
|
|
|
+ except PermissionError as e:
|
|
|
+ db.rollback()
|
|
|
+ return error_response(403, str(e))
|
|
|
+ except ValueError as e:
|
|
|
+ db.rollback()
|
|
|
+ return error_response(400, str(e))
|
|
|
+ except Exception as e:
|
|
|
+ db.rollback()
|
|
|
+ return error_response(400, str(e))
|