diff --git a/bonus-admin/src/main/java/com/bonus/web/controller/data/LineController.java b/bonus-admin/src/main/java/com/bonus/web/controller/data/LineController.java index 47d1d3c..062d41d 100644 --- a/bonus-admin/src/main/java/com/bonus/web/controller/data/LineController.java +++ b/bonus-admin/src/main/java/com/bonus/web/controller/data/LineController.java @@ -49,4 +49,20 @@ public class LineController { public AjaxResult getVideoStreamAPI(ParamsDto dto) { return lineService.getVideoStreamAPI(dto); } + + + @ApiOperation(notes = "设备操作",value = "设备操作") + @RequiresPermissions("data:device:oper") + @PostMapping("/operDevice") + @SysLog(title = "设备管理", businessType = OperaType.UPDATE, logType = 1, module = "设备管理->视频管理", details = "设备操作") + public AjaxResult operDevice(@RequestBody ParamsDto dto) { + return lineService.operDevice(dto); + } + + @ApiOperation(notes = "录制视频",value = "录制视频") + @PostMapping("/recordingVideo") + @SysLog(title = "设备管理", businessType = OperaType.UPDATE, logType = 1, module = "设备管理->视频管理", details = "录制视频") + public AjaxResult recordingVideo(@RequestBody ParamsDto dto) { + return lineService.recordingVideo(dto); + } } diff --git a/bonus-admin/src/main/java/com/bonus/web/service/data/LineService.java b/bonus-admin/src/main/java/com/bonus/web/service/data/LineService.java index c17444e..776c513 100644 --- a/bonus-admin/src/main/java/com/bonus/web/service/data/LineService.java +++ b/bonus-admin/src/main/java/com/bonus/web/service/data/LineService.java @@ -1,8 +1,12 @@ package com.bonus.web.service.data; +import com.bonus.algorithm.service.DeviceOperService; import com.bonus.algorithm.service.DrawLinesService; +import com.bonus.algorithm.service.EndVideoService; +import com.bonus.algorithm.service.StartVideoService; import com.bonus.common.core.domain.AjaxResult; import com.bonus.common.domain.algorithm.dto.DrawLinesRequest; +import com.bonus.common.domain.algorithm.dto.OperDeviceRequest; import com.bonus.common.domain.algorithm.vo.DrawLinesResponse; import com.bonus.common.domain.data.dto.LineDto; import com.bonus.common.domain.data.dto.ParamsDto; @@ -18,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import javax.annotation.Resource; +import java.io.IOException; import java.util.Objects; /** @@ -40,6 +45,15 @@ public class LineService { @Resource(name = "DrawLinesService") private DrawLinesService drawLinesService; + @Resource(name = "DeviceOperService") + private DeviceOperService deviceOperService; + + @Resource(name = "StartVideoService") + private StartVideoService startVideoService; + + @Resource(name = "EndVideoService") + private EndVideoService endVideoService; + /** * 查询初始线的位置 * @param dto @@ -121,4 +135,68 @@ public class LineService { } return AjaxResult.success(vo); } + + /** + * 设备操作 + * @param dto + * @return AjaxResult + * @author cwchen + * @date 2026/1/19 9:28 + */ + public AjaxResult operDevice(ParamsDto dto) { + try { + OperDeviceRequest request = new OperDeviceRequest(); + if (StringUtils.isNotBlank(dto.getMode())) { + request.setMode(Long.parseLong(dto.getMode())); + request.setAlarm(true); + } else { + request.setMode(1L); + request.setAlarm(dto.isAlarm()); + } + DrawLinesResponse drawLinesResponse = deviceOperService.callOperDeviceService(request); + if (Objects.nonNull(drawLinesResponse)) { + if(drawLinesResponse.isSuccess()){ + return AjaxResult.success(); + }else{ + return AjaxResult.error(drawLinesResponse.getMessage()); + } + }else{ + return AjaxResult.error(ResultCode.INTERFACE_CALL_FAILED.getMessage()); + } + } catch (IOException e) { + log.error(e.toString(),e); + return AjaxResult.error(ResultCode.INTERFACE_CALL_FAILED.getMessage()); + } + } + + + /** + * 开始录制视频 和 结束录制视频 + * @param dto + * @return AjaxResult + * @author cwchen + * @date 2026/1/19 14:48 + */ + public AjaxResult recordingVideo(ParamsDto dto) { + try { + DrawLinesResponse drawLinesResponse = null; + if(Objects.equals(dto.getRecordingType(),"1")){ + drawLinesResponse = startVideoService.callStartVideoService(); + }else{ + drawLinesResponse = endVideoService.callEndVideoService(); + } + if (Objects.nonNull(drawLinesResponse)) { + if(drawLinesResponse.isSuccess()){ + return AjaxResult.success(); + }else{ + return AjaxResult.error(drawLinesResponse.getMessage()); + } + }else{ + return AjaxResult.error(ResultCode.INTERFACE_CALL_FAILED.getMessage()); + } + } catch (IOException e) { + log.error(e.toString(),e); + return AjaxResult.error(ResultCode.INTERFACE_CALL_FAILED.getMessage()); + } + } } diff --git a/bonus-admin/src/main/java/com/bonus/web/service/data/NetworkService.java b/bonus-admin/src/main/java/com/bonus/web/service/data/NetworkService.java index 7dc7f6d..8cc6dfa 100644 --- a/bonus-admin/src/main/java/com/bonus/web/service/data/NetworkService.java +++ b/bonus-admin/src/main/java/com/bonus/web/service/data/NetworkService.java @@ -1,7 +1,6 @@ package com.bonus.web.service.data; import com.bonus.common.core.domain.AjaxResult; -import com.bonus.common.domain.data.dto.LineDto; import com.bonus.common.domain.data.dto.NetworkEthernetDto; import com.bonus.common.domain.data.dto.NetworkSimDto; import com.bonus.common.domain.data.dto.ParamsDto; @@ -77,7 +76,7 @@ public class NetworkService { return AjaxResult.error(validResult); } if(Objects.equals(dto.getEnableDhcp(),"0")){ - String validResult2 = validatorsUtils.valid(dto, NetworkEthernetDto.ENABLE.class); + String validResult2 = validatorsUtils.valid(dto, NetworkEthernetDto.NOENABLE.class); if (StringUtils.isNotBlank(validResult2)) { return AjaxResult.error(validResult2); } @@ -88,7 +87,7 @@ public class NetworkService { return AjaxResult.error(validResult); } if(Objects.equals(dto.getEnableDhcp(),"0")){ - String validResult2 = validatorsUtils.valid(dto, NetworkEthernetDto.ENABLE.class); + String validResult2 = validatorsUtils.valid(dto, NetworkEthernetDto.NOENABLE.class); if (StringUtils.isNotBlank(validResult2)) { return AjaxResult.error(validResult2); } diff --git a/bonus-admin/src/main/java/com/bonus/web/service/data/SystemInfoService.java b/bonus-admin/src/main/java/com/bonus/web/service/data/SystemInfoService.java index 4c9e2a4..0d8577a 100644 --- a/bonus-admin/src/main/java/com/bonus/web/service/data/SystemInfoService.java +++ b/bonus-admin/src/main/java/com/bonus/web/service/data/SystemInfoService.java @@ -1,15 +1,22 @@ package com.bonus.web.service.data; +import com.bonus.algorithm.service.DeviceOperService; import com.bonus.common.core.domain.AjaxResult; +import com.bonus.common.domain.algorithm.dto.OperDeviceRequest; +import com.bonus.common.domain.algorithm.vo.DrawLinesResponse; import com.bonus.common.domain.data.dto.ParamsDto; import com.bonus.common.domain.data.vo.SystemInfoVo; +import com.bonus.common.enums.ResultCode; import com.bonus.data.service.DISystemInfoService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import javax.annotation.Resource; +import java.io.IOException; +import java.util.Objects; /** * @className:SystemInfoService @@ -25,8 +32,12 @@ public class SystemInfoService { @Resource(name = "DISystemInfoService") private DISystemInfoService systemInfoService; + @Resource(name = "DeviceOperService") + private DeviceOperService deviceOperService; + /** * 查询系统信息 + * * @param dto * @return AjaxResult * @author cwchen @@ -38,7 +49,7 @@ public class SystemInfoService { vo = systemInfoService.getDeviceInfo(dto); return AjaxResult.success(vo == null ? new SystemInfoVo() : vo); } catch (Exception e) { - log.error(e.toString(),e); + log.error(e.toString(), e); vo = new SystemInfoVo(); } return AjaxResult.success(vo); @@ -46,6 +57,7 @@ public class SystemInfoService { /** * 修改设备信息 + * * @param dto * @return AjaxResult * @author cwchen @@ -57,7 +69,7 @@ public class SystemInfoService { systemInfoService.updateDevice(dto); return AjaxResult.success(); } catch (Exception e) { - log.error(e.toString(),e); + log.error(e.toString(), e); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return AjaxResult.error(); } @@ -65,6 +77,7 @@ public class SystemInfoService { /** * 修改告警状态 + * * @param dto * @return AjaxResult * @author cwchen @@ -72,13 +85,23 @@ public class SystemInfoService { */ public AjaxResult updateAlarmStatus(ParamsDto dto) { try { - // 1.是否调用第三方接口 - systemInfoService.updateAlarmStatus(dto); - return AjaxResult.success(); - } catch (Exception e) { - log.error(e.toString(),e); - TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); - return AjaxResult.error(); + OperDeviceRequest request = new OperDeviceRequest(); + request.setMode(1L); + request.setAlarm(Objects.equals(dto.getAlarmStatus(), "1")); + DrawLinesResponse drawLinesResponse = deviceOperService.callOperDeviceService(request); + if (Objects.nonNull(drawLinesResponse)) { + if (drawLinesResponse.isSuccess()) { + systemInfoService.updateAlarmStatus(dto); + return AjaxResult.success(); + } else { + return AjaxResult.error(drawLinesResponse.getMessage()); + } + } else { + return AjaxResult.error(ResultCode.INTERFACE_CALL_FAILED.getMessage()); + } + } catch (IOException e) { + log.error(e.toString(), e); + return AjaxResult.error(ResultCode.INTERFACE_CALL_FAILED.getMessage()); } } } diff --git a/bonus-admin/src/main/resources/application-algorithm.yml b/bonus-admin/src/main/resources/application-algorithm.yml index de8e10e..97b1a17 100644 --- a/bonus-admin/src/main/resources/application-algorithm.yml +++ b/bonus-admin/src/main/resources/application-algorithm.yml @@ -1,5 +1,9 @@ algorithm: service: url: http://192.168.0.108:8080/api/v1/video/setTripwire # 画线算法接口请求地址 + operUrl: http://192.168.0.108:8080/api/v1/battery/control # 设备操作接口请求地址 + detailUrl: http://192.168.0.108:8080/api/v1/battery/status # 设备状态接口请求地址 + startVideoUrl: http://192.168.0.108:8080/api/v1/record/start # 开始录制接口请求地址 + endVideoUrl: http://192.168.0.108:8080/api/v1/record/stop # 结束录制接口请求地址 timeout: 30000 # 画线算法请求超时时间 max-connections: 100 \ No newline at end of file diff --git a/bonus-admin/src/main/resources/application-dev.yml b/bonus-admin/src/main/resources/application-dev.yml index fabb37b..099cd9f 100644 --- a/bonus-admin/src/main/resources/application-dev.yml +++ b/bonus-admin/src/main/resources/application-dev.yml @@ -8,6 +8,7 @@ bonus: copyrightYear: 2025 # 文件路径 示例( Windows配置D:/bonus/uploadPath,Linux配置 /home/bonus/uploadPath) profile: D:/bonus/uploadPath + lsFile: /home/jar/smart-car-dev # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数字计算 char 字符验证 diff --git a/bonus-admin/src/main/resources/application-druid.yml b/bonus-admin/src/main/resources/application-druid.yml index 2030d2d..6b8ce15 100644 --- a/bonus-admin/src/main/resources/application-druid.yml +++ b/bonus-admin/src/main/resources/application-druid.yml @@ -6,12 +6,12 @@ spring: druid: # 主库数据源 master: - url: jdbc:mysql://192.168.0.14:2009/smart-car-dev?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - username: root - password: Bonus@admin123! -# url: jdbc:mysql://127.0.0.1:3306/smart_bid_dev?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# url: jdbc:mysql://192.168.0.14:2009/smart-car-dev?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: root -# password: ccw1998@yyt1999 +# password: Bonus@admin123! + url: jdbc:mysql://192.168.0.108:3306/smart-car-dev?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: RemoteDev + password: forlinx # 从库数据源 slave: # 从数据源开关/默认关闭 diff --git a/bonus-admin/src/main/resources/application-test.yml b/bonus-admin/src/main/resources/application-test.yml index 531ae20..355b4ff 100644 --- a/bonus-admin/src/main/resources/application-test.yml +++ b/bonus-admin/src/main/resources/application-test.yml @@ -7,7 +7,8 @@ bonus: # 版权年份 copyrightYear: 2025 # 文件路径 示例( Windows配置D:/bonus/uploadPath,Linux配置 /home/bonus/uploadPath) - profile: /home/bonus/uploadPath + profile: /home/forlinx/Vehicle_Road_Counter + lsFile: /home/jar/smart-car-dev # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数字计算 char 字符验证 @@ -20,7 +21,7 @@ sql: # 开发环境配置 server: # 服务器的HTTP端口,默认为8091 - port: 8091 + port: 8099 servlet: # 应用的访问路径 context-path: /smartCar @@ -70,13 +71,13 @@ spring: # redis 配置 redis: # 地址 - host: 192.168.0.14 + host: 192.168.0.108 # 端口,默认为6379 - port: 2004 + port: 6379 # 数据库索引 database: 6 # 密码 - password: Plzbns@Redis123! + password: forlinx # 连接超时时间 timeout: 10s lettuce: diff --git a/bonus-admin/src/main/resources/application.yml b/bonus-admin/src/main/resources/application.yml index b423e36..e4263b7 100644 --- a/bonus-admin/src/main/resources/application.yml +++ b/bonus-admin/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: profiles: - active: @profiles.active@,druid,ocr,file,rabbitmq + active: @profiles.active@,druid,ocr,file,rabbitmq,algorithm # 解决SpringBoot 2.6+与SpringFox兼容性问题 mvc: pathmatch: diff --git a/bonus-algorithm/src/main/java/com/bonus/algorithm/service/DeviceDetailService.java b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/DeviceDetailService.java new file mode 100644 index 0000000..db5a68e --- /dev/null +++ b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/DeviceDetailService.java @@ -0,0 +1,198 @@ +package com.bonus.algorithm.service; + +import com.bonus.common.domain.algorithm.dto.OperDeviceRequest; +import com.bonus.common.domain.algorithm.vo.DeviceDetailResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.net.URI; + +/** + * @className: DeviceOperService + * @author: cwchen + * @date: 2026-01-08-9:26 + * @version: 1.0 + * @description: 设备详情详情接口调用-业务逻辑层 + */ +@Service(value = "DeviceDetailService") +@Slf4j +public class DeviceDetailService { + + private static final String UTF_8 = "UTF-8"; + + @Value("${algorithm.service.detailUrl}") + private String algorithmServiceUrl; + + @Value("${algorithm.service.timeout}") + private int timeout; + + private final CloseableHttpClient httpClient; + private final ObjectMapper objectMapper; + + public DeviceDetailService() { + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .setConnectionRequestTimeout(timeout) + .build(); + + this.httpClient = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) + .build(); + this.objectMapper = new ObjectMapper(); + } + + /** + * 调用设备详情接口 + * + * @return 设备详情响应结果 + * @throws IOException 当设备详情服务调用失败时抛出 + */ + public DeviceDetailResponse callDeviceDetailService() throws IOException { + HttpGet httpGet = null; + try { + httpGet = createHttpGet(); + return executeOcrRequest(httpGet); + } catch (IOException e) { + log.error("调用设备详情服务失败", e); + return null; + } finally { + cleanupResources(httpGet); + } + } + + /** + * 验证设备详情请求参数 + */ + private void validateOperDeviceRequest(OperDeviceRequest operDeviceRequest) { + if (operDeviceRequest == null) { + throw new IllegalArgumentException("设备详情请求参数不能为空"); + } + } + + /** + * 创建HTTP GET请求 + */ + private HttpGet createHttpGet() { + // 声明 HttpGet 对象 + HttpGet httpGet = null; + try { + // 1. 使用 URIBuilder 构建带参数的 URL + URIBuilder uriBuilder = new URIBuilder(algorithmServiceUrl); + // 2. 构建 URI 并创建 HttpGet + URI uri = uriBuilder.build(); + httpGet = new HttpGet(uri); + } catch (Exception e) { + throw new RuntimeException("创建HTTP GET请求失败", e); + } + + return httpGet; + } + + /** + * 将请求对象转换为JSON字符串 + */ + private String convertToJson(OperDeviceRequest request) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(request); + } + + /** + * 执行设备详情请求 + */ + private DeviceDetailResponse executeOcrRequest(HttpGet httpGet) throws IOException { + log.info("开始调用设备详情服务识别"); + + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + return processHttpResponse(response); + } + } + + /** + * 处理HTTP响应 + */ + private DeviceDetailResponse processHttpResponse(CloseableHttpResponse response) throws IOException { + log.info("响应内容:{}",response); + int statusCode = response.getStatusLine().getStatusCode(); + String responseBody = getResponseBody(response); + + log.info("设备详情服务响应状态: {}", statusCode); + log.debug("设备详情服务响应内容: {}", responseBody); // 改为debug级别,避免日志过大 + + // 检查HTTP状态码 + if (statusCode != 200) { + log.error("设备详情服务HTTP请求失败,状态码: {}, 响应: {}", statusCode, responseBody); + return null; + } + + DeviceDetailResponse DeviceDetailResponse = parseResponseBody(responseBody); + return DeviceDetailResponse; + } + + /** + * 获取响应体 + */ + private String getResponseBody(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, UTF_8); + } + + /** + * 解析响应体 + */ + private DeviceDetailResponse parseResponseBody(String responseBody) throws IOException { + try { + return objectMapper.readValue(responseBody, DeviceDetailResponse.class); + } catch (IOException e) { + log.error("解析设备详情请求响应失败,响应内容: {}", responseBody, e); + return null; + } + } + + /** + * 清理资源 + */ + private void cleanupResources(HttpGet httpGet) { + // 清理HTTP连接 + if (httpGet != null) { + httpGet.releaseConnection(); + } + + } + + /** + * 关闭HTTP客户端 + */ + public void close() { + try { + if (httpClient != null) { + httpClient.close(); + log.info("设备详情服务HTTP客户端已关闭"); + } + } catch (IOException e) { + log.error("关闭HTTP客户端失败", e); + } + } + + /** + * 销毁方法,用于Spring容器关闭时调用 + */ + public void destroy() { + close(); + } +} diff --git a/bonus-algorithm/src/main/java/com/bonus/algorithm/service/DeviceOperService.java b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/DeviceOperService.java new file mode 100644 index 0000000..ee11d67 --- /dev/null +++ b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/DeviceOperService.java @@ -0,0 +1,206 @@ +package com.bonus.algorithm.service; + +import com.bonus.common.domain.algorithm.dto.DrawLinesRequest; +import com.bonus.common.domain.algorithm.dto.OperDeviceRequest; +import com.bonus.common.domain.algorithm.vo.DrawLinesResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +/** + * @className: DeviceOperService + * @author: cwchen + * @date: 2026-01-08-9:26 + * @version: 1.0 + * @description: 设备操作接口调用-业务逻辑层 + */ +@Service(value = "DeviceOperService") +@Slf4j +public class DeviceOperService { + + private static final String UTF_8 = "UTF-8"; + + @Value("${algorithm.service.operUrl}") + private String algorithmServiceUrl; + + @Value("${algorithm.service.timeout}") + private int timeout; + + private final CloseableHttpClient httpClient; + private final ObjectMapper objectMapper; + + public DeviceOperService() { + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .setConnectionRequestTimeout(timeout) + .build(); + + this.httpClient = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) + .build(); + this.objectMapper = new ObjectMapper(); + } + + /** + * 调用设备操作接口 + * + * @param operDeviceRequest 设备操作请求参数 + * @return 设备操作响应结果 + * @throws IOException 当设备操作服务调用失败时抛出 + */ + public DrawLinesResponse callOperDeviceService(OperDeviceRequest operDeviceRequest) throws IOException { + validateOperDeviceRequest(operDeviceRequest); + + HttpPost httpPost = null; + try { + httpPost = createHttpPost(operDeviceRequest); + return executeOcrRequest(httpPost); + } catch (IOException e) { + log.error("调用设备操作服务失败", e); + return null; + } finally { + cleanupResources(httpPost); + } + } + + /** + * 验证设备操作请求参数 + */ + private void validateOperDeviceRequest(OperDeviceRequest operDeviceRequest) { + if (operDeviceRequest == null) { + throw new IllegalArgumentException("设备操作请求参数不能为空"); + } + } + + /** + * 创建HTTP POST请求 + */ + private HttpPost createHttpPost(OperDeviceRequest operDeviceRequest) { + HttpPost httpPost = new HttpPost(algorithmServiceUrl); + + try { + // 将请求对象转换为JSON字符串 + String jsonRequest = convertToJson(operDeviceRequest); + + // 设置请求体为JSON + StringEntity entity = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON); + httpPost.setEntity(entity); + + // 设置请求头 + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json; charset=UTF-8"); + + } catch (Exception e) { + log.error("创建HTTP POST请求失败,请求参数: {}", operDeviceRequest, e); + throw new RuntimeException("创建HTTP POST请求失败", e); + } + + return httpPost; + } + + /** + * 将请求对象转换为JSON字符串 + */ + private String convertToJson(OperDeviceRequest request) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(request); + } + + /** + * 执行设备操作请求 + */ + private DrawLinesResponse executeOcrRequest(HttpPost httpPost) throws IOException { + log.info("开始调用设备操作服务识别"); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + return processHttpResponse(response); + } + } + + /** + * 处理HTTP响应 + */ + private DrawLinesResponse processHttpResponse(CloseableHttpResponse response) throws IOException { + log.info("响应内容:{}",response); + int statusCode = response.getStatusLine().getStatusCode(); + String responseBody = getResponseBody(response); + + log.info("设备操作服务响应状态: {}", statusCode); + log.debug("设备操作服务响应内容: {}", responseBody); // 改为debug级别,避免日志过大 + + // 检查HTTP状态码 + if (statusCode != 200) { + log.error("设备操作服务HTTP请求失败,状态码: {}, 响应: {}", statusCode, responseBody); + return null; + } + + DrawLinesResponse drawLinesResponse = parseResponseBody(responseBody); + return drawLinesResponse; + } + + /** + * 获取响应体 + */ + private String getResponseBody(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, UTF_8); + } + + /** + * 解析响应体 + */ + private DrawLinesResponse parseResponseBody(String responseBody) throws IOException { + try { + return objectMapper.readValue(responseBody, DrawLinesResponse.class); + } catch (IOException e) { + log.error("解析设备操作请求响应失败,响应内容: {}", responseBody, e); + return null; + } + } + + /** + * 清理资源 + */ + private void cleanupResources(HttpPost httpPost) { + // 清理HTTP连接 + if (httpPost != null) { + httpPost.releaseConnection(); + } + + } + + /** + * 关闭HTTP客户端 + */ + public void close() { + try { + if (httpClient != null) { + httpClient.close(); + log.info("设备操作服务HTTP客户端已关闭"); + } + } catch (IOException e) { + log.error("关闭HTTP客户端失败", e); + } + } + + /** + * 销毁方法,用于Spring容器关闭时调用 + */ + public void destroy() { + close(); + } +} diff --git a/bonus-algorithm/src/main/java/com/bonus/algorithm/service/EndVideoService.java b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/EndVideoService.java new file mode 100644 index 0000000..da8278e --- /dev/null +++ b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/EndVideoService.java @@ -0,0 +1,186 @@ +package com.bonus.algorithm.service; + +import com.bonus.common.domain.algorithm.dto.OperDeviceRequest; +import com.bonus.common.domain.algorithm.vo.DrawLinesResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +/** + * @className: EndVideoService + * @author: cwchen + * @date: 2026-01-08-9:26 + * @version: 1.0 + * @description: 结束录制视频接口调用-业务逻辑层 + */ +@Service(value = "EndVideoService") +@Slf4j +public class EndVideoService { + + private static final String UTF_8 = "UTF-8"; + + @Value("${algorithm.service.endVideoUrl}") + private String algorithmServiceUrl; + + @Value("${algorithm.service.timeout}") + private int timeout; + + private final CloseableHttpClient httpClient; + private final ObjectMapper objectMapper; + + public EndVideoService() { + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .setConnectionRequestTimeout(timeout) + .build(); + + this.httpClient = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) + .build(); + this.objectMapper = new ObjectMapper(); + } + + /** + * 调用结束录制视频接口 + * + * @return 结束录制视频响应结果 + * @throws IOException 当结束录制视频服务调用失败时抛出 + */ + public DrawLinesResponse callEndVideoService() throws IOException { + HttpPost httpPost = null; + try { + httpPost = createHttpPost(); + return executeOcrRequest(httpPost); + } catch (IOException e) { + log.error("调用结束录制视频服务失败", e); + return null; + } finally { + cleanupResources(httpPost); + } + } + + /** + * 创建HTTP POST请求 + */ + private HttpPost createHttpPost() { + HttpPost httpPost = new HttpPost(algorithmServiceUrl); + + try { + // 设置请求头 + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json; charset=UTF-8"); + + } catch (Exception e) { + log.error("创建HTTP POST请求失败", e); + throw new RuntimeException("创建HTTP POST请求失败", e); + } + + return httpPost; + } + + /** + * 将请求对象转换为JSON字符串 + */ + private String convertToJson(OperDeviceRequest request) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(request); + } + + /** + * 执行结束录制视频请求 + */ + private DrawLinesResponse executeOcrRequest(HttpPost httpPost) throws IOException { + log.info("开始调用结束录制视频服务识别"); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + return processHttpResponse(response); + } + } + + /** + * 处理HTTP响应 + */ + private DrawLinesResponse processHttpResponse(CloseableHttpResponse response) throws IOException { + log.info("响应内容:{}",response); + int statusCode = response.getStatusLine().getStatusCode(); + String responseBody = getResponseBody(response); + + log.info("结束录制视频服务响应状态: {}", statusCode); + log.debug("结束录制视频服务响应内容: {}", responseBody); // 改为debug级别,避免日志过大 + + // 检查HTTP状态码 + if (statusCode != 200) { + log.error("结束录制视频服务HTTP请求失败,状态码: {}, 响应: {}", statusCode, responseBody); + return null; + } + + DrawLinesResponse drawLinesResponse = parseResponseBody(responseBody); + return drawLinesResponse; + } + + /** + * 获取响应体 + */ + private String getResponseBody(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, UTF_8); + } + + /** + * 解析响应体 + */ + private DrawLinesResponse parseResponseBody(String responseBody) throws IOException { + try { + return objectMapper.readValue(responseBody, DrawLinesResponse.class); + } catch (IOException e) { + log.error("解析结束录制视频请求响应失败,响应内容: {}", responseBody, e); + return null; + } + } + + /** + * 清理资源 + */ + private void cleanupResources(HttpPost httpPost) { + // 清理HTTP连接 + if (httpPost != null) { + httpPost.releaseConnection(); + } + + } + + /** + * 关闭HTTP客户端 + */ + public void close() { + try { + if (httpClient != null) { + httpClient.close(); + log.info("结束录制视频服务HTTP客户端已关闭"); + } + } catch (IOException e) { + log.error("关闭HTTP客户端失败", e); + } + } + + /** + * 销毁方法,用于Spring容器关闭时调用 + */ + public void destroy() { + close(); + } +} diff --git a/bonus-algorithm/src/main/java/com/bonus/algorithm/service/StartVideoService.java b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/StartVideoService.java new file mode 100644 index 0000000..48f7cf8 --- /dev/null +++ b/bonus-algorithm/src/main/java/com/bonus/algorithm/service/StartVideoService.java @@ -0,0 +1,188 @@ +package com.bonus.algorithm.service; + +import com.bonus.common.domain.algorithm.dto.OperDeviceRequest; +import com.bonus.common.domain.algorithm.vo.DrawLinesResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +/** + * @className: StartVideoService + * @author: cwchen + * @date: 2026-01-08-9:26 + * @version: 1.0 + * @description: 开始录制视频接口调用-业务逻辑层 + */ +@Service(value = "StartVideoService") +@Slf4j +public class StartVideoService { + + private static final String UTF_8 = "UTF-8"; + + @Value("${algorithm.service.startVideoUrl}") + private String algorithmServiceUrl; + + @Value("${algorithm.service.timeout}") + private int timeout; + + private final CloseableHttpClient httpClient; + private final ObjectMapper objectMapper; + + public StartVideoService() { + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .setConnectionRequestTimeout(timeout) + .build(); + + this.httpClient = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) + .build(); + this.objectMapper = new ObjectMapper(); + } + + /** + * 调用录制视频接口 + * + * @return 录制视频响应结果 + * @throws IOException 当录制视频服务调用失败时抛出 + */ + public DrawLinesResponse callStartVideoService() throws IOException { + + HttpPost httpPost = null; + try { + httpPost = createHttpPost(); + return executeOcrRequest(httpPost); + } catch (IOException e) { + log.error("调用录制视频服务失败", e); + return null; + } finally { + cleanupResources(httpPost); + } + } + + /** + * 创建HTTP POST请求 + */ + private HttpPost createHttpPost() { + HttpPost httpPost = new HttpPost(algorithmServiceUrl); + + try { + + // 设置请求头 + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json; charset=UTF-8"); + + } catch (Exception e) { + log.error("创建HTTP POST请求失败", e); + throw new RuntimeException("创建HTTP POST请求失败", e); + } + + return httpPost; + } + + /** + * 将请求对象转换为JSON字符串 + */ + private String convertToJson(OperDeviceRequest request) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(request); + } + + /** + * 执行录制视频请求 + */ + private DrawLinesResponse executeOcrRequest(HttpPost httpPost) throws IOException { + log.info("开始调用录制视频服务识别"); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + return processHttpResponse(response); + } + } + + /** + * 处理HTTP响应 + */ + private DrawLinesResponse processHttpResponse(CloseableHttpResponse response) throws IOException { + log.info("响应内容:{}",response); + int statusCode = response.getStatusLine().getStatusCode(); + String responseBody = getResponseBody(response); + + log.info("录制视频服务响应状态: {}", statusCode); + log.debug("录制视频服务响应内容: {}", responseBody); // 改为debug级别,避免日志过大 + + // 检查HTTP状态码 + if (statusCode != 200) { + log.error("录制视频服务HTTP请求失败,状态码: {}, 响应: {}", statusCode, responseBody); + return null; + } + + DrawLinesResponse drawLinesResponse = parseResponseBody(responseBody); + return drawLinesResponse; + } + + /** + * 获取响应体 + */ + private String getResponseBody(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity, UTF_8); + } + + /** + * 解析响应体 + */ + private DrawLinesResponse parseResponseBody(String responseBody) throws IOException { + try { + return objectMapper.readValue(responseBody, DrawLinesResponse.class); + } catch (IOException e) { + log.error("解析录制视频请求响应失败,响应内容: {}", responseBody, e); + return null; + } + } + + /** + * 清理资源 + */ + private void cleanupResources(HttpPost httpPost) { + // 清理HTTP连接 + if (httpPost != null) { + httpPost.releaseConnection(); + } + + } + + /** + * 关闭HTTP客户端 + */ + public void close() { + try { + if (httpClient != null) { + httpClient.close(); + log.info("录制视频服务HTTP客户端已关闭"); + } + } catch (IOException e) { + log.error("关闭HTTP客户端失败", e); + } + } + + /** + * 销毁方法,用于Spring容器关闭时调用 + */ + public void destroy() { + close(); + } +} diff --git a/bonus-common/src/main/java/com/bonus/common/domain/algorithm/dto/OperDeviceRequest.java b/bonus-common/src/main/java/com/bonus/common/domain/algorithm/dto/OperDeviceRequest.java new file mode 100644 index 0000000..0575b81 --- /dev/null +++ b/bonus-common/src/main/java/com/bonus/common/domain/algorithm/dto/OperDeviceRequest.java @@ -0,0 +1,23 @@ +package com.bonus.common.domain.algorithm.dto; + +import lombok.Data; + +/** + * @className:OperDeviceRequest + * @author:cwchen + * @date:2026-01-19-9:29 + * @version:1.0 + * @description:设备操作请求实体 + */ +@Data +public class OperDeviceRequest { + + /** + * 为1(工作模式)或者2(休眠模式) + */ + private Long mode; + /** + * 为true(开启报警)或者false(关闭报警) + */ + private boolean alarm; +} diff --git a/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DeviceDetailResponse.java b/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DeviceDetailResponse.java new file mode 100644 index 0000000..23f183a --- /dev/null +++ b/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DeviceDetailResponse.java @@ -0,0 +1,61 @@ +package com.bonus.common.domain.algorithm.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import java.util.Objects; + +/** + * @className: DeviceDetailResponse + * @author: cwchen + * @date: 2026-01-08-9:35 + * @version: 1.0 + * @description: 设备详情响应-实体 + */ +@Data +public class DeviceDetailResponse { + + @JsonProperty("code") + private Integer code; // 状态码 + + @JsonProperty("status") + private String status; + + /** + * 对应 JSON 中的 "data" 对象 + */ + @JsonProperty("data") + private DeviceInfo data; + + public boolean isSuccess() { + return Objects.equals(status, "success") && code != null && code == 200; + } + + /** + * 内部类,用于映射 data 字段 + * 使用静态内部类 (static class) 方便实例化 + */ + @Data + public static class DeviceInfo { + + @JsonProperty("battery_cap") + private Integer batteryCap; // 电量百分比 (0-100) + + @JsonProperty("time_to_full_min") + private Integer timeToFullMin; // 预计充满剩余分钟数 + + @JsonProperty("time_to_empty_min") + private Integer timeToEmptyMin; // 预计放空剩余分钟数 + + @JsonProperty("status_code") + private Integer statusCode; // 电池内部状态码 + + @JsonProperty("temperature_c") + private Double temperatureC; // 温度 (摄氏度),注意用 Double 接收小数 + + @JsonProperty("system_mode") + private Integer systemMode; // 当前模式 (1: WORK, 2: SLEEP) + + @JsonProperty("alarm_flag") + private Integer alarmFlag; // 报警标志 (0: 无, 1: 报警) + } +} \ No newline at end of file diff --git a/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DrawLinesResponse.java b/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DrawLinesResponse.java index c618a1b..d0c8fa9 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DrawLinesResponse.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/algorithm/vo/DrawLinesResponse.java @@ -28,6 +28,6 @@ public class DrawLinesResponse { private String status; public boolean isSuccess() { - return Objects.equals(status, "success") && code != null && code == 200; + return code == 200; } } diff --git a/bonus-common/src/main/java/com/bonus/common/domain/data/dto/NetworkEthernetDto.java b/bonus-common/src/main/java/com/bonus/common/domain/data/dto/NetworkEthernetDto.java index cc8b33b..cb8c794 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/data/dto/NetworkEthernetDto.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/data/dto/NetworkEthernetDto.java @@ -48,8 +48,11 @@ public class NetworkEthernetDto { */ @NotBlank(message = "IP地址不能为空", groups = {NOENABLE.class}) @Length(max = 32, message = "IP地址字符长度不能超过32", groups = {NOENABLE.class}) - @Pattern(regexp = "^(?=.{1,255}$)(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$|^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", - message = "IP地址格式不正确(需为有效IP或域名)", groups = {NOENABLE.class}) + @Pattern( + regexp = "^(?:(?=.{1,255}$)(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,63}))|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$", + message = "IP地址格式不正确(需为有效IPv4地址或域名)", + groups = {NOENABLE.class} + ) private String ipAddress; /** @@ -58,19 +61,18 @@ public class NetworkEthernetDto { @NotBlank(message = "子网掩码不能为空", groups = {NOENABLE.class}) @Length(max = 15, message = "子网掩码长度不正确", groups = {NOENABLE.class}) @Pattern( - regexp = "^(254|252|248|240|224|192|128|0)\\.0\\.0\\.0$|^(255\\.(254|252|248|240|224|192|128|0)\\.0\\.0)$|^(255\\.255\\.(254|252|248|240|224|192|128|0)\\.0)$|^(255\\.255\\.255\\.(255|254|252|248|240|224|192|128|0))$", + regexp = "^(?:(?:254|252|248|240|224|192|128|0)\\.0\\.0\\.0)|(?:255\\.(?:254|252|248|240|224|192|128|0)\\.0\\.0)|(?:255\\.255\\.(?:254|252|248|240|224|192|128|0)\\.0)|(?:255\\.255\\.255\\.(?:255|254|252|248|240|224|192|128|0))$", message = "子网掩码格式不正确", groups = {NOENABLE.class} ) private String subnetMask; /** - * 默认网关 + * 默认网关 (允许为空,有内容则校验格式) */ - @NotBlank(message = "默认网关不能为空", groups = {NOENABLE.class}) - @Length(max = 15, message = "默认网关长度不正确", groups = {NOENABLE.class}) @Pattern( - regexp = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + // 将原正则包裹在 (?:原正则)? 中,或者利用 @Pattern 默认不校验 null 的特性 + regexp = "^$|^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", message = "默认网关格式不正确", groups = {NOENABLE.class} ) @@ -79,7 +81,6 @@ public class NetworkEthernetDto { /** * DNS */ - @NotBlank(message = "DNS不能为空", groups = {NOENABLE.class}) @Length(max = 512, message = "DNS字符长度不能超过512", groups = {NOENABLE.class}) private String dns; diff --git a/bonus-common/src/main/java/com/bonus/common/domain/data/dto/ParamsDto.java b/bonus-common/src/main/java/com/bonus/common/domain/data/dto/ParamsDto.java index d58d638..1fa867a 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/data/dto/ParamsDto.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/data/dto/ParamsDto.java @@ -16,7 +16,9 @@ import java.util.Date; @Data public class ParamsDto { - /**车辆类型 1.油车 2.新能源*/ + /** + * 车辆类型 1.油车 2.新能源 + */ private String carType; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @@ -27,16 +29,24 @@ public class ParamsDto { @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date endTime; - /**设备名称*/ + /** + * 设备名称 + */ private String equipmentName; - /**设备ID*/ + /** + * 设备ID + */ private Long systemId = 1L; - /**告警状态*/ + /** + * 告警状态 + */ private String alarmStatus; - /**系统设置ID*/ + /** + * 系统设置ID + */ private Long systemSettingId; /** @@ -48,4 +58,17 @@ public class ParamsDto { * SIM_ID */ private Long simId; + + /** + * 为1(工作模式)或者2(休眠模式) + */ + private String mode; + /** + * 为true(开启报警)或者false(关闭报警) + */ + private boolean alarm; + + /**录制状态 1.开始录制 2.结束录制*/ + private String recordingType; + } diff --git a/bonus-data/src/main/java/com/bonus/data/mapper/DISystemInfoMapper.java b/bonus-data/src/main/java/com/bonus/data/mapper/DISystemInfoMapper.java index 3d02458..61c102f 100644 --- a/bonus-data/src/main/java/com/bonus/data/mapper/DISystemInfoMapper.java +++ b/bonus-data/src/main/java/com/bonus/data/mapper/DISystemInfoMapper.java @@ -1,5 +1,6 @@ package com.bonus.data.mapper; +import com.bonus.common.domain.algorithm.vo.DeviceDetailResponse; import com.bonus.common.domain.data.dto.ParamsDto; import com.bonus.common.domain.data.vo.StorageVo; import com.bonus.common.domain.data.vo.SystemInfoVo; @@ -49,4 +50,13 @@ public interface DISystemInfoMapper { * @date 2025/12/24 15:07 */ void updateSystemStorage(StorageVo vo); + + /** + * 更新设备详情 + * @param data + * @return void + * @author cwchen + * @date 2026/1/19 13:48 + */ + void updateSystemInfo(DeviceDetailResponse.DeviceInfo data); } diff --git a/bonus-data/src/main/java/com/bonus/data/service/DISystemInfoService.java b/bonus-data/src/main/java/com/bonus/data/service/DISystemInfoService.java index 0456f0a..3e3ea60 100644 --- a/bonus-data/src/main/java/com/bonus/data/service/DISystemInfoService.java +++ b/bonus-data/src/main/java/com/bonus/data/service/DISystemInfoService.java @@ -1,5 +1,6 @@ package com.bonus.data.service; +import com.bonus.common.domain.algorithm.vo.DeviceDetailResponse; import com.bonus.common.domain.data.dto.ParamsDto; import com.bonus.common.domain.data.vo.StorageVo; import com.bonus.common.domain.data.vo.SystemInfoVo; @@ -47,4 +48,13 @@ public interface DISystemInfoService { * @date 2025/12/24 15:06 */ void updateSystemStorage(StorageVo vo); + + /** + * 更新设备详情 + * @param data + * @return void + * @author cwchen + * @date 2026/1/19 13:48 + */ + void updateSystemInfo(DeviceDetailResponse.DeviceInfo data); } diff --git a/bonus-data/src/main/java/com/bonus/data/service/impl/DSystemInfoServiceImpl.java b/bonus-data/src/main/java/com/bonus/data/service/impl/DSystemInfoServiceImpl.java index 86b0540..d935ee7 100644 --- a/bonus-data/src/main/java/com/bonus/data/service/impl/DSystemInfoServiceImpl.java +++ b/bonus-data/src/main/java/com/bonus/data/service/impl/DSystemInfoServiceImpl.java @@ -1,5 +1,6 @@ package com.bonus.data.service.impl; +import com.bonus.common.domain.algorithm.vo.DeviceDetailResponse; import com.bonus.common.domain.data.dto.ParamsDto; import com.bonus.common.domain.data.vo.StorageVo; import com.bonus.common.domain.data.vo.SystemInfoVo; @@ -41,4 +42,9 @@ public class DSystemInfoServiceImpl implements DISystemInfoService { public void updateSystemStorage(StorageVo vo) { diSystemInfoMapper.updateSystemStorage(vo); } + + @Override + public void updateSystemInfo(DeviceDetailResponse.DeviceInfo data) { + diSystemInfoMapper.updateSystemInfo(data); + } } diff --git a/bonus-data/src/main/resources/mapper/DSystemInfoMapper.xml b/bonus-data/src/main/resources/mapper/DSystemInfoMapper.xml index 1cd8251..035bac8 100644 --- a/bonus-data/src/main/resources/mapper/DSystemInfoMapper.xml +++ b/bonus-data/src/main/resources/mapper/DSystemInfoMapper.xml @@ -42,4 +42,14 @@ UPDATE tb_system_info SET tf_storage = #{capacity} WHERE system_id = #{systemId} + + + UPDATE tb_system_info + SET + equipment_status = #{systemMode}, + equipment_operating_temperature = #{temperatureC}, + alarm_status = #{alarmFlag}, + battery_power = #{batteryCap} + WHERE system_id = 1 + diff --git a/bonus-quartz/pom.xml b/bonus-quartz/pom.xml index 46ef1c4..6672484 100644 --- a/bonus-quartz/pom.xml +++ b/bonus-quartz/pom.xml @@ -34,7 +34,16 @@ com.bonus bonus-common - + + com.bonus + bonus-algorithm + 3.9.0 + compile + + + com.bonus + bonus-data + diff --git a/bonus-quartz/src/main/java/com/bonus/quartz/task/DeviceDetailTask.java b/bonus-quartz/src/main/java/com/bonus/quartz/task/DeviceDetailTask.java new file mode 100644 index 0000000..2570ffe --- /dev/null +++ b/bonus-quartz/src/main/java/com/bonus/quartz/task/DeviceDetailTask.java @@ -0,0 +1,59 @@ +package com.bonus.quartz.task; +import com.bonus.algorithm.service.DeviceDetailService; +import com.bonus.common.domain.algorithm.vo.DeviceDetailResponse; +import com.bonus.data.service.DISystemInfoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Objects; + +/** + * @className:DeviceDetailTask + * @author:cwchen + * @date:2025-12-30-17:07 + * @version:1.0 + * @description:设备详情任务类 + */ +@Slf4j +@Component(value = "DeviceDetailTask") +public class DeviceDetailTask { + + @Resource(name = "DeviceDetailService") + private DeviceDetailService detailService; + + @Resource(name = "DISystemInfoService") + private DISystemInfoService diSystemInfoService; + + + /** + * 每天十分钟执行一次清理任务 + * cron 表达式: 秒 分 时 日 月 周 + */ + public void getDeviceDetail() { + try { + DeviceDetailResponse deviceDetailResponse = detailService.callDeviceDetailService(); + if (Objects.nonNull(deviceDetailResponse)) { + if(deviceDetailResponse.isSuccess()){ + log.info("设备详情:{}",deviceDetailResponse); + DeviceDetailResponse.DeviceInfo data = deviceDetailResponse.getData(); + // 处理温度 + BigDecimal bd = new BigDecimal(Double.toString(data.getTemperatureC())); + bd = bd.setScale(2, RoundingMode.HALF_UP); + double result = bd.doubleValue(); + data.setTemperatureC(result); + // 处理设备状态 + if(Objects.equals(data.getSystemMode(),"2")){ + data.setSystemMode(0); + } + diSystemInfoService.updateSystemInfo(data); + } + } + } catch (IOException e) { + log.error("设备详情更新失败",e); + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index baef741..e6b390b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ bonus http://www.bonus.vip - 智能投标系统 + 车辆道路计数仪 3.9.0