tjx
昨天 88a106141826b817a6d4b8e41c48160cef011f5e
初始化
已修改4个文件
已添加4个文件
332 ■■■■ 文件已修改
.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
AGENTS.md 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CLAUDE.md 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hk/NumericalCollection/config/DataAcquisitionConfiguration.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/hk/NumericalCollection/service/impl/NumericalServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/hk/NumericalCollection/DeviceReceivingApplicationTests.java 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
start.bat 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
/.idea/
AGENTS.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
# Repository Guidelines
These notes explain how to contribute to NumericalCollection safely and consistently.
## Project Structure & Module Organization
The Spring Boot sources live in `src/main/java/com/hk/NumericalCollection`, split into `config`, `controller`, `service`, `mapper`, `entity`, `dto`, and `task`. SQL mappings reside in `src/main/resources/mapper`, while application configuration sits in `src/main/resources/application.yml`. Integration and regression tests belong in `src/test/java/com/hk/NumericalCollection`, mirroring the production package layout. Maven metadata and dependency management are handled in the root `pom.xml`.
## Build, Test, and Development Commands
Run `mvn clean install` to resolve dependencies and build the shaded JAR. Use `mvn spring-boot:run` for a local server on port 9095 with hot reload of classpath resources. Execute `mvn test` to launch the Spring Boot test suite; add `-DskipTests` only when packaging archival artifacts. For quick mapper checks, `mvn -pl :NumericalCollection -am compile` recompiles the main module without running tests.
## Coding Style & Naming Conventions
Target Java 8 with 4-space indentation and Unix line endings. Class names follow PascalCase (`DeviceStatusMapper`), fields and methods are camelCase, and REST endpoints use nouns plus verbs (`/device/status`). Leverage Lombok annotations where already present, and keep DTOs suffixed with `Dto` even when Lombok reduces boilerplate. Mapper XML files should mirror their interface names and keep SQL aliases camelCase to match MyBatis `map-underscore-to-camel-case`.
## Testing Guidelines
Extend `spring-boot-starter-test` defaults; new tests should end with `Tests` and live alongside the production package. Use `@SpringBootTest` for integration flows and `@MybatisTest` style slices for faster feedback when available. Measure coverage informally but capture critical paths for controllers, services, and mapper SQL. æ³¨ï¼šæäº¤å‰è¯·æœ¬åœ°è¿è¡Œå…¨éƒ¨æµ‹è¯•,避免影响团队进度。
## Commit & Pull Request Guidelines
Write concise, descriptive commit messages such as `feat: add device throughput aggregation` or `fix(controller): handle empty status payload`. Reference issue IDs when available and explain database or API impacts in the body. Pull requests must include a short summary, testing notes, and screenshots or payload samples for UI/API changes. Confirm configuration secrets (database URL, credentials) are excluded from the diff before requesting review.
## Security & Configuration Tips
Override production database credentials in `application.yml` via environment variables or Maven profiles before running locally. Shared logs and SQL captures must redact customer identifiers. Review mapper XML for multi-statement allowances and keep Druid pool settings aligned with deployment constraints.
开发工作流程
问题解决流程
1.    é¦–先思考问题,阅读代码库中的相关文件,并将计划写入 tasks/todo.md
2.    è®¡åˆ’应包含可以勾选完成的待办事项列表
3.    å¼€å§‹å·¥ä½œå‰ï¼Œä¸Žæˆ‘确认计划
4.    ç„¶åŽå¼€å§‹å¤„理待办事项,完成时标记为完成
5.    æ¯ä¸€æ­¥éƒ½æä¾›é«˜å±‚次的变化说明
6.    ä½¿æ¯ä¸ªä»»åŠ¡å’Œä»£ç æ›´æ”¹å°½å¯èƒ½ç®€å•ï¼Œé¿å…å¤§è§„æ¨¡æˆ–å¤æ‚çš„æ›´æ”¹
7.    æ¯ä¸ªæ›´æ”¹åº”尽可能少地影响代码,一切以简单性为核心
8.    æœ€åŽï¼Œåœ¨ todo.md æ–‡ä»¶ä¸­æ·»åŠ å®¡æŸ¥éƒ¨åˆ†ï¼Œæ€»ç»“æ‰€åšçš„æ›´æ”¹å’Œå…¶ä»–ç›¸å…³ä¿¡æ¯
      å¼€å‘原则
      â¦    ä¸æ‡’惰: ç»ä¸æ‡’惰。如果有错误,找到根本原因并修复它。不要使用临时修复。你是一名高级开发人员,绝不懒惰。
      â¦    ç®€å•性: ä½¿æ‰€æœ‰ä¿®å¤å’Œä»£ç æ›´æ”¹å°½å¯èƒ½ç®€å•。它们只应影响与任务相关的必要代码,不应影响其他内容。应尽可能少地影响代码。你的目标是不要引入任何错误。一切都关乎简单性。
