guzhi/app/api/v1/calculation/calcuation.py
2025-10-03 17:29:10 +08:00

158 lines
6.0 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
from app.utils.calculation_engine.economic_value_b1.sub_formulas.basic_value_b11 import calculate_popularity_score, \
calculate_infringement_score, calculate_patent_usage_score
from app.utils.calculation_engine.economic_value_b1.sub_formulas.traffic_factor_b12 import calculate_search_index_s1
from app.models.esg import ESG
from app.models.industry import Industry
from app.models.policy import Policy
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()
# 根据行业查询 ESG 基准分(优先用行业名称匹配,如用的是行业代码就把 name 改成 code
esg_obj = await ESG.filter(name=data.industry).first()
esg_score = float(esg_obj.number) if esg_obj else 0.0
# 根据行业查询 行业修正系数与ROE
industry_obj = await Industry.filter(name=data.industry).first()
# roe_score = industry_obj.roe
fix_num_score = industry_obj.fix_num
# 根据行业查询 政策匹配度
policy_obj = await Policy.filter(name=data.industry).first()
policy_match_score = policy_obj.score
# 提取计算参数
input_data = _extract_calculation_params(data)
# ESG关联价值 ESG分 (0-10分)
input_data["esg_score"] = esg_score
# 行业修正系数I
input_data["industry_coefficient"] = fix_num_score
# 政策匹配度
input_data["policy_match_score"] = policy_match_score
# 调用计算引擎
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相关参数
# 普及地域分值 默认 7分
popularity_score = calculate_popularity_score(data.application_coverage)
# TODO 专利剩余年限【专利证书】 需要使用第三方API
patent = data.patent_application_no
patent_score = 0
# 侵权分 默认 6 TODO 需要使用第三方API 无侵权记录(10分),历史侵权已解决(6分),现存纠纷(2分)
# infringement_score = calculate_infringement_score()
infringement_score = 0
# 发展潜力D相关参数
# 专利使用量 TODO 需要使用第三方API
patent_score = calculate_patent_usage_score(0)
# 创新投入比 = (研发费用/营收) * 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
#
# 流量因子B12相关参数
# 近30天搜索指数S1 - 从社交媒体数据计算 TODO 需要使用第三方API
search_index_s1 = calculate_search_index_s1() # 默认值实际应从API获取
# 行业均值S2 TODO 系统内置 未找到相关内容
industry_average_s2 = 0.0
# 社交媒体传播度S3 - TODO 需要使用第三方API,click_count view_count 未找到对应参数
# likes: 点赞数(API获取)
# comments: 评论数(API获取)
# shares: 转发数(API获取)
# followers: 粉丝数
# click_count: 商品链接点击量(用户填写) sales_volume 使用 sales_volume 销售量
# view_count: 内容浏览量(用户填写) link_views
# 政策乘数B13相关参数
# 政策契合度评分P - 根据行业和资助情况计算
# 实施阶段
implementation_stage = data.implementation_stage
# 资金支持
funding_support = data.funding_status
return {
# 基础价值B11相关参数
'three_year_income': three_year_income,
'patent_score': patent_score,
'popularity_score': popularity_score,
'infringement_score': infringement_score,
'innovation_ratio': innovation_ratio,
# 流量因子B12相关参数
'search_index_s1': search_index_s1,
# 'industry_average_s2': industry_average_s2,
# 'social_media_spread_s3': social_media_spread_s3,
'click_count': int(data.click_count) or 100,
'view_count': int(data.link_views) or 100,
# 政策乘数B13相关参数
'implementation_stage': implementation_stage,
'funding_support':funding_support
}