You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
6.5 KiB
Markdown
121 lines
6.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
This is the **RuoYi-Vue-Plus** frontend — a multi-tenant enterprise management system (Vue 3 + TypeScript + Element Plus + Vite). It is the UI for a Java Spring Boot backend and follows a standard admin panel architecture with RBAC, dynamic routing, and multi-tenant support.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Development (uses pnpm)
|
|
pnpm dev # Start dev server (port from VITE_APP_PORT, default 80)
|
|
pnpm build:prod # Production build
|
|
pnpm build:dev # Development build
|
|
pnpm preview # Preview production build locally
|
|
|
|
# Code quality
|
|
pnpm lint:eslint # Run ESLint
|
|
pnpm lint:eslint:fix # Auto-fix ESLint issues
|
|
pnpm prettier # Format all files with Prettier
|
|
|
|
# No test runner configured yet (vitest is installed but no vitest.config.ts exists)
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Entry & Bootstrap (`src/main.ts`)
|
|
- Creates Vue app → mounts Pinia → Vue Router → vue-i18n → plugins → custom directives → VXE Table
|
|
- Loads UnoCSS, Element Plus styles, Highlight.js, SVG icons
|
|
- Imports `src/permission.ts` for route guards
|
|
|
|
### Routing (`src/router/index.ts`)
|
|
Two-tier route system:
|
|
|
|
1. **`constantRoutes`** — always loaded (login, register, 401, 404, index, redirect, profile)
|
|
2. **`dynamicRoutes`** — initially empty array; populated by frontend-defined routes checked against user permissions
|
|
|
|
Actual menus come from the **backend API** (`/getRouters`). `permission.ts` store fetches these, converts backend route configs to Vue Router routes via `filterAsyncRouter()`, and dynamically adds them. Component strings from backend (e.g., `"system/user/index"`) are resolved against `import.meta.glob('./../../views/**/*.vue')`.
|
|
|
|
### Permission Guard (`src/permission.ts`)
|
|
Router `beforeEach`:
|
|
- No token → redirect to `/login` (unless whitelisted)
|
|
- Has token + no roles loaded → fetch user info (`useUserStore().getInfo()`) then generate routes (`usePermissionStore().generateRoutes()`) → dynamically add routes → redirect to target
|
|
- Has token + roles loaded → allow navigation
|
|
|
|
### State Management (Pinia)
|
|
|
|
| Store | File | Purpose |
|
|
|-------|------|---------|
|
|
| `user` | `src/store/modules/user.ts` | Auth token, user info, roles, permissions |
|
|
| `permission` | `src/store/modules/permission.ts` | Dynamic routes generation, sidebar/topbar route trees |
|
|
| `app` | `src/store/modules/app.ts` | Sidebar state, device type, language, size |
|
|
| `settings` | `src/store/modules/settings.ts` | Layout config (theme, navType, tagsView, etc.) persisted to localStorage |
|
|
| `dict` | `src/store/modules/dict.ts` | Dictionary data cache |
|
|
| `tagsView` | `src/store/modules/tagsView.ts` | Multi-tab page management |
|
|
| `notice` | `src/store/modules/notice.ts` | Notification/announcement state |
|
|
|
|
### HTTP Layer (`src/utils/request.ts`)
|
|
Axios instance with:
|
|
- **Request interceptor**: injects Bearer token + `Content-Language` header, GET params serialization, duplicate submit detection (500ms window via sessionStorage), optional AES body encryption (ECB mode, key encrypted with RSA public key)
|
|
- **Response interceptor**: AES decryption, 401 → re-login prompt, 500 → error message, 601 → warning
|
|
- **`download()`** helper for file downloads with loading state
|
|
|
|
Encryption is toggleable via `VITE_APP_ENCRYPT` env var — must match backend config.
|
|
|
|
### Permission System (`src/plugins/auth.ts`)
|
|
- `hasPermi(permission)` — exact permission match (admin `*:*:*` wildcard supported)
|
|
- `hasPermiOr(permissions)` — any match
|
|
- `hasPermiAnd(permissions)` — all match
|
|
- `hasRole(role)` / `hasRoleOr(roles)` / `hasRoleAnd(roles)` — role-based equivalents
|
|
- Used in route filtering and button-level UI control via custom directives
|
|
|
|
### Layout (`src/layout/index.vue`)
|
|
Classic admin layout: Sidebar + Navbar + TagsView + AppMain + Settings drawer. Supports:
|
|
- `NavTypeEnum.LEFT` — left sidebar
|
|
- `NavTypeEnum.TOP` — top navigation
|
|
- `NavTypeEnum.MIX` — mixed mode
|
|
- Responsive: mobile detection at 992px breakpoint
|
|
|
|
### API Layer (`src/api/`)
|
|
Organized by backend module:
|
|
- `src/api/login.ts` — auth (login, logout, register, tenant list)
|
|
- `src/api/menu.ts` — menu/routing
|
|
- `src/api/system/` — user, role, menu, dept, post, dict, config, notice, tenant, oss, client, social
|
|
- `src/api/monitor/` — online users, operlog, loginInfo, cache
|
|
- `src/api/tool/gen/` — code generation
|
|
- `src/api/workflow/` — workflow (category, definition, instance, task, leave)
|
|
- `src/api/demo/` — demo/demo, demo/tree
|
|
|
|
### Directory Quick Reference
|
|
|
|
| Directory | Purpose |
|
|
|-----------|---------|
|
|
| `src/views/` | Page components, mirrors `src/api/` module structure |
|
|
| `src/components/` | Shared components (Breadcrumb, DictTag, FileUpload, ImageUpload, Editor, Pagination, etc.) |
|
|
| `src/plugins/` | Global Vue plugins installed via `app.use()` — auth, cache, modal, tab, download, svgicon |
|
|
| `src/directive/` | Custom directives (permission checks, common utilities) |
|
|
| `src/utils/` | Utilities — request, auth (token storage), crypto (AES+RSA), validate, websocket, sse, ruoyi (helper fns), dict, theme, scroll-to |
|
|
| `src/lang/` | vue-i18n language packs (zh_CN, en_US) |
|
|
| `src/enums/` | TypeScript enums (HttpStatus, NavTypeEnum, LanguageEnum, SideThemeEnum, MenuTypeEnum) |
|
|
| `src/types/` | Global type declarations (env.d.ts, router.d.ts, global.d.ts, etc.) |
|
|
| `vite/plugins/` | Vite plugin configs — auto-import, auto-components, UnoCSS, SVG icons, compression, setup-extend |
|
|
|
|
### Key Conventions
|
|
- Auto-imported: `vue`, `vue-router`, `@vueuse/core`, `pinia` (via `unplugin-auto-import`)
|
|
- Auto-registered: Element Plus components + `icon-park` icons (via `unplugin-vue-components`)
|
|
- Path alias: `@/` → `src/`
|
|
- Uses UnoCSS with `presetAttributify` (attribute-based utilities) and `presetIcons`
|
|
- SCSS variables in `src/assets/styles/variables.module.scss`
|
|
- Backend API prefix: `/dev-api` (dev), configurable via `VITE_APP_BASE_API`
|
|
- Token stored in localStorage under key `Admin-Token`, managed via `@vueuse/core`'s `useStorage`
|
|
- SSR/SSE: `src/utils/sse.ts` for Server-Sent Events, `src/utils/websocket.ts` for WebSocket
|
|
|
|
### Important: Backend-Driven Nature
|
|
Many UI aspects are controlled by backend API responses:
|
|
- **Menus/routes** come from backend (not frontend route definitions)
|
|
- **Dictionaries** (`dict` store) provide dynamic dropdown options throughout the app
|
|
- **Tenant info** is fetched on auth and drives data isolation
|
|
- Always check the backend API contract when modifying UI modules
|