diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/device/pojo/entity/FeiBaSetEntity.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/device/pojo/entity/FeiBaSetEntity.java index 0ecd5710..dbc63b63 100644 --- a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/device/pojo/entity/FeiBaSetEntity.java +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/device/pojo/entity/FeiBaSetEntity.java @@ -28,14 +28,14 @@ public class FeiBaSetEntity extends BaseEntity { * 空闲 */ public static Integer FS_STATUS_FREE = 1; - /** - * 已绑定 - */ - public static Integer FS_STATUS_BOUND = 2; /** * 使用中 */ public static Integer FS_STATUS_USED = 3; + /** + * 已绑定 + */ + public static Integer FS_STATUS_BOUND = 2; public static Map fsStatusMap = new HashMap<>(3); diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/EquipmentController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/EquipmentController.java index 79932938..f2c0d338 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/EquipmentController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/EquipmentController.java @@ -32,6 +32,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import jakarta.annotation.PostConstruct; import lombok.AllArgsConstructor; import jakarta.validation.Valid; @@ -44,6 +45,7 @@ import org.springblade.core.tool.utils.Func; import org.springblade.desk.device.pojo.excel.EquipmentExcel; import org.springblade.desk.device.pojo.vo.EquipmentStatusStatisticsVO; import org.springblade.desk.order.wrapper.AssayContentWrapper; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.*; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -184,4 +186,18 @@ public class EquipmentController extends BladeController { ExcelUtil.export(response, "设备信息表数据" + DateUtil.time(), "设备信息表数据表", list, EquipmentExcel.class); } + @PostConstruct // 项目启动后立即执行一次 + public void init() { + regularlyUpdated(); + } + + /** + * 同步IOT设备数据 + * TODO 以后需要交由PowerJob服务统一管理 + */ + @Scheduled(cron = "0 0 0/23 * * ?") // 每23小时执行一次 + public void regularlyUpdated() { + equipmentService.regularlyUpdated(); + } + } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/FeiBaSetController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/FeiBaSetController.java index 08e2e4a1..d552bdf8 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/FeiBaSetController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/controller/FeiBaSetController.java @@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import jakarta.annotation.PostConstruct; import lombok.AllArgsConstructor; import jakarta.validation.Valid; @@ -22,6 +23,7 @@ import org.springblade.desk.device.pojo.vo.FeiBaSetVO; import org.springblade.desk.device.service.IFeiBaSetService; import org.springblade.desk.device.wrapper.EquipmentWrapper; import org.springblade.desk.device.wrapper.FeiBaSetWrapper; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.*; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -147,4 +149,17 @@ public class FeiBaSetController extends BladeController { ExcelUtil.export(response, "飞靶设置数据" + DateUtil.time(), "飞靶设置数据表", list, FeiBaSetExcel.class); } + @PostConstruct // 项目启动后立即执行一次 + public void init() { + regularlyUpdated(); + } + + /** + * 同步IOT飞靶数据 + * TODO 以后需要交由PowerJob服务统一管理 + */ + @Scheduled(cron = "0 0 0/23 * * ?") // 每23小时执行一次 + public void regularlyUpdated() { + feiBaSetService.regularlyUpdated(); + } } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IEquipmentService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IEquipmentService.java index 8dbf2e21..9589c383 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IEquipmentService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IEquipmentService.java @@ -74,4 +74,6 @@ public interface IEquipmentService extends BaseService { * @return */ Boolean editIp(String ip, Long deviceId); + + void regularlyUpdated(); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IFeiBaSetService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IFeiBaSetService.java index f9f76789..12912a24 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IFeiBaSetService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/IFeiBaSetService.java @@ -42,4 +42,6 @@ public interface IFeiBaSetService extends BaseService { * @return */ Boolean bind(@NotEmpty List ids, Integer deviceId); + + void regularlyUpdated(); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/EquipmentServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/EquipmentServiceImpl.java index 302b4e26..890a6df0 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/EquipmentServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/EquipmentServiceImpl.java @@ -1,46 +1,35 @@ -/** - * BladeX Commercial License Agreement - * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. - *

- * Use of this software is governed by the Commercial License Agreement - * obtained after purchasing a license from BladeX. - *

- * 1. This software is for development use only under a valid license - * from BladeX. - *

- * 2. Redistribution of this software's source code to any third party - * without a commercial license is strictly prohibited. - *

- * 3. Licensees may copyright their own code but cannot use segments - * from this software for such purposes. Copyright of this software - * remains with BladeX. - *

- * Using this software signifies agreement to this License, and the software - * must not be used for illegal purposes. - *

- * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is - * not liable for any claims arising from secondary or illegal development. - *

- * Author: Chill Zhuang (bladejava@qq.com) - */ package org.springblade.desk.device.service.impl; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.nacos.common.utils.CollectionUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import jodd.util.StringUtil; +import lombok.extern.slf4j.Slf4j; import org.springblade.desk.device.pojo.entity.EquipmentEntity; import org.springblade.desk.device.pojo.excel.EquipmentExcel; +import org.springblade.desk.device.pojo.request.MeasuringUsageQuery; import org.springblade.desk.device.pojo.vo.EquipmentStatusStatisticsVO; import org.springblade.desk.device.pojo.vo.EquipmentVO; import org.springblade.desk.device.mapper.EquipmentMapper; import org.springblade.desk.device.service.IEquipmentService; +import org.springblade.desk.jobtransfer.pojo.entity.CertificateTypeEntity; import org.springblade.system.cache.DictCache; import org.springblade.system.pojo.enums.DictEnum; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseServiceImpl; -import java.util.List; -import java.util.Objects; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.*; +import java.util.stream.Collectors; /** * 设备信息表 服务实现类 @@ -48,9 +37,25 @@ import java.util.Objects; * @author qyl * @since 2025-12-26 */ +@Slf4j @Service public class EquipmentServiceImpl extends BaseServiceImpl implements IEquipmentService { + @Value("${request.iot.orgId}") + private String orgId; + @Value("${request.iot.systemId}") + private String systemId; + + @Value("${request.iot.url}") + private String iotUrl; + + @Value("${request.iotNew.url}") + private String iotNewUrl; + // 使用JDK 17内置的HttpClient(线程安全,可复用) + private final HttpClient httpClient = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(30)) + .version(HttpClient.Version.HTTP_2) + .build(); @Override public IPage selectEquipmentPage(IPage page, EquipmentEntity equipment) { // return page.setRecords(baseMapper.selectEquipmentPage(page, equipment)); @@ -95,4 +100,84 @@ public class EquipmentServiceImpl extends BaseServiceImpl response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + // 处理响应 + String responseBody = response.body(); + JSONObject result = JSONObject.parseObject(responseBody); + log.debug("同步IOT设备数据: {}", result.toJSONString()); + if (result != null && result.getInteger("code").equals(0)) { + List jsonList = JSONArray.parseArray(result.getJSONArray("result").toJSONString(), JSONObject.class); + if (jsonList != null && jsonList.size() > 0) { + //接口返回设备id即为本系统code + Map iotIdObjectMap = jsonList.stream().collect(Collectors.toMap( + e -> e.getString("id"), + e -> e)); + Set iotIds = iotIdObjectMap.keySet(); + if (iotIds == null || iotIds.size() < 1) { + log.error("同步IOT设备数据接口返回数据为空"); + return; + } + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(iotIds), EquipmentEntity::getDeviceCode, iotIds); + List equipmentEntities = this.list(lambdaQueryWrapper); + Map equipmentEntityMap = new HashMap<>(); + if (null != equipmentEntities && equipmentEntities.size() > 0) { + equipmentEntities.stream().collect(Collectors.toMap( + e -> e.getDeviceCode(), + e -> e)); + } + List saves = new ArrayList<>(); + for (JSONObject jsonObject : jsonList) { + EquipmentEntity equipment = equipmentEntityMap.get(jsonObject.getString("id")); + equipment = Optional.ofNullable(equipment).orElse(new EquipmentEntity()); + equipment.setDeviceCode(jsonObject.getString("id")); + equipment.setDeviceName(jsonObject.getString("name")); + equipment.setTypeName(jsonObject.getString("productName")); + JSONObject state = jsonObject.getJSONObject("state"); + equipment.setUsed("在线".equals(state.getString("text")) ? EquipmentEntity.USED_OK : EquipmentEntity.USED_PAUSE); + equipment.setDocking("1"); + equipment.setMemo(jsonObject.getString("describe")); + equipment.setCategorys(jsonObject.getString("category")); + saves.add(equipment); + } + boolean saved = this.saveOrUpdateBatch(saves); + if (saved) { + log.debug("同步IOT设备数据成功"); + } else { + log.error("同步IOT设备数据失败"); + } + } + } + } catch (Exception e) { + log.error("同步IOT设备数据接口调用失败: {}", e.getMessage(), e); + } + } + + /** + * 构建请求体 + */ + private JSONObject buildRequestBody() { + JSONObject requestBody = new JSONObject(); + requestBody.put("orgId", orgId); + requestBody.put("systemId", systemId); + log.debug("同步IOT设备数据请求参数: {}", requestBody.toJSONString()); + return requestBody; + } + } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/FeiBaSetServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/FeiBaSetServiceImpl.java index 90d50b33..f282fe5e 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/FeiBaSetServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/device/service/impl/FeiBaSetServiceImpl.java @@ -1,23 +1,32 @@ package org.springblade.desk.device.service.impl; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.nacos.common.utils.CollectionUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; import org.springblade.desk.device.mapper.FeiBaSetMapper; -import org.springblade.desk.device.pojo.entity.EquipmentEntity; +import org.springblade.desk.device.pojo.entity.FeiBaSetEntity; import org.springblade.desk.device.pojo.entity.FeiBaSetEntity; import org.springblade.desk.device.pojo.excel.FeiBaSetExcel; import org.springblade.desk.device.service.IFeiBaSetService; import org.springblade.desk.order.pojo.entity.YieldOrder; import org.springblade.system.cache.DictCache; import org.springblade.system.pojo.enums.DictEnum; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseServiceImpl; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.*; +import java.util.stream.Collectors; /** * 飞跋设置 服务实现类 @@ -25,9 +34,17 @@ import java.util.Objects; * @author qyl * @since 2025-12-29 */ +@Slf4j @Service public class FeiBaSetServiceImpl extends BaseServiceImpl implements IFeiBaSetService { + @Value("${request.equ.url}") + private String equUrl; + // 使用JDK 17内置的HttpClient(线程安全,可复用) + private final HttpClient httpClient = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(30)) + .version(HttpClient.Version.HTTP_2) + .build(); @Override public IPage selectFeiBaSetPage(IPage page, FeiBaSetEntity feiBaSet) { // return page.setRecords(baseMapper.selectFeiBaSetPage(page, feiBaSet)); @@ -67,4 +84,67 @@ public class FeiBaSetServiceImpl extends BaseServiceImpl response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + // 处理响应 + String responseBody = response.body(); + JSONObject result = JSONObject.parseObject(responseBody); + log.debug("同步飞靶数据: {}", result.toJSONString()); + if (result != null && result.getInteger("code").equals(0)) { + List jsonList = JSONArray.parseArray(result.getJSONArray("result").toJSONString(), JSONObject.class); + if (jsonList != null && jsonList.size() > 0) { + //接口返回飞靶code即为本系统code + Map equCodeObjectMap = jsonList.stream().collect(Collectors.toMap( + e -> e.getString("code"), + e -> e)); + Set equCodes = equCodeObjectMap.keySet(); + if (equCodes == null || equCodes.size() < 1) { + log.error("同步飞靶数据接口返回数据为空"); + return; + } + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(equCodes), FeiBaSetEntity::getFsCode, equCodes); + List feiBaSetEntityList = this.list(lambdaQueryWrapper); + Map FeiBaSetEntityMap = new HashMap<>(); + if (null != feiBaSetEntityList && feiBaSetEntityList.size() > 0) { + feiBaSetEntityList.stream().collect(Collectors.toMap( + e -> e.getFsCode(), + e -> e)); + } + List saves = new ArrayList<>(); + for (JSONObject jsonObject : jsonList) { + FeiBaSetEntity feiBaSet = FeiBaSetEntityMap.get(jsonObject.getString("code")); + feiBaSet = Optional.ofNullable(feiBaSet).orElse(new FeiBaSetEntity()); + feiBaSet.setFsCode(jsonObject.getString("code")); + feiBaSet.setFsType(jsonObject.getString("name")); + if (null == feiBaSet.getId()) { + feiBaSet.setStatus(FeiBaSetEntity.FS_STATUS_FREE); + } + saves.add(feiBaSet); + } + boolean saved = this.saveOrUpdateBatch(saves); + if (saved) { + log.debug("同步飞靶数据成功"); + } else { + log.error("同步飞靶数据失败"); + } + } + } + } catch (Exception e) { + log.error("同步飞靶数据接口调用失败: {}", e.getMessage(), e); + } + } } diff --git a/blade-service/blade-desk/src/main/resources/application-dev.yml b/blade-service/blade-desk/src/main/resources/application-dev.yml index dd9852ab..16e6bd5d 100644 --- a/blade-service/blade-desk/src/main/resources/application-dev.yml +++ b/blade-service/blade-desk/src/main/resources/application-dev.yml @@ -39,12 +39,23 @@ role-config: sj-checker-alias: "rb_checker" request: - measuringTool: + #用水用电接口请求地址(iot) + iot: + #热表分厂组织id(部门id) + orgId: 16 + #业务系统id + systemId: 344123 + url: http://192.168.169.32:80720 + iotNew: + url: http://192.168.169.23:8072 #量具使用记录 + measuringTool: url: "192.168.191.11:8888" - lims: #计量记录 + lims: url: "http://192.168.169.50:30000" - + #飞拔信息接口请求地址 + equ: + url: http://192.168.169.69 logging: config: classpath:logback.xml