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
This commit is contained in:
270
CLAUDE.md
Normal file
270
CLAUDE.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user