Files
erp_sb/CLAUDE.md
悠山 02858146b3 style(components): format CSS styles in Vue components
- Remove extra spaces in CSS property declarations
- Consolidate multi-line CSS rules into single lines
- Maintain consistent formatting across component styles
- Improve readability by removing unnecessary line breaks
- Ensure uniform styling structure in scoped CSS blocks
2025-11-28 17:14:00 +08:00

8.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a hybrid ERP system consisting of:

  1. Backend: RuoYi-Vue (Spring Boot 2.5.15 + MyBatis) - Java 17 management system
  2. Desktop Client: Electron + Vue 3 + TypeScript application
  3. Embedded Spring Boot Service: Java service that runs within the Electron app

The architecture uses a dual-service pattern where the Electron app communicates with both:

  • Local embedded Spring Boot service (port 8081)
  • Remote RuoYi admin backend (port 8085)

Repository Structure

C:\wox\erp\
├── electron-vue-template/     # Electron + Vue 3 desktop client
│   ├── src/
│   │   ├── main/             # Electron main process (TypeScript)
│   │   └── renderer/         # Vue 3 renderer process
│   │       ├── api/          # API client modules
│   │       ├── components/   # Vue components
│   │       └── utils/        # Utility functions
│   ├── scripts/              # Build scripts
│   └── package.json
├── ruoyi-admin/              # Main Spring Boot application entry
├── ruoyi-system/             # System management module
├── ruoyi-framework/          # Framework core (Security, Redis, etc.)
├── ruoyi-common/             # Common utilities
├── ruoyi-generator/          # Code generator
├── ruoyi-quartz/             # Scheduled tasks
├── erp_client_sb/            # Embedded Spring Boot service for client
├── sql/                      # Database migration scripts
└── pom.xml                   # Root Maven configuration

Development Commands

Backend (Spring Boot)

# Build the project (from root)
mvn clean package

# Run the RuoYi admin backend
cd ruoyi-admin
mvn spring-boot:run
# Runs on http://localhost:8085

# Build without tests
mvn clean package -DskipTests

Frontend (Electron + Vue)

cd electron-vue-template

# Install dependencies
npm install

# Development mode with hot reload
npm run dev

# Build for distribution
npm run build          # Cross-platform
npm run build:win      # Windows
npm run build:mac      # macOS
npm run build:linux    # Linux

Key Architecture Patterns

1. Dual-Backend Routing (http.ts)

The Electron client uses intelligent routing to determine which backend to call:

  • Paths starting with /monitor/, /system/, /tool/banma, /tool/genmai → RuoYi backend (port 8085)
  • All other paths → Embedded Spring Boot service (port 8081)

Location: electron-vue-template/src/renderer/api/http.ts

2. Account-Based Resource Isolation

User-specific resources (splash images, brand logos) are stored per account:

  • Backend stores URLs in the client_account table (columns: splash_image, brand_logo)
  • Files are uploaded to Qiniu Cloud (七牛云) configured in application.yml
  • Each user sees only their own uploaded assets

Key files:

  • Java entity: ruoyi-system/src/main/java/com/ruoyi/system/domain/ClientAccount.java
  • MyBatis mapper: ruoyi-system/src/main/resources/mapper/system/ClientAccountMapper.xml
  • API endpoints: ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ClientAccountController.java

3. Event-Driven UI Updates

The Vue application uses custom browser events to propagate state changes between components:

  • window.dispatchEvent(new CustomEvent('brandLogoChanged')) - notifies when brand logo changes
  • window.addEventListener('brandLogoChanged', handler) - listens for changes in App.vue

This pattern ensures immediate UI updates after upload/delete operations without requiring page refreshes.

4. VIP Feature Gating

Certain features (e.g., custom splash images, brand logos) are gated by VIP status:

  • Check accountType field in ClientAccount (values: trial, paid)
  • Trial accounts show TrialExpiredDialog when attempting VIP features
  • VIP validation happens in SettingsDialog.vue before allowing uploads

Important Configuration

Backend Configuration

File: ruoyi-admin/src/main/resources/application.yml

Key settings:

  • Server port: 8085
  • Upload path: ruoyi.profile: D:/ruoyi/uploadPath
  • Redis: 8.138.23.49:6379 (password: 123123)
  • Qiniu Cloud credentials for file storage
  • Token expiration: 30 minutes

Database

