weather-data-ui/CLAUDE.md
2026-06-21 20:23:36 +08:00

6.5 KiB

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.