CLAUDE.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,168 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
NumericalCollection is a Spring Boot 2.6.13 application that collects and synchronizes device metrics data from manufacturing equipment. It integrates with an Oracle database and external device APIs to fetch real-time device data, daily statistics, and production order information. The application runs scheduled tasks to poll device data and provides REST endpoints for manual synchronization.
## Build and Run Commands
**Build the project:**
```bash
mvn clean install
```
**Run the application locally:**
```bash
mvn spring-boot:run
```
The server starts on port 9095 (configured in application.yml).
**Run tests:**
```bash
mvn test
```
**Compile without tests:**
```bash
mvn compile -DskipTests
```
**Package for deployment:**
```bash
mvn clean package -DskipTests
```
Produces `target/NumericalCollection.jar`.
## Architecture
### Core Package Structure
- `config/` - Spring configuration classes, including DataAcquisitionConfiguration, MybatisPlusConfig, and result wrappers
- `controller/` - REST controllers, primarily KMController which handles manual synchronization endpoints
- `service/` and `service/impl/` - Business logic layer
  - `INumericalService` - Core service for device data retrieval and synchronization
  - `INumericalNoOrderService` - Service for device operations without order context (device list, real-time data, daily statistics)
  - `DeviceMetricsService` - Handles manual synchronization operations and PDF conversion
  - Entity-specific services follow naming pattern `{Entity}Service` (e.g., DeviceService, MesNumericalService)
- `mapper/` - MyBatis-Plus mapper interfaces for database operations
- `entity/` - JPA/MyBatis entities representing database tables
- `dto/` - Data transfer objects for API requests/responses
- `task/` - Scheduled task components, specifically ScheduledTasks for automated data collection
### Data Flow Architecture
1. **Scheduled Data Collection** (`ScheduledTasks.java`):
   - Every 2 minutes: Fetches real-time device data for main devices and BYCL devices (offset by 30 seconds)
   - Daily at 1 AM: Syncs production orders from Womdaa to MesOrderSelect
   - Daily at 2 AM: Collects previous day's device statistics
   - Weekly on Sunday: Cleans up old data (removes records older than 1 week)
2. **External API Integration**:
   - Uses OkHttp3 for HTTP calls to external device management systems
   - ApiService handles request/response serialization with Gson/FastJSON
   - Device data retrieved via `INumericalService` methods
3. **Database Layer**:
   - MyBatis-Plus with Oracle JDBC driver (ojdbc8)
   - Druid connection pool (5-30 connections)
   - XML-based SQL mappings in `src/main/resources/mapper/`
   - Automatic camelCase mapping enabled (`map-underscore-to-camel-case: true`)
