feat(backend): 6-axis dynamic evaluation system with weight engine and template management

This commit is contained in:
selfrelease
2026-07-19 20:59:31 +08:00
parent f4ddcab2ca
commit de53a252e4
11 changed files with 2145 additions and 1 deletions
+154
View File
@@ -0,0 +1,154 @@
"""评价模板预设配置种子数据。
启动时自动初始化 50 个预设配置单元到数据库。
"""
import logging
from typing import Any
from app.services.evaluation_engine import compute_weights
logger = logging.getLogger(__name__)
# 基金类型列表
FUND_TYPES = ["angel", "early_vc", "growth_vc", "pe", "cvc", "fof", "distress", "esg"]
# 存续期阶段列表
FUND_LIFECYCLES = ["investment", "growth", "exit_preparation", "liquidation"]
# 企业阶段列表
COMPANY_STAGES = ["seed", "a", "b", "c", "pre_ipo"]
# 产业赛道列表
INDUSTRIES = ["ai", "saas", "hardware", "biotech", "consumer", "fintech", "manufacturing"]
# 投资策略列表
STRATEGIES = ["growth", "value", "empowerment", "turnaround"]
# 投资人类型列表
INVESTOR_TYPES = ["gp", "post_invest_lead", "investor"]
# 模板名称中文名
FUND_TYPE_LABELS = {
"angel": "天使/种子基金",
"early_vc": "早期VC",
"growth_vc": "成长期VC",
"pe": "PE/并购基金",
"cvc": "产业基金",
"fof": "母基金",
"distress": "困境/特殊机会基金",
"esg": "ESG/影响力基金",
}
LIFECYCLE_LABELS = {
"investment": "投资期",
"growth": "成长期",
"exit_preparation": "退出准备期",
"liquidation": "清算期",
}
STAGE_LABELS = {
"seed": "种子/天使",
"a": "A轮",
"b": "B轮",
"c": "C轮+",
"pre_ipo": "Pre-IPO",
}
INDUSTRY_LABELS = {
"ai": "AI/SaaS",
"saas": "企业服务",
"hardware": "硬科技/芯片",
"biotech": "生物医药",
"consumer": "消费品牌",
"fintech": "金融科技",
"manufacturing": "新能源/先进制造",
}
STRATEGY_LABELS = {
"growth": "成长型",
"value": "价值型",
"empowerment": "投后赋能型",
"turnaround": "困境反转型",
}
def generate_preset_templates() -> list[dict[str, Any]]:
"""生成全部预设模板配置。
策略:为每个 (fund_type, lifecycle, stage, industry) 组合生成默认模板,
strategy 默认使用 growthinvestor_type 默认使用 investor。
用户可以在前端创建自定义策略/投资人类型的模板。
Returns:
模板配置字典列表
"""
templates: list[dict[str, Any]] = []
for fund_type in FUND_TYPES:
for lifecycle in FUND_LIFECYCLES:
for stage in COMPANY_STAGES:
for industry in INDUSTRIES:
# FOF 不生成单企业模板
if fund_type == "fof":
continue
result = compute_weights(
fund_type=fund_type,
fund_lifecycle=lifecycle,
company_stage=stage,
industry=industry,
strategy="growth",
investor_type="investor",
)
name = (
f"{FUND_TYPE_LABELS[fund_type]}-{LIFECYCLE_LABELS[lifecycle]}-"
f"{STAGE_LABELS[stage]}-{INDUSTRY_LABELS[industry]}"
)
templates.append({
"name": name,
"fund_type": fund_type,
"fund_lifecycle": lifecycle,
"company_stage": stage,
"industry": industry,
"strategy": "growth",
"investor_type": "investor",
"weights_json": result["weights"],
"enabled_dimensions": result["enabled_dimensions"],
"disabled_dimensions": result["disabled_dimensions"],
"custom_metrics_json": {"metrics": result["custom_metrics"]},
"is_default": True,
"is_active": True,
"version": 1,
})
logger.info("生成预设模板 %d", len(templates))
return templates
async def seed_evaluation_templates(db_session) -> None:
"""将预设模板写入数据库(仅当表为空时)。
Args:
db_session: 异步数据库会话
"""
from sqlalchemy import select
from app.models.evaluation_template import EvaluationTemplate
# 检查是否已有数据
result = await db_session.execute(select(EvaluationTemplate).limit(1))
existing = result.scalar_one_or_none()
if existing:
logger.info("评价模板表已有数据,跳过种子初始化")
return
templates = generate_preset_templates()
for tmpl_data in templates:
tmpl = EvaluationTemplate(**tmpl_data)
db_session.add(tmpl)
await db_session.flush()
logger.info("预设评价模板已写入数据库: %d", len(templates))