guzhi/app/api/v1/calculation/calcuation.py

120 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter, Depends, HTTPException, status
from typing import Optional, List, Dict, Any
import json
from app.controllers.user_valuation import user_valuation_controller
from app.schemas.valuation import (
UserValuationCreate,
UserValuationQuery,
UserValuationList,
UserValuationOut,
UserValuationDetail
)
from app.schemas.base import Success, SuccessExtra
from app.utils.app_user_jwt import get_current_app_user_id
from app.utils.calculation_engine.economic_value_b1.economic_value_b1 import EconomicValueB1Calculator
app_valuations_router = APIRouter(tags=["用户端估值评估"])
@app_valuations_router.post("/calculation", summary="计算估值")
async def calculate_valuation(
data: UserValuationCreate,
user_id: int = Depends(get_current_app_user_id)
):
"""
计算估值评估
根据用户提交的估值评估数据调用计算引擎进行经济价值B1计算
"""
try:
# 创建计算器实例
calculator = EconomicValueB1Calculator()
# 从用户数据中提取计算所需的参数
input_data = _extract_calculation_params(data)
# 调用计算引擎进行估值计算
calculation_result = calculator.calculate_complete_economic_value_b1(input_data)
# 创建估值评估记录
result = await user_valuation_controller.create_valuation(
user_id=user_id,
data=data
)
# 将计算结果添加到返回数据中
result_dict = json.loads(result.model_dump_json())
result_dict['calculation_result'] = calculation_result
return Success(data=result_dict, msg="估值计算完成")
except Exception as e:
raise HTTPException(status_code=400, detail=f"计算失败: {str(e)}")
def _extract_calculation_params(data: UserValuationCreate) -> Dict[str, Any]:
"""
从用户提交的数据中提取计算所需的参数
Args:
data: 用户提交的估值评估数据
Returns:
Dict: 计算所需的参数字典
"""
# 基础价值B11相关参数
# 财务价值所需数据 从近三年收益计算
three_year_income = data.three_year_income or [0, 0, 0]
# 法律强度L相关参数 - 需要用户额外提供评分
# 这里使用默认值,实际应用中需要用户填写
patent_score = 5.0 # 专利分 (0-10分)
popularity_score = 5.0 # 普及地域分 (0-10分)
infringement_score = 5.0 # 侵权分 (0-10分)
# 发展潜力D相关参数
esg_score = 5.0 # ESG分 (0-10分)
# 创新投入比 = (研发费用/营收) * 100
try:
rd_investment = float(data.rd_investment or 0)
annual_revenue = float(data.annual_revenue or 1) # 避免除零
innovation_ratio = (rd_investment / annual_revenue) * 100 if annual_revenue > 0 else 0
except (ValueError, TypeError):
innovation_ratio = 0.0
# 行业系数I - 系统配置值
target_industry_roe = 0.15 # 目标行业平均ROE
benchmark_industry_roe = 0.12 # 基准行业ROE
# 流量因子B12相关参数
# 近30天搜索指数S1 - 从社交媒体数据计算
search_index_s1 = 4500.0 # 默认值实际应从API获取
industry_average_s2 = 5000.0 # 行业均值,系统配置
# 社交媒体传播度S3 - 从线上账号信息计算
social_media_spread_s3 = 1.07 # 默认值实际应从API获取
# 政策乘数B13相关参数
# 政策契合度评分P - 根据行业和资助情况计算
policy_compatibility_score = 9.1 # 默认值,实际应系统计算
return {
# 基础价值B11相关参数
'financial_value': financial_value,
'patent_score': patent_score,
'popularity_score': popularity_score,
'infringement_score': infringement_score,
'esg_score': esg_score,
'innovation_ratio': innovation_ratio,
'target_industry_roe': target_industry_roe,
'benchmark_industry_roe': benchmark_industry_roe,
# 流量因子B12相关参数
'search_index_s1': search_index_s1,
'industry_average_s2': industry_average_s2,
'social_media_spread_s3': social_media_spread_s3,
# 政策乘数B13相关参数
'policy_compatibility_score': policy_compatibility_score
}