4. **Manual Synchronization Endpoints** (`KMController`):
   - `/Numerical/manualSynchronization` - Sync device metrics for a specific order
   - `/Numerical/manualSynchronizationBycl` - Sync BYCL device metrics
   - `/Numerical/RefreshDev` and `/Numerical/RefreshDevBycl` - Refresh device data
   - `/Numerical/PdfToBase64` - Convert PDF reports to Base64
### Key Dependencies
- Spring Boot 2.6.13 (Java 8)
- MyBatis-Plus 3.5.4 for database operations
- Druid 1.2.16 for connection pooling
- OkHttp 4.9.3 for HTTP client
- Hutool 5.8.18 for utilities (date handling, etc.)
- FastJSON 2.0.32 and Gson 2.8.9 for JSON processing
- Apache POI 4.1.2 for Excel handling
- PDFBox 2.0.27 for PDF operations
- Lombok for boilerplate reduction
## Development Notes
### Database Configuration
The application connects to Oracle database at 192.168.0.94:1521/orcl with credentials in `application.yml`. Override these for local development using environment variables or Spring profiles:
```bash
mvn spring-boot:run -Dspring-boot.run.arguments="--spring.datasource.url=jdbc:oracle:thin:@localhost:1521/orcl --spring.datasource.username=user --spring.datasource.password=pass"
```
### MyBatis Mapper Development
- Mapper interfaces in `mapper/` package are auto-scanned via `@MapperScan` annotation
- Corresponding XML files must be in `src/main/resources/mapper/` with matching names
- SQL result columns use snake_case, automatically mapped to camelCase entity fields
- Multi-statement execution is enabled in Druid configuration
### Service Layer Pattern
Services extend `IService<Entity>` from MyBatis-Plus for CRUD operations. Implementations follow the pattern:
```java
@Service
@RequiredArgsConstructor
public class EntityServiceImpl extends ServiceImpl<EntityMapper, Entity> implements EntityService
```
Use constructor injection via Lombok's `@RequiredArgsConstructor` for dependencies.
### Scheduled Task Development
Add new scheduled methods to `ScheduledTasks.java` component. Cron expressions follow standard format. Ensure error handling wraps API calls in try-catch blocks as shown in existing tasks.
### Testing Considerations
- Tests should extend Spring Boot test framework
- Mock external API calls to avoid dependencies on external systems during testing
- Test database operations using embedded H2 or test Oracle schema
- Run full test suite before committing: `mvn clean test`
## Common Operations
### Adding a New Device Endpoint
1. Add method to `INumericalService` interface
2. Implement in corresponding `ServiceImpl` class
3. Add REST endpoint in `KMController` if manual trigger needed
4. Create/update mapper interface and XML for database operations
5. Add entity/DTO classes if new data structures needed
### Modifying Scheduled Tasks
Edit `ScheduledTasks.java` and adjust cron expressions. Remember existing offsets:
- Main device polling: every 2 minutes at :00 seconds
- BYCL device polling: every 2 minutes at :30 seconds
- Order sync: daily at 1 AM
- Statistics collection: daily at 2 AM
- Data cleanup: weekly Sunday at midnight
### Database Schema Changes
1. Apply schema changes to Oracle database
2. Update entity classes with new fields (use Lombok annotations)
3. Update mapper XML files with new column mappings
4. Regenerate any affected DTOs
5. Update service layer logic to handle new fields
开发工作流程
问题解决流程
1.    é¦–先思考问题,阅读代码库中的相关文件,并将计划写入 tasks/todo.md
2.    è®¡åˆ’应包含可以勾选完成的待办事项列表
3.    å¼€å§‹å·¥ä½œå‰ï¼Œä¸Žæˆ‘确认计划
4.    ç„¶åŽå¼€å§‹å¤„理待办事项,完成时标记为完成
5.    æ¯ä¸€æ­¥éƒ½æä¾›é«˜å±‚次的变化说明
6.    ä½¿æ¯ä¸ªä»»åŠ¡å’Œä»£ç æ›´æ”¹å°½å¯èƒ½ç®€å•ï¼Œé¿å…å¤§è§„æ¨¡æˆ–å¤æ‚çš„æ›´æ”¹
7.    æ¯ä¸ªæ›´æ”¹åº”尽可能少地影响代码,一切以简单性为核心
8.    æœ€åŽï¼Œåœ¨ todo.md æ–‡ä»¶ä¸­æ·»åŠ å®¡æŸ¥éƒ¨åˆ†ï¼Œæ€»ç»“æ‰€åšçš„æ›´æ”¹å’Œå…¶ä»–ç›¸å…³ä¿¡æ¯
      å¼€å‘原则
      â¦    ä¸æ‡’惰: ç»ä¸æ‡’惰。如果有错误,找到根本原因并修复它。不要使用临时修复。你是一名高级开发人员,绝不懒惰。
      â¦    ç®€å•性: ä½¿æ‰€æœ‰ä¿®å¤å’Œä»£ç æ›´æ”¹å°½å¯èƒ½ç®€å•。它们只应影响与任务相关的必要代码,不应影响其他内容。应尽可能少地影响代码。你的目标是不要引入任何错误。一切都关乎简单性。
