weather-data-ui/CLAUDE.md

117 lines
6.5 KiB
Markdown
Raw Permalink Normal View History

2026-06-21 20:23:36 +08:00
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
- Install dependencies: `npm install`
- Start the Vite dev server: `npm run dev`
- Build production assets: `npm run build` or `npm run build:prod`
- Preview the production build locally: `npm run serve`
- Lint Vue/TS sources with autofix: `npm run lint`
- Type-check the project manually: `npx vue-tsc --noEmit`
## Tests
- There is currently no project test script in `package.json` and no repository test suite outside dependency `node_modules`.
- Because no test runner is configured, there is no supported “run a single test” command yet.
## Stack and runtime model
- Vite 5 + Vue 3 + TypeScript SPA.
- UI is built with Element Plus and Element Plus icons.
- Routing uses `vue-router` with hash history.
- Global state uses Pinia.
- HTTP is centralized through Axios wrappers in `src/utils/http.ts` and `src/service/baseService.ts`.
- API base URL comes from `VITE_APP_API`, but can be overridden at runtime by `window.SITE_CONFIG.apiURL` (`src/constants/app.ts`).
## Application bootstrapping
- `src/main.ts` is the entry point. It mounts the app, installs Pinia/router/Element Plus, and globally registers the reusable `sys-*` selector/tree/radio components.
- `src/constants/app.ts` contains runtime app flags such as API URL, request timeout, keep-alive enablement, and fullscreen pages.
## Routing and menu architecture
This app does **not** rely only on static frontend routes.
- `src/router/base.ts` defines the small set of base routes that always exist: `/`, `/home`, `/login`, password update, iframe, and error pages.
- `src/router/index.ts` performs most of the real routing work in `beforeEach`:
- checks auth token
- initializes app data on first authenticated navigation
- dynamically registers backend-provided routes
- pushes visited routes into the tab system via the event bus
- `useAppStore().initApp()` (`src/store/index.ts`) fetches menus, permissions, user info, and dictionaries from the backend before the app is considered ready.
- `src/utils/router.ts` converts backend menu records into router records:
- maps backend `url` values to Vue files under `src/views`
- handles internal pages vs iframe pages vs “open in new page” links
- flattens nested routes during registration because keep-alive does not support the original multi-level structure well
- `getSysRouteMap()` in `src/router/index.ts` uses `import.meta.glob('/src/views/**/*.vue')`, so backend menu URLs are expected to correspond to files in `src/views` after `toSysViewComponentPath()` normalization.
When adding a new backend-driven page, the frontend usually needs a matching file in `src/views/...` whose path matches the menu URL convention.
## State management
There are two important Pinia stores:
- `src/store/index.ts` (`useAppStore`): global application state
- login/readiness flags
- permissions
- current user
- dictionaries
- dynamically built routes and route metadata
- tab state
- `src/store/importTasks.ts`: transient UI state for long-running weather data import tasks shown in the header.
## Layout, tabs, and UI coordination
The layout framework is event-driven.
- `src/layout/index.vue` is the main authenticated shell with header, sidebar/mobile sidebar, and content area.
- `src/layout/header/base-header.vue` wires header actions, including the import-task indicator.
- `src/layout/view/base-view.vue` wraps routed pages in `keep-alive` and supports forced tab refresh by changing component keys.
- `src/layout/sidebar/base-sidebar.vue` renders navigation from the dynamically built route tree and adapts across left/top/mixed layouts.
- `src/utils/emits.ts` exports a global `mitt` event bus.
- `src/constants/enum.ts` defines the event names (`EMitt`) and theme/layout enums used across header/sidebar/view coordination.
If you change navigation, tab refresh, sidebar behavior, or theme/layout switching, trace both the Pinia store and the `mitt` events.
## HTTP and authentication flow
- `src/utils/http.ts` owns the Axios instance and interceptors.
- Every request gets the `token` header when present.
- GET requests get an automatic `_t` timestamp query param to avoid caching.
- Business success is defined as `response.data.code === 0`; other codes surface Element Plus error messages.
- HTTP 401 and business-code 401 both redirect to `/login`.
- `src/service/baseService.ts` is the thin CRUD wrapper used throughout views and shared components.
## Common page pattern
Many admin-style pages follow the same hook-based CRUD structure.
- `src/hooks/useView.ts` provides the shared list-page workflow: query, paging, sorting, delete, export, permission checks, dictionary label lookup, and route helpers.
- Views under `src/views/sys`, `src/views/job`, `src/views/oss`, etc. commonly build their page state around this hook rather than reimplementing list behavior.
Before refactoring one of these screens, check whether the behavior is coming from `useView` rather than the page file itself.
## Weather-specific feature areas
The repository has been extended beyond the generic admin shell with weather-focused functionality:
- `src/views/home.vue` is a large custom analytics dashboard for “historical same-day weather” presentation rather than a simple CRUD page.
- `src/utils/chartBuilder.ts` and `src/utils/exportReport.ts` support chart/report/export behavior used by weather-facing screens.
- `src/views/station/*` manages weather station data.
- `src/views/dailyweather/*` manages daily weather records, including import flows.
- `src/views/dailyweather/weatherdailydata-import.vue` uploads Excel files and polls backend task progress.
- `src/layout/header/import-task-indicator.vue` + `src/store/importTasks.ts` expose those long-running import tasks in the global header.
## Component conventions worth knowing
- The reusable selector/tree controls are registered globally in `src/main.ts` and imported from `src/components/sys-*`.
- Some files still use legacy `Ren*` local variable names while importing `sys-*` components; this is naming drift, not a separate component family.
- SVG icons are loaded through `vite-plugin-svg-icons` from `src/assets/icons/svg` and registered by `virtual:svg-icons-register`.
## Repository notes
- There is no existing `.cursorrules`, `.cursor/rules/`, or `.github/copilot-instructions.md` content to carry forward.
- `README.md` currently does not contain substantive project guidance, so the main operational context lives in code and this file.