# 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.