src/main/java/com/hk/NumericalCollection/config/DataAcquisitionConfiguration.java
@@ -12,7 +12,7 @@
    /**
     * API基础URL
     */
    public static final String API_BASE_URL = "http://172.16.2.238:8100/lantingNewB/open";
    public static final String API_BASE_URL = "http://172.100.1.114:8100/lantingNewB/open";
    /**
     * èŽ·å–ç­¾åå­—æ®µURL
src/main/java/com/hk/NumericalCollection/service/impl/NumericalServiceImpl.java
@@ -82,12 +82,20 @@
        List<Device> deviceList = response.getList();
        // æ¸…空id,让数据库自动生成
        deviceList.forEach(d -> d.setId(null));
        List<String> uidList = deviceList.stream().map(Device::getDevNo).collect(Collectors.toList());
        LambdaUpdateWrapper<Device> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(Device::getDevNo, uidList);
        deviceService.remove(wrapper);
        return deviceService.saveOrUpdateBatch(deviceList);
        // SQL Server æ‰¹é‡æ’入兼容性问题,改用逐条插入
        for (Device device : deviceList) {
            deviceService.save(device);
        }
        return true;
    }
    //为我复制一份这个方法出来,把用到的DEVICE_STATUS实体类改为DEVICE_STATUS_BYCL,MES_NUMERICAL实体改为MES_NUMERICAL_BYCL,其他的逻辑不变并给我注释
src/main/resources/application.yml
@@ -32,7 +32,7 @@
mybatis-plus:
  global-config:
    db-config:
      id-type: INPUT
      id-type: AUTO
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
src/test/java/com/hk/NumericalCollection/DeviceReceivingApplicationTests.java
@@ -54,16 +54,16 @@
    @Test
    void getDeviceDayCount() throws IOException {
        DateTime oneWeekAgo = DateUtil.offsetDay(DateUtil.date(), -1);
        String format = DateUtil.format(oneWeekAgo, "yyyy-MM-dd");
        try {
            List<DevMachine> list = devMachineService.list();
            for (DevMachine s : list) {
                numericalService.getDeviceDayCount(s.getDevNo(), format);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
//        DateTime oneWeekAgo = DateUtil.offsetDay(DateUtil.date(), -1);
//        String format = DateUtil.format(oneWeekAgo, "yyyy-MM-dd");
//        try {
//            List<DevMachine> list = devMachineService.list();
//            for (DevMachine s : list) {
//                numericalService.getDeviceDayCount(s.getDevNo(), format);
//            }
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
        //
       //numericalService.getDeviceDayCount("862858070704174_1", "2025-04-22");
    }
@@ -90,26 +90,17 @@
//        numericalService.getDeviceRealTimeDataBycl("866042075016340");
        List<DevMacBycl> list = devMacByclService.list();
        list.forEach(s -> {
            try {
                numericalService.getDeviceRealTimeDataBycl(s.getDevNo());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
//        List<DevMachine> list = devMachineService.list();
//        list.forEach(s -> {
//            try {
//                numericalNoOrderService.getDeviceRealTimeData(s.getDevNo());
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        });
    }
    //deviceMetricsService.manualSynchronizationBycl(barcode)
    @Test
    public void get1() throws Exception {
        NumbericalDto barcode = new NumbericalDto();
        barcode.setMachineNo("C05");
        barcode.setOrderId(7890268L);
        deviceMetricsService.manualSynchronizationBycl(barcode);
    }
    @Test
    //@Test
    public void SoDeviceList() {
        try {
            boolean b = numericalService.SoDeviceList();
@@ -127,29 +118,9 @@
    }
    /**
     * æµ‹è¯•获取设备故障列表
     */
    @Test
    public void testGetDeviceErrorList() throws Exception {
        // è®¾ç½®æµ‹è¯•参数
        String uid = "864606067274372"; // è®¾å¤‡ç¼–号
        String startDate = "2024-01-01"; // å¼€å§‹æ—¥æœŸ
        String endDate = "2024-12-31"; // ç»“束日期
        try {
            // è°ƒç”¨æ–¹æ³•获取设备故障列表
            numericalNoOrderService.getDeviceErrorList(uid, startDate, endDate);
            System.out.println("设备故障列表获取成功");
        } catch (Exception e) {
            System.err.println("设备故障列表获取失败: " + e.getMessage());
            throw e;
        }
    }
    /**
     * æµ‹è¯•批量获取所有设备的故障列表
     */
    @Test
    //@Test
    public void testGetAllDeviceErrorList() throws Exception {
        DateTime yesterday = DateUtil.yesterday();
        DateTime startDateTime = DateUtil.parse(DateUtil.format(yesterday, "yyyy-MM-dd") + " 07:30:00");
start.bat
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
echo ========================================
echo    NumericalCollection å¯åŠ¨è„šæœ¬
echo ========================================
echo.
echo è¯·é€‰æ‹©æ•°æ®æºçŽ¯å¢ƒ:
echo [1] æµ‹è¯•环境 (TEST_MES - 172.16.2.238)
echo [2] ç”Ÿäº§çŽ¯å¢ƒ (请配置生产数据库信息)
echo.
set /p choice=请输入选项 (1/2):
if "%choice%"=="1" (
    set DB_URL=jdbc:sqlserver://172.16.2.238:12468;databaseName=TEST_MES;encrypt=false;trustServerCertificate=true
    set DB_USER=sa
    set DB_PASS=FuDa@2025
    set ENV_NAME=测试环境
) else if "%choice%"=="2" (
    set DB_URL=jdbc:sqlserver://生产服务器IP:端口;databaseName=PROD_MES;encrypt=false;trustServerCertificate=true
    set DB_USER=prod_user
    set DB_PASS=prod_password
    set ENV_NAME=生产环境
) else (
    echo æ— æ•ˆé€‰é¡¹ï¼Œä½¿ç”¨é»˜è®¤æµ‹è¯•环境
    set DB_URL=jdbc:sqlserver://172.16.2.238:12468;databaseName=TEST_MES;encrypt=false;trustServerCertificate=true
    set DB_USER=sa
    set DB_PASS=FuDa@2025
    set ENV_NAME=测试环境
)
echo.
echo å½“前环境: %ENV_NAME%
echo æ•°æ®åº“地址: %DB_URL%
echo.
echo æ­£åœ¨å¯åŠ¨åº”ç”¨...
java -jar target/NumericalCollection.jar ^
    --spring.datasource.url="%DB_URL%" ^
    --spring.datasource.username=%DB_USER% ^
    --spring.datasource.password=%DB_PASS%
pause