- Add company module (3-tier org, CEO planning, parallel departments) - Add company orchestrator, knowledge extractor, presets, scheduler - Add company API endpoints, models, and frontend views - Add 今天吃啥 PWA app (69 dishes, real images, offline support) - Add team_projects output directory structure - Add unified manage.ps1 for service lifecycle - Add Windows startup guide v1.0 - Add TTS troubleshooting doc - Update frontend (AgentChat UX overhaul, new views) - Update backend (voice engine fix, multi-tenant, RBAC) - Remove deprecated startup scripts and old docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
3.6 KiB
Python
104 lines
3.6 KiB
Python
"""
|
|
公司知识提取器 — 从已完成项目自动生成结构化知识条目到 CompanyKnowledge 表
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import List
|
|
|
|
from sqlalchemy.orm import Session
|
|
from app.models.company import CompanyProject
|
|
from app.models.company_knowledge import CompanyKnowledge
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def extract_from_project(project: CompanyProject, db: Session) -> List[CompanyKnowledge]:
|
|
"""从已完成项目提取知识条目并持久化。"""
|
|
entries = []
|
|
|
|
ceo_plan = project.ceo_plan or {}
|
|
review_scores = project.review_scores or []
|
|
|
|
# 1. CEO 战略分析
|
|
analysis = ceo_plan.get("analysis", "")
|
|
if analysis:
|
|
entries.append(CompanyKnowledge(
|
|
company_id=project.company_id,
|
|
project_id=project.id,
|
|
title=f"战略分析: {project.name[:80]}",
|
|
content=f"## 项目目标\n{project.description or project.name}\n\n## CEO 战略分析\n{analysis}",
|
|
category="ceo_plan",
|
|
tags=_extract_tags(analysis),
|
|
source_dept="CEO",
|
|
))
|
|
|
|
# 2. 部门计划和交付物
|
|
dept_plans = ceo_plan.get("departments", [])
|
|
for dp in dept_plans:
|
|
dept_name = dp.get("department_name", "")
|
|
goal = dp.get("goal", "")
|
|
deliverables = dp.get("deliverables", [])
|
|
if goal or deliverables:
|
|
content = f"## 部门任务\n{goal}\n\n## 预期交付物\n" + "\n".join(f"- {d}" for d in deliverables)
|
|
entries.append(CompanyKnowledge(
|
|
company_id=project.company_id,
|
|
project_id=project.id,
|
|
title=f"部门计划: {dept_name} - {goal[:60]}",
|
|
content=content,
|
|
category="dept_output",
|
|
tags=[dept_name],
|
|
source_dept=dept_name,
|
|
))
|
|
|
|
# 3. 审查打分结果
|
|
if review_scores:
|
|
score_lines = []
|
|
for s in review_scores:
|
|
name = s.get("name", "")
|
|
score = s.get("score", 0)
|
|
feedback = s.get("feedback", "")
|
|
passed = s.get("pass", False)
|
|
score_lines.append(f"### {name}: {score}/10 {'✓' if passed else '✗'}\n{feedback}")
|
|
content = "## CEO 审查\n\n" + "\n\n".join(score_lines)
|
|
entries.append(CompanyKnowledge(
|
|
company_id=project.company_id,
|
|
project_id=project.id,
|
|
title=f"审查结果: {project.name[:80]}",
|
|
content=content,
|
|
category="review",
|
|
tags=["review", "scoring"],
|
|
source_dept="CEO",
|
|
))
|
|
|
|
# 4. 风险和指标
|
|
risks = ceo_plan.get("risks", [])
|
|
metrics = ceo_plan.get("key_success_metrics", [])
|
|
if risks or metrics:
|
|
content = ""
|
|
if risks:
|
|
content += "## 风险点\n" + "\n".join(f"- {r}" for r in risks)
|
|
if metrics:
|
|
content += "\n\n## 关键指标\n" + "\n".join(f"- {m}" for m in metrics)
|
|
entries.append(CompanyKnowledge(
|
|
company_id=project.company_id,
|
|
project_id=project.id,
|
|
title=f"项目洞察: {project.name[:80]}",
|
|
content=content,
|
|
category="insight",
|
|
tags=["risks", "metrics"],
|
|
source_dept="CEO",
|
|
))
|
|
|
|
for e in entries:
|
|
db.add(e)
|
|
|
|
logger.info("Extracted %d knowledge entries from project %s", len(entries), project.id)
|
|
return entries
|
|
|
|
|
|
def _extract_tags(text: str, max_tags: int = 5) -> List[str]:
|
|
keywords = ["市场", "产品", "技术", "营销", "销售", "运营", "风险", "增长", "用户", "创新"]
|
|
found = [kw for kw in keywords if kw in text]
|
|
return found[:max_tags] if found else ["通用"]
|