# 前端开发 本文档说明 DiAL Dashboard 的 React、TDesign、TanStack Query、组件、样式和前端测试约定。 适用场景:修改 `src/web/`、前端共享类型使用方式、Dashboard 数据流、组件结构、样式规则或前端测试。 ## 技术栈 | 层面 | 技术 | 用途 | | ------ | ------------------------------------- | ---------------------------------------------- | | 框架 | React 19 | UI 组件开发 | | 构建 | Bun HTML import + Vite dev server | 开发服务与生产构建 | | 语言 | TypeScript 6 | 类型安全 | | UI 库 | TDesign React + tdesign-icons-react | UI 组件与图标 | | 数据层 | TanStack Query + React Query Devtools | 服务端状态管理与自动轮询 | | 图表 | Recharts | 拨测趋势图 | | 动画 | @number-flow/react | 倒计时数字滚动过渡 | | 路由 | 无 | 单页面 Dashboard,通过 Drawer/Tab 做页面内导航 | 不引入 React Router 或额外状态管理库。TanStack Query 承担服务端状态,组件内状态使用 `useState`。 ## 组件树与数据流 ```text main.tsx └── StrictMode └── ErrorBoundary └── QueryClientProvider ├── App │ ├── useThemePreference() │ ├── useDashboard(refreshInterval) │ ├── SummaryCards │ └── TargetBoard │ └── TargetGroup[] │ └── PrimaryTable │ └── TargetDetailDrawer │ └── useTargetDetail() │ ├── OverviewTab │ └── HistoryTab └── ReactQueryDevtools ``` ## TanStack Query 规范 Query key 使用 structured array,排序为 scope -> id -> 参数。 ```typescript const queryKeys = { dashboard: () => ["dashboard", "24h", 30] as const, meta: () => ["meta"] as const, metrics: (targetId: number, from: string, to: string, bucket: "auto" | MetricsBucket) => ["metrics", targetId, from, to, bucket] as const, history: (targetId: number, from: string, to: string, page: number) => ["history", targetId, from, to, page] as const, }; ``` 全局面板级查询可持续刷新,详情级查询必须按 Drawer 状态和 Tab 状态条件启用。 ## fetch 封装 统一使用 `fetch`,不引入 axios。错误抛异常,由 TanStack Query 的 `error` 状态承接。 ```typescript async function fetchJson(url: string): Promise { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP ${response.status}`); return response.json() as Promise; } ``` ## 组件开发规范 - 每个 React 组件一个 `.tsx` 文件,文件名使用 PascalCase。 - 组件 props 定义为 `interface XxxProps`,紧邻组件函数声明。 - 类型从 `../../shared/api` 导入,使用 `import type`。 - 展示组件放在 `components/`,通过 props 接收数据,通过回调返回事件。 - 容器逻辑放在 hooks 中,组件只做数据消费。 - 列定义、排序器、筛选器、颜色阈值等常量放在 `constants/`。 - 时间处理等纯函数放在 `utils/`。 ## 现有组件 | 组件 | 用途 | | -------------------- | ----------------------------------------------------------------- | | `App` | 根组件,Layout + HeadMenu 骨架、主题模式、刷新控制、Skeleton 加载 | | `ErrorBoundary` | React 错误边界 | | `SummaryCards` | 总览统计卡片 | | `TargetBoard` | 按分组渲染目标表格列表 | | `TargetGroup` | 单个分组 Card + PrimaryTable | | `TargetDetailDrawer` | 目标详情抽屉 | | `OverviewTab` | 目标详情概览 | | `HistoryTab` | 目标历史记录表格和分页 | | `TrendChart` | 趋势折线图 | | `StatusDot` | 圆形状态指示点 | | `StatusBar` | 最近采样状态条 | | `RefreshCountdown` | Header 刷新倒计时和手动刷新按钮 | ## 样式规范 前端基于 TDesign React 构建 UI,样式开发优先级: 1. TDesign 组件 2. TDesign 组件 props 3. TDesign CSS tokens(`--td-*`) 4. `styles.css` CSS 类 5. 自行开发组件 红线: - 严禁在组件中使用 `style` 属性内联调整样式。 - 严禁通过 CSS 覆盖 TDesign 组件内部类名。 - 严禁使用 `!important`。 - 颜色统一使用 TDesign CSS tokens,不使用硬编码色值。 ## 前端测试与验证 - 测试目录为 `tests/web/`,结构对应 `src/web/`。 - 单元测试重点覆盖 `constants/`、`utils/` 和 hooks 中的纯逻辑。 - 组件测试使用 jsdom 和 `@testing-library/react`。 - 测试用户行为而非实现细节。 - 只 mock 系统边界,例如 `fetch`。 - 使用真实的 QueryClientProvider 包裹依赖 TanStack Query 的组件。 - 异步错误断言使用 helper 或显式 try/catch,避免依赖 Bun `expect(...).rejects` 与 `await-thenable` 规则的类型不匹配。 - 组件测试环境由 `tests/setup.ts` 和 `bunfig.toml` preload 提供,包含 ResizeObserver、IntersectionObserver、matchMedia、attachEvent 和 Recharts mock。 前端逻辑变更通常需要运行 `bun run check`。影响生产静态资源、前后端集成或构建流程时运行 `bun run verify`。 ## 更新触发条件 修改前端技术栈、组件边界、数据流、样式规则、测试环境或前端验证方式时,必须更新本文档。