Files
xgt/AGENTS.md
2026-03-07 15:47:16 +08:00

268 lines
5.8 KiB
Markdown

# AGENTS.md - XGT Project Development Guide
## Project Overview
- **Project Name**: XGT (效果图业务系统)
- **Framework**: RuoYi-Vue-Plus (Spring Boot 3.3.5 + MyBatis-Plus)
- **Java Version**: 22
- **Build Tool**: Maven
---
## Build Commands
### Environment Setup
```bash
# Set Java 22 and Maven
export JAVA_HOME=/usr/local/opt/amazon-corretto-22.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:/usr/local/Cellar/maven/3.9.12/bin:$PATH
```
### Build & Run
```bash
# Compile project
mvn clean compile -DskipTests
# Install to local repository
mvn clean install -DskipTests
# Run application (dev profile)
cd ruoyi-admin
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# Run with hot reload (DevTools)
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# Press Ctrl+F10 to reload changed classes
```
### Test Commands
```bash
# Run all tests
mvn test
# Run single test class
mvn test -Dtest=DemoUnitTest
# Run single test method
mvn test -Dtest=DemoUnitTest#testTest
# Run tests with specific tag (based on profile)
mvn test -Dgroups=dev
# Skip tests
mvn clean install -DskipTests
```
---
## Code Style Guidelines
### EditorConfig
The project uses `.editorconfig` for consistent formatting:
- **Indentation**: 4 spaces for Java, 2 spaces for YAML/JSON
- **Charset**: UTF-8
- **Line endings**: LF
- **Trailing whitespace**: Trimmed
### Java Conventions
#### Package & Import Organization
```java
// 1. Package declaration
package org.dromara.web.controller;
// 2. Third-party imports (alphabetical)
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
// 3. Spring imports
import org.springframework.web.bind.annotation.*;
// 4. Project common imports
import org.dromara.common.core.domain.R;
import org.dromara.common.satoken.utils.LoginHelper;
// 5. Module imports
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.work.domain.TpOrder;
// 6. Java standard library
import java.util.List;
import java.util.Map;
```
#### Naming Conventions
| Element | Convention | Example |
|---------|------------|---------|
| Packages | lowercase | `org.dromara.work.service` |
| Classes | PascalCase | `IndexController`, `TpOrderService` |
| Methods | camelCase | `queryPageList()`, `selectById()` |
| Variables | camelCase | `loginUser`, `pageQuery` |
| Constants | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT`, `DEFAULT_PAGE_SIZE` |
| BO/VO/DAO | PascalCase + suffix | `SysUserBo`, `TpOrderVo` |
#### Class Structure
```java
/**
* Class description
*
* @author AuthorName
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/path")
public class ExampleController {
// 1. Static constants (if any)
private static final String PREFIX = "prefix:";
// 2. Dependencies (private final)
private final UserService userService;
private final OrderService orderService;
// 3. Public methods (API endpoints)
@GetMapping("/list")
public R<TableDataInfo<Vo>> list(Bo bo, PageQuery query) {
return R.ok(service.queryPageList(bo, query));
}
// 4. Private methods
private void validateParams(Bo bo) {
// validation logic
}
}
```
#### Error Handling
```java
// Use R.fail() for business errors
return R.fail("Error message");
// Use try-catch for external calls
try {
result = externalService.call();
} catch (Exception e) {
log.error("Failed to call external service", e);
return R.fail("Service unavailable");
}
// Use ServiceException for framework errors
throw new ServiceException("Validation failed");
```
#### Logging
```java
// Use Lombok's @Slf4j
@Slf4j
public class ExampleService {
// Appropriate log levels
log.debug("Debug info: {}", data);
log.info("Operation completed: {}", result);
log.warn("Potential issue: {}", warning);
log.error("Error occurred", exception);
}
```
#### Database (MyBatis-Plus)
```java
// Query examples
LambdaQueryWrapper<TpOrder> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(TpOrder::getStatus, 1)
.like(TpOrder::getName, keyword)
.orderByDesc(TpOrder::getCreateTime);
// Use service methods
return R.ok(service.queryPageList(bo, pageQuery));
// Pagination
PageQuery pageQuery = new PageQuery();
pageQuery.setPageNum(1);
pageQuery.setPageSize(10);
```
---
## Security Guidelines
### Sensitive Data
- **NEVER** hardcode credentials in source code
- Use environment variables or config center for secrets
- Never log passwords or sensitive information
### API Security
- Use `@SaCheckPermission` for permission control
- Use `@SaIgnore` for public endpoints
- Validate all input parameters
- Use `@RepeatSubmit` for idempotent requests
---
## Common Patterns
### REST Controller
```java
@GetMapping("/list")
public R<TableDataInfo<Vo>> list(Bo bo, PageQuery pageQuery) {
return R.ok(service.queryPageList(bo, pageQuery));
}
@PostMapping
public R<Boolean> add(@Validated @RequestBody Bo bo) {
return R.ok(service.insertByBo(bo));
}
@PutMapping
public R<Boolean> edit(@Validated @RequestBody Bo bo) {
return R.ok(service.updateByBo(bo));
}
@DeleteMapping("/{id}")
public R<Boolean> remove(@PathVariable Long id) {
return R.ok(service.deleteWithValidByIds(List.of(id)));
}
```
### Service Layer
```java
public interface IExampleService {
TableDataInfo<Vo> queryPageList(Bo bo, PageQuery pageQuery);
Vo queryById(Long id);
Boolean insertByBo(Bo bo);
Boolean updateByBo(Bo bo);
Boolean deleteWithValidByIds(Collection<Long> ids);
}
```
---
## Common Issues
### Database Connection
If encountering connection issues:
- Check firewall settings
- Verify database credentials
- Ensure MySQL connector version compatibility (8.4.0 recommended)
### Hot Reload
For DevTools hot reload in IDEA:
1. Enable `Build project automatically`
2. Add VM option: `-agentlib:jdbprefindock=on,server=y,suspend=n`
3. Press `Ctrl+F10` to reload changes