cd_flux_removal.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. """
  2. Cd通量移除计算API接口
  3. @description: 提供籽粒移除和秸秆移除的Cd通量计算功能
  4. """
  5. from fastapi import APIRouter, HTTPException, Query, Path
  6. from pydantic import BaseModel, Field
  7. from typing import Dict, Any, Optional
  8. import logging
  9. from ..services.cd_flux_removal_service import CdFluxRemovalService
  10. router = APIRouter()
  11. # =============================================================================
  12. # 数据模型定义
  13. # =============================================================================
  14. class CdFluxRemovalResponse(BaseModel):
  15. """
  16. Cd通量移除计算响应模型
  17. @description: 标准化的API响应格式
  18. """
  19. success: bool = Field(..., description="是否成功")
  20. message: str = Field(..., description="响应消息")
  21. data: Optional[Dict[str, Any]] = Field(None, description="计算结果数据")
  22. # 设置日志
  23. logger = logging.getLogger(__name__)
  24. # =============================================================================
  25. # Cd通量移除计算接口
  26. # =============================================================================
  27. @router.get("/grain-removal",
  28. summary="计算籽粒移除Cd通量",
  29. description="根据指定地区计算籽粒移除Cd通量,公式:EXP(LnCropCd)*F11*0.5*15/1000",
  30. response_model=CdFluxRemovalResponse)
  31. async def calculate_grain_removal(
  32. area: str = Query(..., description="地区名称,如:韶关")
  33. ) -> Dict[str, Any]:
  34. """
  35. 计算籽粒移除Cd通量
  36. @param area: 地区名称
  37. @returns: 籽粒移除Cd通量计算结果
  38. 计算公式:籽粒移除(g/ha/a) = EXP(LnCropCd) * F11 * 0.5 * 15 / 1000
  39. 数据来源:
  40. - LnCropCd: CropCd_output_data表
  41. - F11: Parameters表(作物亩产量)
  42. """
  43. try:
  44. service = CdFluxRemovalService()
  45. result = service.calculate_grain_removal_by_area(area)
  46. if not result["success"]:
  47. raise HTTPException(
  48. status_code=404,
  49. detail=result["message"]
  50. )
  51. return result
  52. except HTTPException:
  53. raise
  54. except Exception as e:
  55. logger.error(f"计算地区 '{area}' 的籽粒移除Cd通量失败: {str(e)}")
  56. raise HTTPException(
  57. status_code=500,
  58. detail=f"计算失败: {str(e)}"
  59. )
  60. @router.get("/straw-removal",
  61. summary="计算秸秆移除Cd通量",
  62. description="根据指定地区计算秸秆移除Cd通量,公式:[EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)]*F11*0.5*15/1000",
  63. response_model=CdFluxRemovalResponse)
  64. async def calculate_straw_removal(
  65. area: str = Query(..., description="地区名称,如:韶关")
  66. ) -> Dict[str, Any]:
  67. """
  68. 计算秸秆移除Cd通量
  69. @param area: 地区名称
  70. @returns: 秸秆移除Cd通量计算结果
  71. 计算公式:秸秆移除(g/ha/a) = [EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)] * F11 * 0.5 * 15 / 1000
  72. 数据来源:
  73. - LnCropCd: CropCd_output_data表
  74. - F11: Parameters表(作物亩产量)
  75. """
  76. try:
  77. service = CdFluxRemovalService()
  78. result = service.calculate_straw_removal_by_area(area)
  79. if not result["success"]:
  80. raise HTTPException(
  81. status_code=404,
  82. detail=result["message"]
  83. )
  84. return result
  85. except HTTPException:
  86. raise
  87. except Exception as e:
  88. logger.error(f"计算地区 '{area}' 的秸秆移除Cd通量失败: {str(e)}")
  89. raise HTTPException(
  90. status_code=500,
  91. detail=f"计算失败: {str(e)}"
  92. )
  93. @router.get("/both-removals",
  94. summary="同时计算籽粒移除和秸秆移除Cd通量",
  95. description="根据指定地区同时计算籽粒移除和秸秆移除Cd通量",
  96. response_model=CdFluxRemovalResponse)
  97. async def calculate_both_removals(
  98. area: str = Query(..., description="地区名称,如:韶关")
  99. ) -> Dict[str, Any]:
  100. """
  101. 同时计算籽粒移除和秸秆移除Cd通量
  102. @param area: 地区名称
  103. @returns: 包含籽粒移除和秸秆移除Cd通量的计算结果
  104. 计算公式:
  105. - 籽粒移除(g/ha/a) = EXP(LnCropCd) * F11 * 0.5 * 15 / 1000
  106. - 秸秆移除(g/ha/a) = [EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)] * F11 * 0.5 * 15 / 1000
  107. """
  108. try:
  109. service = CdFluxRemovalService()
  110. result = service.calculate_both_removals_by_area(area)
  111. if not result["success"]:
  112. raise HTTPException(
  113. status_code=404,
  114. detail=result["message"]
  115. )
  116. return result
  117. except HTTPException:
  118. raise
  119. except Exception as e:
  120. logger.error(f"计算地区 '{area}' 的Cd通量移除失败: {str(e)}")
  121. raise HTTPException(
  122. status_code=500,
  123. detail=f"计算失败: {str(e)}"
  124. )
  125. @router.get("/sample/{farmland_id}/{sample_id}",
  126. summary="计算特定样点的Cd通量移除",
  127. description="根据特定农地ID和样点ID计算籽粒移除和秸秆移除Cd通量",
  128. response_model=CdFluxRemovalResponse)
  129. async def calculate_removal_by_sample(
  130. farmland_id: int = Path(..., description="农地ID", ge=1),
  131. sample_id: int = Path(..., description="样点ID", ge=1),
  132. area: str = Query(..., description="地区名称,如:韶关")
  133. ) -> Dict[str, Any]:
  134. """
  135. 计算特定样点的Cd通量移除
  136. @param farmland_id: 农地ID
  137. @param sample_id: 样点ID
  138. @param area: 地区名称
  139. @returns: 特定样点的籽粒移除和秸秆移除Cd通量计算结果
  140. 计算公式:
  141. - 籽粒移除(g/ha/a) = EXP(LnCropCd) * F11 * 0.5 * 15 / 1000
  142. - 秸秆移除(g/ha/a) = [EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)] * F11 * 0.5 * 15 / 1000
  143. """
  144. try:
  145. service = CdFluxRemovalService()
  146. result = service.calculate_removal_by_sample(farmland_id, sample_id, area)
  147. if not result["success"]:
  148. raise HTTPException(
  149. status_code=404,
  150. detail=result["message"]
  151. )
  152. return result
  153. except HTTPException:
  154. raise
  155. except Exception as e:
  156. logger.error(f"计算样点 {farmland_id}-{sample_id} 的Cd通量移除失败: {str(e)}")
  157. raise HTTPException(
  158. status_code=500,
  159. detail=f"计算失败: {str(e)}"
  160. )