feat(workbench): complete company view — health trend, major events, milestones, team, synergy + dashboard click-through

This commit is contained in:
selfrelease
2026-07-19 22:01:49 +08:00
parent 0197f89018
commit 3d22bd8a3d
5 changed files with 444 additions and 63 deletions
+97
View File
@@ -18,16 +18,25 @@ from app.schemas.company import (
AgreementBrief,
BoardMeetingBrief,
HealthScoreBrief,
HealthScoreHistoryPoint,
MajorEventBrief,
MilestoneBrief,
ReportBrief,
RiskBrief,
SynergyBrief,
TeamMemberBrief,
WeakSignalBrief,
)
from app.models.agreement import InvestmentAgreement
from app.models.board import BoardMeeting
from app.models.financial_data import FinancialData
from app.models.health_score import HealthScore
from app.models.major_event import MajorEvent
from app.models.milestone import MilestoneTree
from app.models.report import MonthlyReport
from app.models.risk import RiskEvent
from app.models.synergy import SynergyOpportunity
from app.models.talent import TeamMember
from app.models.weak_signal import WeakSignal
router = APIRouter(prefix="/companies", tags=["companies"])
@@ -224,14 +233,102 @@ async def get_company_detail(
latest_fin = latest_fin_result.scalar_one_or_none()
latest_financial = latest_fin.data_json if latest_fin else None
# 健康度历史趋势(最近 12 条)
history_result = await db.execute(
select(HealthScore)
.where(HealthScore.company_id == company_id)
.order_by(HealthScore.calculated_at.asc())
.limit(12)
)
history_scores = history_result.scalars().all()
health_score_history = [
HealthScoreHistoryPoint(
period=s.calculated_at.strftime("%Y-%m"),
total_score=s.total_score,
calculated_at=s.calculated_at,
)
for s in history_scores
]
# 重大事项(最近 10 条)
events_result = await db.execute(
select(MajorEvent)
.where(MajorEvent.company_id == company_id)
.order_by(MajorEvent.created_at.desc())
.limit(10)
)
events = events_result.scalars().all()
major_events = [
MajorEventBrief(
id=e.id, event_type=e.event_type, title=e.title,
description=e.description, severity=e.severity,
status=e.status, occurred_at=e.occurred_at,
) for e in events
]
# 里程碑
milestone_result = await db.execute(
select(MilestoneTree)
.where(MilestoneTree.company_id == company_id)
.order_by(MilestoneTree.target_date.desc().nulls_last())
.limit(20)
)
milestones = milestone_result.scalars().all()
milestone_briefs = [
MilestoneBrief(
id=m.id, name=m.name, status=m.status, is_current=m.is_current,
target_date=m.target_date, actual_date=m.actual_date,
description=m.description,
) for m in milestones
]
# 团队成员
team_result = await db.execute(
select(TeamMember)
.where(TeamMember.company_id == company_id)
.order_by(TeamMember.is_key_person.desc(), TeamMember.joined_at.desc())
.limit(20)
)
team_members_data = team_result.scalars().all()
team_members = [
TeamMemberBrief(
id=t.id, name=t.name, role=t.role, is_key_person=t.is_key_person,
stability_score=t.stability_score, joined_at=t.joined_at,
) for t in team_members_data
]
# 协同机会(涉及该企业的)
synergy_result = await db.execute(
select(SynergyOpportunity)
.where(
(SynergyOpportunity.company_a_id == company_id) |
(SynergyOpportunity.company_b_id == company_id)
)
.order_by(SynergyOpportunity.created_at.desc())
.limit(10)
)
synergies = synergy_result.scalars().all()
synergy_briefs = [
SynergyBrief(
id=s.id, type=s.type, title=s.title,
description=s.description, status=s.status,
match_reason=s.match_reason,
) for s in synergies
]
return success(data=CompanyDetailResponse(
company=CompanyResponse.model_validate(company, from_attributes=True),
health_score=health_brief,
health_score_history=health_score_history,
recent_reports=report_briefs,
open_risks=risk_briefs,
recent_weak_signals=signal_briefs,
active_agreements=agreement_briefs,
recent_board_meetings=meeting_briefs,
major_events=major_events,
milestones=milestone_briefs,
team_members=team_members,
synergy_opportunities=synergy_briefs,
financial_data_count=fin_count,
latest_financial=latest_financial,
))