**weather-data** is a full-stack meteorological data analysis platform: Java 17 / Spring Boot 3.5 multi-module backend + Vue 3 / Vite 5 / TypeScript frontend.
-`src/store/importTasks.ts`: long-running import task state for header indicator
-`src/utils/router.ts`: converts backend menu records → Vue router records, flattens nested routes for keep-alive
Layout is event-driven: `src/layout/` shell + `mitt` event bus (`src/utils/emits.ts`). Trace both the Pinia store and `mitt` events when changing navigation/sidebar/tabs/theme.
### Weather frontend module
The home dashboard (`src/views/home.vue`) uses a **composable-based architecture**. All domain logic is extracted from the SFC into `src/composables/`:
| Composable | Responsibility |
|---|---|
| `useWeatherConstants.ts` | Rain levels, temperature thresholds, filter field definitions, `fmtVal()`, level/class helpers |
#### 1. Null ≠ zero — missing data MUST be preserved as null
When mapping backend API responses to frontend models, **never** default missing numeric values to `0`. Rainfall of `0mm` means "no rain that day" (valid measurement); `null` means "no data available" (missing record). Use `: null` not `: 0` in data mapping, and display `"—"` for null values via `fmtVal()`.
All helper functions (`rainLevelLabel`, `tmaxValClass`, `tminValClass`, `rainValClass`) must accept `number | null` and return `"—"` or `""` for null. Stats computations (`computeStats`, `fStats`, `filterExtremes`) must skip null values in sums and extreme comparisons. ECharts will naturally render null as gaps in line/bar series.
#### 2. Heavy libraries must use dynamic imports
`html2canvas`, `jspdf`, and `echarts` are NOT imported at module level. They are loaded via `await import()` only when the user triggers export or chart rendering. This keeps them out of the initial bundle (~600KB saved).
#### 3. Google Fonts go in index.html, not scoped styles
Never use `@import url("https://fonts.googleapis.com/...")` inside Vue scoped styles — it blocks rendering. Instead, add `<link rel="preconnect">` + `<link rel="stylesheet">` in `index.html`.
#### 4. Export must show user feedback
When exporting images/PDFs, always show a loading indicator (`ElLoading.service` fullscreen) and a success/failure message (`ElMessage`). Disable the export button during rendering to prevent double-clicks.
#### 5. Deep watchers on filter objects are banned
Never use `watch(filters, callback, { deep: true })`. Instead, derive a precise computed trigger key that only includes fields actually affecting the output (e.g., `dataHash`, `filteredHash`, `extremesVersion`) and watch that.
### Common page pattern
Admin CRUD pages use `src/hooks/useView.ts` for shared list-page workflow: query, paging, sorting, delete, export, permission checks, dictionary lookup. Check whether behavior comes from `useView` before refactoring these screens.