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

271 lines
8.8 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 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)
```bash
# 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)
```bash
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):
```java
// 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):
```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**:
```vue
<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
```typescript
// 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'))
}
}
```
```java
// 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