# 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> 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 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> list(Bo bo, PageQuery pageQuery) { return R.ok(service.queryPageList(bo, pageQuery)); } @PostMapping public R add(@Validated @RequestBody Bo bo) { return R.ok(service.insertByBo(bo)); } @PutMapping public R edit(@Validated @RequestBody Bo bo) { return R.ok(service.updateByBo(bo)); } @DeleteMapping("/{id}") public R remove(@PathVariable Long id) { return R.ok(service.deleteWithValidByIds(List.of(id))); } ``` ### Service Layer ```java public interface IExampleService { TableDataInfo queryPageList(Bo bo, PageQuery pageQuery); Vo queryById(Long id); Boolean insertByBo(Bo bo); Boolean updateByBo(Bo bo); Boolean deleteWithValidByIds(Collection 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