pilot_checkup.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. """中试服务体检管理 API(体检信息、预约项目、实际项目)"""
  2. from typing import List, Optional
  3. from fastapi import APIRouter, Depends, Query
  4. from pydantic import BaseModel
  5. from sqlalchemy.orm import Session
  6. from app.core.database import get_db
  7. from app.core.menu_guard import require_admin_or_super_admin
  8. from app.core.response import error_response, success_response
  9. from app.crud import pilot_checkup
  10. from app.models.models import SysUser
  11. router = APIRouter(prefix="/web/admin", tags=["中试服务体检管理"])
  12. def _get_tenant_no(db: Session, user: dict) -> str:
  13. user_id = user.get("user_id")
  14. if not user_id:
  15. raise PermissionError("用户身份信息缺失,无法确定租户")
  16. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  17. if not sys_user or not sys_user.tenant_no:
  18. raise PermissionError("用户租户信息缺失")
  19. return sys_user.tenant_no
  20. # ---------------------------------------------------------------------------
  21. # Pydantic Schemas
  22. # ---------------------------------------------------------------------------
  23. class IdBody(BaseModel):
  24. id: str
  25. class CheckupSaveBody(BaseModel):
  26. application_id: str
  27. checkup_institution_id: Optional[str] = None
  28. reserve_time: Optional[str] = None
  29. reserve_fee: Optional[float] = None
  30. actual_checkup_time: Optional[str] = None
  31. actual_checkup_fee: Optional[float] = None
  32. checkup_remark: Optional[str] = None
  33. report_attachments: Optional[str] = None
  34. class CheckupItemBody(BaseModel):
  35. project_name: str
  36. project_fee: Optional[float] = None
  37. class CheckupItemsSaveBody(BaseModel):
  38. pilot_checkup_id: str
  39. items: List[CheckupItemBody]
  40. # ---------------------------------------------------------------------------
  41. # 1. 体检信息 CRUD + 状态变更
  42. # ---------------------------------------------------------------------------
  43. @router.get("/pilot-checkup/detail")
  44. async def api_get_checkup_detail(
  45. application_id: str = Query(...),
  46. user: dict = Depends(require_admin_or_super_admin),
  47. db: Session = Depends(get_db),
  48. ):
  49. tenant_no = _get_tenant_no(db, user)
  50. result = pilot_checkup.get_checkup_by_application(
  51. db, application_id=application_id, tenant_no=tenant_no
  52. )
  53. if result is None:
  54. return success_response(None)
  55. return success_response(result)
  56. @router.post("/pilot-checkup/save")
  57. async def api_save_checkup(
  58. body: CheckupSaveBody,
  59. user: dict = Depends(require_admin_or_super_admin),
  60. db: Session = Depends(get_db),
  61. ):
  62. try:
  63. tenant_no = _get_tenant_no(db, user)
  64. data = {
  65. "checkupInstitutionId": body.checkup_institution_id,
  66. "reserveTime": body.reserve_time,
  67. "reserveFee": body.reserve_fee,
  68. "actualCheckupTime": body.actual_checkup_time,
  69. "actualCheckupFee": body.actual_checkup_fee,
  70. "checkupRemark": body.checkup_remark,
  71. "reportAttachments": body.report_attachments,
  72. }
  73. existing = pilot_checkup.get_checkup_by_application(
  74. db, application_id=body.application_id, tenant_no=tenant_no
  75. )
  76. if existing:
  77. result = pilot_checkup.update_checkup(
  78. db, checkup_id=existing["id"], data=data, tenant_no=tenant_no
  79. )
  80. return success_response(result, message="更新成功")
  81. else:
  82. result = pilot_checkup.create_checkup(
  83. db,
  84. application_id=body.application_id,
  85. data=data,
  86. tenant_no=tenant_no,
  87. user_id=user.get("user_id"),
  88. )
  89. return success_response(result, message="创建成功")
  90. except ValueError as e:
  91. return error_response(400, str(e))
  92. @router.delete("/pilot-checkup/delete")
  93. async def api_delete_checkup(
  94. body: IdBody,
  95. user: dict = Depends(require_admin_or_super_admin),
  96. db: Session = Depends(get_db),
  97. ):
  98. try:
  99. tenant_no = _get_tenant_no(db, user)
  100. pilot_checkup.soft_delete_checkup(db, checkup_id=body.id, tenant_no=tenant_no)
  101. return success_response(None, message="删除成功")
  102. except ValueError as e:
  103. return error_response(400, str(e))
  104. @router.post("/pilot-checkup/mark-checked")
  105. async def api_mark_checked(
  106. body: IdBody,
  107. user: dict = Depends(require_admin_or_super_admin),
  108. db: Session = Depends(get_db),
  109. ):
  110. try:
  111. tenant_no = _get_tenant_no(db, user)
  112. result = pilot_checkup.mark_checkup_checked(
  113. db, checkup_id=body.id, tenant_no=tenant_no, user_id=user.get("user_id")
  114. )
  115. return success_response(result, message="操作成功")
  116. except ValueError as e:
  117. return error_response(400, str(e))
  118. @router.post("/pilot-checkup/settle-fee")
  119. async def api_settle_fee(
  120. body: IdBody,
  121. user: dict = Depends(require_admin_or_super_admin),
  122. db: Session = Depends(get_db),
  123. ):
  124. try:
  125. tenant_no = _get_tenant_no(db, user)
  126. result = pilot_checkup.settle_checkup_fee(
  127. db, checkup_id=body.id, tenant_no=tenant_no, user_id=user.get("user_id")
  128. )
  129. return success_response(result, message="结算成功")
  130. except ValueError as e:
  131. return error_response(400, str(e))
  132. # ---------------------------------------------------------------------------
  133. # 2. 预约项目
  134. # ---------------------------------------------------------------------------
  135. @router.get("/pilot-checkup/reserve-items")
  136. async def api_list_reserve_items(
  137. pilot_checkup_id: str = Query(...),
  138. user: dict = Depends(require_admin_or_super_admin),
  139. db: Session = Depends(get_db),
  140. ):
  141. tenant_no = _get_tenant_no(db, user)
  142. result = pilot_checkup.list_reserve_items(
  143. db, checkup_id=pilot_checkup_id, tenant_no=tenant_no
  144. )
  145. return success_response(result)
  146. @router.post("/pilot-checkup/reserve-items/save")
  147. async def api_save_reserve_items(
  148. body: CheckupItemsSaveBody,
  149. user: dict = Depends(require_admin_or_super_admin),
  150. db: Session = Depends(get_db),
  151. ):
  152. try:
  153. tenant_no = _get_tenant_no(db, user)
  154. items_json = [item.dict() for item in body.items]
  155. result = pilot_checkup.save_reserve_items(
  156. db,
  157. checkup_id=body.pilot_checkup_id,
  158. items_json=items_json,
  159. tenant_no=tenant_no,
  160. user_id=user.get("user_id"),
  161. )
  162. return success_response(result, message="保存成功")
  163. except ValueError as e:
  164. return error_response(400, str(e))
  165. @router.delete("/pilot-checkup/reserve-item/delete")
  166. async def api_delete_reserve_item(
  167. body: IdBody,
  168. user: dict = Depends(require_admin_or_super_admin),
  169. db: Session = Depends(get_db),
  170. ):
  171. try:
  172. tenant_no = _get_tenant_no(db, user)
  173. pilot_checkup.delete_reserve_item(db, item_id=body.id, tenant_no=tenant_no)
  174. return success_response(None, message="删除成功")
  175. except ValueError as e:
  176. return error_response(400, str(e))
  177. # ---------------------------------------------------------------------------
  178. # 3. 实际项目
  179. # ---------------------------------------------------------------------------
  180. @router.get("/pilot-checkup/actual-items")
  181. async def api_list_actual_items(
  182. pilot_checkup_id: str = Query(...),
  183. user: dict = Depends(require_admin_or_super_admin),
  184. db: Session = Depends(get_db),
  185. ):
  186. tenant_no = _get_tenant_no(db, user)
  187. result = pilot_checkup.list_actual_items(
  188. db, checkup_id=pilot_checkup_id, tenant_no=tenant_no
  189. )
  190. return success_response(result)
  191. @router.post("/pilot-checkup/actual-items/save")
  192. async def api_save_actual_items(
  193. body: CheckupItemsSaveBody,
  194. user: dict = Depends(require_admin_or_super_admin),
  195. db: Session = Depends(get_db),
  196. ):
  197. try:
  198. tenant_no = _get_tenant_no(db, user)
  199. items_json = [item.dict() for item in body.items]
  200. result = pilot_checkup.save_actual_items(
  201. db,
  202. checkup_id=body.pilot_checkup_id,
  203. items_json=items_json,
  204. tenant_no=tenant_no,
  205. user_id=user.get("user_id"),
  206. )
  207. return success_response(result, message="保存成功")
  208. except ValueError as e:
  209. return error_response(400, str(e))
  210. @router.delete("/pilot-checkup/actual-item/delete")
  211. async def api_delete_actual_item(
  212. body: IdBody,
  213. user: dict = Depends(require_admin_or_super_admin),
  214. db: Session = Depends(get_db),
  215. ):
  216. try:
  217. tenant_no = _get_tenant_no(db, user)
  218. pilot_checkup.delete_actual_item(db, item_id=body.id, tenant_no=tenant_no)
  219. return success_response(None, message="删除成功")
  220. except ValueError as e:
  221. return error_response(400, str(e))