diff --git a/app/api/v1/app_valuations/app_valuations.py b/app/api/v1/app_valuations/app_valuations.py index 4fb0e9e..74b7b9d 100644 --- a/app/api/v1/app_valuations/app_valuations.py +++ b/app/api/v1/app_valuations/app_valuations.py @@ -66,7 +66,7 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate except Exception as e: logger.warning("valuation.policy_fetch_timeout industry={} err={}", data.industry, repr(e)) policy_match_score = getattr(policy_obj, 'score', 0.0) or 0.0 - + # 提取 经济价值B1 计算参数 input_data_by_b1 = await _extract_calculation_params_b1(data) # ESG关联价值 ESG分 (0-10分) @@ -79,7 +79,7 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate # 侵权分 默认 6 try: judicial_data = universal_api.query_judicial_data(data.institution) - _data = judicial_data["data"].get("target",None) # 诉讼标的 + _data = judicial_data["data"].get("target", None) # 诉讼标的 if _data: infringement_score = 0.0 else: @@ -87,7 +87,7 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate except: infringement_score = 0.0 input_data_by_b1["infringement_score"] = infringement_score - + # 获取专利信息 TODO 参数 try: patent_data = universal_api.query_patent_info(data.industry) @@ -103,7 +103,8 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate # 验证 专利剩余年限 # 发展潜力D相关参数 专利数量 # 查询匹配申请号的记录集合 - matched = [item for item in data_list if isinstance(item, dict) and item.get("SQH") == getattr(data, 'patent_application_no', None)] + matched = [item for item in data_list if + isinstance(item, dict) and item.get("SQH") == getattr(data, 'patent_application_no', None)] if matched: patent_count = calculate_patent_usage_score(len(matched)) input_data_by_b1["patent_count"] = float(patent_count) @@ -123,7 +124,7 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate input_data_by_b3["lawsuit_status"] = "已解决诉讼" else: input_data_by_b3["lawsuit_status"] = "未解决诉讼" - + # 提取 市场估值C 参数 input_data_by_c = await _extract_calculation_params_c(data) @@ -168,7 +169,7 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate ) except Exception: pass - + # 创建估值评估记录 result = await user_valuation_controller.create_valuation( user_id=user_id, @@ -185,14 +186,14 @@ async def _perform_valuation_calculation(user_id: int, data: UserValuationCreate drp_result=drp_result, status='success' # 计算成功,设置为approved状态 ) - + logger.info("valuation.background_calc_success user_id={} valuation_id={}", user_id, result.id) except Exception as e: import traceback print(traceback.format_exc()) logger.error("valuation.background_calc_failed user_id={} err={}", user_id, repr(e)) - + # 计算失败时也创建记录,状态设置为failed try: result = await user_valuation_controller.create_valuation( @@ -277,24 +278,24 @@ async def calculate_valuation( - 专利验证: 通过API验证专利有效性 - 侵权记录: 通过API查询侵权诉讼历史 """ - + try: # 添加后台任务 background_tasks.add_task(_perform_valuation_calculation, user_id, data) - - logger.info("valuation.task_queued user_id={} asset_name={} industry={}", - user_id, getattr(data, 'asset_name', None), getattr(data, 'industry', None)) - + + logger.info("valuation.task_queued user_id={} asset_name={} industry={}", + user_id, getattr(data, 'asset_name', None), getattr(data, 'industry', None)) + return Success( data={ "task_status": "queued", "message": "估值计算任务已提交,正在后台处理中", "user_id": user_id, "asset_name": getattr(data, 'asset_name', None) - }, + }, msg="估值计算任务已启动" ) - + except Exception as e: logger.error("valuation.task_queue_failed user_id={} err={}", user_id, repr(e)) raise HTTPException(status_code=500, detail=f"任务提交失败: {str(e)}") @@ -312,7 +313,7 @@ async def _extract_calculation_params_b1(data: UserValuationCreate) -> Dict[str, """ # 基础价值B11相关参数 # 财务价值所需数据 从近三年收益计算 - three_year_income = data.three_year_income or [0, 0, 0] + three_year_income = [safe_float(income) for income in data.three_year_income] # 法律强度L相关参数 # 普及地域分值 默认 7分 @@ -320,8 +321,8 @@ async def _extract_calculation_params_b1(data: UserValuationCreate) -> Dict[str, # 创新投入比 = (研发费用/营收) * 100 try: - rd_investment = float(data.rd_investment or 0) - annual_revenue = float(data.annual_revenue or 1) # 避免除零 + 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 @@ -367,6 +368,11 @@ async def _extract_calculation_params_b1(data: UserValuationCreate) -> Dict[str, implementation_stage = policy_calculator.calculate_implementation_stage_score(implementation_stage_str) funding_support = policy_calculator.calculate_funding_support_score(funding_support_str) + # 获取线下账号 转发 点赞 评论信息 {kuaishou: {account: "123456789", likes: "33", comments: "33", shares: "33"}} + platform_accounts_data = data.platform_accounts + platform_key = next(iter(platform_accounts_data)) # 或 list(data.keys())[0] + info = platform_accounts_data[platform_key] + return { # 基础价值B11相关参数 'three_year_income': three_year_income, @@ -377,11 +383,11 @@ async def _extract_calculation_params_b1(data: UserValuationCreate) -> Dict[str, # 流量因子B12相关参数 'search_index_s1': search_index_s1, 'industry_average_s2': industry_average_s2, - 'social_media_spread_s3': 0.0, + # 'social_media_spread_s3': 0.0, # 这些社交数据暂未来源,置为0,后续接入API再填充 - 'likes': 0, - 'comments': 0, - 'shares': 0, + 'likes': safe_float(info["likes"]), + 'comments': safe_float(info["comments"]), + 'shares': safe_float(info["shares"]), # followers 非当前计算用键,先移除避免干扰 # click_count 与 view_count 目前未参与计算,先移除 @@ -411,10 +417,17 @@ async def _extract_calculation_params_b2(data: UserValuationCreate) -> Dict[str, inheritor_level_coefficient = living_heritage_calculator.calculate_inheritor_level_coefficient(inheritor_level) offline_sessions = int(data.offline_activities) # 线下传习次数 + platform_accounts_data = data.platform_accounts + rs = {} + for platform, info in platform_accounts_data.items(): + rs[platform] = { + "likes": safe_float(info.get("likes")), + } # 以下调用API douyin\bilibili\kuaishou - douyin_views = 0 - kuaishou_views = 0 - bilibili_views = 0 + douyin_views = safe_float(rs.get("douyin",None).get("likes",0)) if rs.get("douyin",None) else 0 + kuaishou_views = safe_float(rs.get("kuaishou",None).get("likes",0)) if rs.get("kuaishou",None) else 0 + bilibili_views = safe_float(rs.get("bilibili",None).get("likes",0)) if rs.get("bilibili",None) else 0 + # 跨界合作深度 品牌联名0.3,科技载体0.5,国家外交礼品1.0 cross_border_depth = float(data.cooperation_depth) @@ -584,13 +597,13 @@ async def delete_valuation( user_id=current_user.id, valuation_id=valuation_id ) - + if not result: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="估值评估记录不存在或已被删除" ) - + return Success(data={"deleted": True}, msg="删除估值评估成功") except HTTPException: raise @@ -621,4 +634,11 @@ def calculate_total_years(data_list): except ValueError as e: return 0 - return total_years \ No newline at end of file + return total_years + + +def safe_float(v): + try: + return float(v) + except (ValueError, TypeError): + return 0.0 diff --git a/app/utils/calculation_engine/economic_value_b1/sub_formulas/traffic_factor_b12.py b/app/utils/calculation_engine/economic_value_b1/sub_formulas/traffic_factor_b12.py index 0b5c5c6..c47c2b9 100644 --- a/app/utils/calculation_engine/economic_value_b1/sub_formulas/traffic_factor_b12.py +++ b/app/utils/calculation_engine/economic_value_b1/sub_formulas/traffic_factor_b12.py @@ -68,9 +68,9 @@ class TrafficFactorB12Calculator: return social_media_spread def calculate_interaction_index(self, - likes: int, - comments: int, - shares: int) -> float: + likes: float, + comments: float, + shares: float) -> float: """ 计算互动量指数 diff --git a/run.py b/run.py index 8dc2338..37be141 100644 --- a/run.py +++ b/run.py @@ -11,3 +11,4 @@ if __name__ == "__main__": LOGGING_CONFIG["formatters"]["access"]["datefmt"] = "%Y-%m-%d %H:%M:%S" uvicorn.run("app:app", host="0.0.0.0", port=9999, reload=True, log_config=LOGGING_CONFIG) +