123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- """
- Cd通量移除计算API接口
- @description: 提供籽粒移除和秸秆移除的Cd通量计算功能
- """
- from fastapi import APIRouter, HTTPException, Query, Path
- from pydantic import BaseModel, Field
- from typing import Dict, Any, Optional
- import logging
- from ..services.cd_flux_removal_service import CdFluxRemovalService
- router = APIRouter()
- # =============================================================================
- # 数据模型定义
- # =============================================================================
- class CdFluxRemovalResponse(BaseModel):
- """
- Cd通量移除计算响应模型
-
- @description: 标准化的API响应格式
- """
- success: bool = Field(..., description="是否成功")
- message: str = Field(..., description="响应消息")
- data: Optional[Dict[str, Any]] = Field(None, description="计算结果数据")
- # 设置日志
- logger = logging.getLogger(__name__)
- # =============================================================================
- # Cd通量移除计算接口
- # =============================================================================
- @router.get("/grain-removal",
- summary="计算籽粒移除Cd通量",
- description="根据指定地区计算籽粒移除Cd通量,公式:EXP(LnCropCd)*F11*0.5*15/1000",
- response_model=CdFluxRemovalResponse)
- async def calculate_grain_removal(
- area: str = Query(..., description="地区名称,如:韶关")
- ) -> Dict[str, Any]:
- """
- 计算籽粒移除Cd通量
-
- @param area: 地区名称
- @returns: 籽粒移除Cd通量计算结果
-
- 计算公式:籽粒移除(g/ha/a) = EXP(LnCropCd) * F11 * 0.5 * 15 / 1000
- 数据来源:
- - LnCropCd: CropCd_output_data表
- - F11: Parameters表(作物亩产量)
- """
- try:
- service = CdFluxRemovalService()
- result = service.calculate_grain_removal_by_area(area)
-
- if not result["success"]:
- raise HTTPException(
- status_code=404,
- detail=result["message"]
- )
-
- return result
-
- except HTTPException:
- raise
- except Exception as e:
- logger.error(f"计算地区 '{area}' 的籽粒移除Cd通量失败: {str(e)}")
- raise HTTPException(
- status_code=500,
- detail=f"计算失败: {str(e)}"
- )
- @router.get("/straw-removal",
- summary="计算秸秆移除Cd通量",
- description="根据指定地区计算秸秆移除Cd通量,公式:[EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)]*F11*0.5*15/1000",
- response_model=CdFluxRemovalResponse)
- async def calculate_straw_removal(
- area: str = Query(..., description="地区名称,如:韶关")
- ) -> Dict[str, Any]:
- """
- 计算秸秆移除Cd通量
-
- @param area: 地区名称
- @returns: 秸秆移除Cd通量计算结果
-
- 计算公式:秸秆移除(g/ha/a) = [EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)] * F11 * 0.5 * 15 / 1000
- 数据来源:
- - LnCropCd: CropCd_output_data表
- - F11: Parameters表(作物亩产量)
- """
- try:
- service = CdFluxRemovalService()
- result = service.calculate_straw_removal_by_area(area)
-
- if not result["success"]:
- raise HTTPException(
- status_code=404,
- detail=result["message"]
- )
-
- return result
-
- except HTTPException:
- raise
- except Exception as e:
- logger.error(f"计算地区 '{area}' 的秸秆移除Cd通量失败: {str(e)}")
- raise HTTPException(
- status_code=500,
- detail=f"计算失败: {str(e)}"
- )
- @router.get("/both-removals",
- summary="同时计算籽粒移除和秸秆移除Cd通量",
- description="根据指定地区同时计算籽粒移除和秸秆移除Cd通量",
- response_model=CdFluxRemovalResponse)
- async def calculate_both_removals(
- area: str = Query(..., description="地区名称,如:韶关")
- ) -> Dict[str, Any]:
- """
- 同时计算籽粒移除和秸秆移除Cd通量
-
- @param area: 地区名称
- @returns: 包含籽粒移除和秸秆移除Cd通量的计算结果
-
- 计算公式:
- - 籽粒移除(g/ha/a) = EXP(LnCropCd) * F11 * 0.5 * 15 / 1000
- - 秸秆移除(g/ha/a) = [EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)] * F11 * 0.5 * 15 / 1000
- """
- try:
- service = CdFluxRemovalService()
- result = service.calculate_both_removals_by_area(area)
-
- if not result["success"]:
- raise HTTPException(
- status_code=404,
- detail=result["message"]
- )
-
- return result
-
- except HTTPException:
- raise
- except Exception as e:
- logger.error(f"计算地区 '{area}' 的Cd通量移除失败: {str(e)}")
- raise HTTPException(
- status_code=500,
- detail=f"计算失败: {str(e)}"
- )
- @router.get("/sample/{farmland_id}/{sample_id}",
- summary="计算特定样点的Cd通量移除",
- description="根据特定农地ID和样点ID计算籽粒移除和秸秆移除Cd通量",
- response_model=CdFluxRemovalResponse)
- async def calculate_removal_by_sample(
- farmland_id: int = Path(..., description="农地ID", ge=1),
- sample_id: int = Path(..., description="样点ID", ge=1),
- area: str = Query(..., description="地区名称,如:韶关")
- ) -> Dict[str, Any]:
- """
- 计算特定样点的Cd通量移除
-
- @param farmland_id: 农地ID
- @param sample_id: 样点ID
- @param area: 地区名称
- @returns: 特定样点的籽粒移除和秸秆移除Cd通量计算结果
-
- 计算公式:
- - 籽粒移除(g/ha/a) = EXP(LnCropCd) * F11 * 0.5 * 15 / 1000
- - 秸秆移除(g/ha/a) = [EXP(LnCropCd)/(EXP(LnCropCd)*0.76-0.0034)] * F11 * 0.5 * 15 / 1000
- """
- try:
- service = CdFluxRemovalService()
- result = service.calculate_removal_by_sample(farmland_id, sample_id, area)
-
- if not result["success"]:
- raise HTTPException(
- status_code=404,
- detail=result["message"]
- )
-
- return result
-
- except HTTPException:
- raise
- except Exception as e:
- logger.error(f"计算样点 {farmland_id}-{sample_id} 的Cd通量移除失败: {str(e)}")
- raise HTTPException(
- status_code=500,
- detail=f"计算失败: {str(e)}"
- )
|