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.

6.5 KiB

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

# 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