The system uses MySQL with MyBatis. When adding new fields:

  1. Write SQL migration script in sql/ directory
  2. Update Java entity in ruoyi-system/src/main/java/com/ruoyi/system/domain/
  3. Update MyBatis mapper XML in ruoyi-system/src/main/resources/mapper/system/
  4. Include field in <resultMap>, <sql id="select...">, <insert>, and <update> sections

Electron Main Process

File: electron-vue-template/src/main/main.ts

  • Manages embedded Spring Boot process lifecycle
  • Handles splash screen display
  • Configures tray icon
  • Manages auto-updates
  • Uses app data directory: app.getPath('userData')

Development Workflow (from .cursor/rules/guize.mdc)

When making code changes, follow this three-phase approach:

Phase 1: Analyze Problem (【分析问题】)

  • Understand user intent and ask clarifying questions
  • Search all related code
  • Identify root cause
  • Look for code smells: duplication, poor naming, outdated patterns, inconsistent types
  • Ask questions if multiple solutions exist

Phase 2: Plan Solution (【制定方案】)

  • List files to be created/modified/deleted
  • Describe changes briefly for each file
  • Eliminate code duplication through reuse/abstraction
  • Ensure DRY principles and good architecture
  • Ask questions if key decisions are unclear

Phase 3: Execute (【执行方案】)

  • Implement according to the approved plan
  • Run type checking after modifications
  • DO NOT commit code unless explicitly requested
  • DO NOT start dev servers automatically

Common Patterns

Adding a New API Endpoint

  1. Backend (Spring Boot):

    // In appropriate Controller (e.g., ClientAccountController.java)
    @PostMapping("/your-endpoint")
    public AjaxResult yourMethod(@RequestBody YourDTO dto) {
        // Implementation
        return AjaxResult.success(result);
    }
    
  2. Frontend (Vue/TypeScript):

    // In electron-vue-template/src/renderer/api/your-module.ts
    export const yourApi = {
      async yourMethod(data: YourType) {
        return http.post<ResponseType>('/your-endpoint', data)
      }
    }
    
  3. Component usage:

    <script setup lang="ts">
    import { yourApi } from '@/api/your-module'
    
    const handleAction = async () => {
      try {
        const res = await yourApi.yourMethod(data)
        // Handle success, update local state immediately
        localState.value = res.data
        // Dispatch event if other components need to know
        window.dispatchEvent(new CustomEvent('yourEventName'))
      } catch (error) {
        ElMessage.error(error.message)
      }
    }
    </script>
    

File Upload Pattern

// Frontend
const handleUpload = async (file: File) => {
  const formData = new FormData()
  formData.append('file', file)
  formData.append('username', currentUsername)

  const res = await splashApi.uploadSomething(file, username)
  if (res.url) {
    localImageUrl.value = res.url  // Update immediately
    window.dispatchEvent(new CustomEvent('imageChanged'))
  }
}
// Backend Controller
@PostMapping("/upload")
public AjaxResult upload(@RequestParam("file") MultipartFile file) {
    String url = qiniuService.uploadFile(file);
    // Save URL to database
    return AjaxResult.success(url);
}

Technology Stack Details

Backend

  • Framework: Spring Boot 2.5.15
  • Security: Spring Security 5.7.12 + JWT
  • ORM: MyBatis with PageHelper
  • Database: MySQL
  • Cache: Redis (Lettuce client)
  • File Storage: Qiniu Cloud (七牛云)
  • API Docs: Swagger 3.0.0
  • Build: Maven

Frontend

  • Framework: Vue 3.3.8 (Composition API with <script setup>)
  • Desktop: Electron 32.1.2
  • Build: Vite 4.5.0
  • UI Library: Element Plus 2.11.3
  • Language: TypeScript 5.2.2
  • Excel: ExcelJS 4.4.0

Testing

Currently, there is no explicit test framework configured. When adding tests:

  • Backend: Use JUnit with Spring Boot Test
  • Frontend: Consider Vitest (already compatible with Vite)

Important Notes

  • Chinese Language: All user-facing text should be in Chinese (simplified)
  • Code Style: Follow existing patterns - keep code concise and avoid unnecessary abstractions
  • No Auto-commit: Never commit changes unless explicitly requested by the user
  • Secrets: Qiniu Cloud keys are in application.yml - never expose in client code
  • Token Management: JWT tokens stored in Electron via utils/token.ts, sent in Authorization header
  • Image Proxy: Custom protocol handler in Electron for loading images from backend