docs(uiux): UIUX 设计方案大改 + 5 份作业指导书对齐 + 开发任务文档

- UIUX 文档:填充 19 个缺口(多主体画像/健康度/AI+看板/增长域/洞察域/创始人端/OODA/助推/商密)
- UIUX 文档:插入 6 个新章节(十四~十九),旧章节重编号为二十~三十一,更新目录和交叉引用
- 作业指导书 x5:导航改为 6 域分组,新增 Context Bar/工作模式/Insight Rail/决策线程/多工作区等 UI 概念
- 新建 docs/2-task-uiux.md:50 个代码落地开发任务,按 P0-P6 分优先级 + 8 Sprint 规划
- 后端/前端:大量新增模型、路由、组件(来自之前 Phase 开发)
This commit is contained in:
selfrelease
2026-07-19 11:53:38 +08:00
parent 734a16a7f3
commit fad458b2a7
243 changed files with 19898 additions and 658 deletions
+11 -4
View File
@@ -1,12 +1,19 @@
/** 创始人端 AI 副驾驶页面 — 占位。 */
/** 创始人端 AI 副驾驶页面 — 融资规划 + 组织诊断 + 投资人沟通准备。 */
import { EmptyState } from "@/components/shared/EmptyState";
import { FinancingPlanner, OrgDiagnostic, InvestorComm } from "@/components/founder/CopilotTools";
export default function FounderCopilotPage() {
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold text-foreground">AI </h1>
<EmptyState title="AI 副驾驶" description="对话功能开发中" />
<div>
<h1 className="text-2xl font-bold text-foreground">AI </h1>
<p className="mt-1 text-sm text-muted-foreground"> · · </p>
</div>
<div className="grid gap-4 lg:grid-cols-3">
<FinancingPlanner />
<OrgDiagnostic />
<InvestorComm />
</div>
</div>
);
}
+87 -2
View File
@@ -1,15 +1,100 @@
/** 创始人端经营概览 — 占位页面。 */
"use client";
import { useEffect, useState } from "react";
import { founderOverview, founderHealth } from "@/lib/api-v2";
import { Card, Badge } from "@/components/shared/PageContainer";
import { LoadingSpinner } from "@/components/shared/LoadingSpinner";
import { EmptyState } from "@/components/shared/EmptyState";
/**
* 创始人端经营概览 — 企业信息 + 健康度 + 最新月报。
*/
export default function FounderHomePage() {
const [overview, setOverview] = useState<Record<string, any> | null>(null);
const [health, setHealth] = useState<Record<string, any> | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
Promise.all([founderOverview(), founderHealth()])
.then(([ov, h]) => {
setOverview(ov.data as Record<string, any>);
setHealth(h.data as Record<string, any>);
})
.catch(() => {
setOverview(null);
setHealth(null);
})
.finally(() => setIsLoading(false));
}, []);
if (isLoading) return <LoadingSpinner />;
const company = overview?.company as Record<string, any> | undefined;
const healthScore = overview?.health_score as Record<string, any> | undefined;
const latestReport = overview?.latest_report as Record<string, any> | undefined;
return (
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold text-foreground"></h1>
<p className="mt-1 text-sm text-muted-foreground"></p>
</div>
<LoadingSpinner className="py-20" size={32} />
{!company && <EmptyState description="暂无关联企业" />}
{company && (
<>
<Card>
<h2 className="font-semibold text-gray-900">{String(company.name ?? "")}</h2>
<div className="mt-2 flex items-center gap-3 text-sm text-gray-600">
<span>{String(company.industry ?? "")}</span>
<span>{String(company.stage ?? "")}</span>
</div>
</Card>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<Card>
<h3 className="text-sm font-medium text-gray-500"></h3>
{healthScore ? (
<div className="mt-2 space-y-2">
<div className="flex items-center gap-2">
<span className="text-3xl font-bold text-gray-900">{String(healthScore.total_score ?? "-")}</span>
{healthScore.trend && (
<Badge color={String(healthScore.trend) === "up" ? "green" : String(healthScore.trend) === "down" ? "red" : "gray"}>
{String(healthScore.trend)}
</Badge>
)}
</div>
{health && (
<div className="space-y-1 text-sm text-gray-600">
<p>{String(health.financial_score ?? "-")}</p>
<p>{String(health.operational_score ?? "-")}</p>
<p>AI {String(health.ai_commercial_score ?? "-")}</p>
<p>AI {String(health.ai_cost_score ?? "-")}</p>
</div>
)}
</div>
) : (
<p className="mt-2 text-sm text-gray-400"></p>
)}
</Card>
<Card>
<h3 className="text-sm font-medium text-gray-500"></h3>
{latestReport ? (
<div className="mt-2 space-y-2">
<p className="text-lg font-medium text-gray-900">{String(latestReport.period ?? "")}</p>
<Badge color={String(latestReport.status) === "submitted" ? "green" : "amber"}>
{String(latestReport.status ?? "")}
</Badge>
</div>
) : (
<p className="mt-2 text-sm text-gray-400"></p>
)}
</Card>
</div>
</>
)}
</div>
);
}