From 1b6ef3cc2803467a56f75050058f3aab6313c0f0 Mon Sep 17 00:00:00 2001 From: huguanghan Date: Wed, 8 Jan 2025 16:15:02 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E7=89=A9=E6=A8=A1=E5=9E=8B,=E7=89=A9?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=B1=9E=E6=80=A7=E7=BC=93=E5=AD=98=E5=88=B7?= =?UTF-8?q?=E6=96=B0,deviceEventCommand=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cache/domain/IotFieldInfoCache.java | 3 ++ .../modules/cache/service/IotModelCache.java | 9 ++++ .../cache/service/impl/IotModelCacheImpl.java | 42 +++++++++++++++++++ .../service/impl/SysIotModelServiceImpl.java | 17 ++++++++ .../node/command/DeviceEventCommand.java | 23 +++++----- 5 files changed, 82 insertions(+), 12 deletions(-) diff --git a/das/src/main/java/com/das/modules/cache/domain/IotFieldInfoCache.java b/das/src/main/java/com/das/modules/cache/domain/IotFieldInfoCache.java index 5aa11e2e..a815a885 100644 --- a/das/src/main/java/com/das/modules/cache/domain/IotFieldInfoCache.java +++ b/das/src/main/java/com/das/modules/cache/domain/IotFieldInfoCache.java @@ -1,5 +1,6 @@ package com.das.modules.cache.domain; +import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; @Data @@ -10,6 +11,8 @@ public class IotFieldInfoCache { private Integer porder; private Integer highspeed; private String datatype; + private Integer level; + private String stateDesc; public boolean isHighSpeed() { return highspeed.equals(1) && attributeType.equals(138); diff --git a/das/src/main/java/com/das/modules/cache/service/IotModelCache.java b/das/src/main/java/com/das/modules/cache/service/IotModelCache.java index 315538f3..0bc32e6d 100644 --- a/das/src/main/java/com/das/modules/cache/service/IotModelCache.java +++ b/das/src/main/java/com/das/modules/cache/service/IotModelCache.java @@ -1,7 +1,16 @@ package com.das.modules.cache.service; +import com.das.modules.cache.domain.IotFieldInfoCache; +import com.das.modules.equipment.entity.SysIotModel; +import com.das.modules.equipment.entity.SysIotModelField; + public interface IotModelCache { public boolean isHighSpeed(Long modelId, String attr); public boolean isLowSpeed(Long modelId, String attr); public boolean isCalculate(Long modelId, String attr); + void refreshIotFieldCache(SysIotModelField sysIotModelField); + void removeIotFieldCache(Long modelId, String attributeCode); + void refreshIotModelInfoIdMap(SysIotModel sysIotModel); + void removeIotModelInfoIdMap(Long modelId); + IotFieldInfoCache getIotFiledCache(Long modelId,String attr); } diff --git a/das/src/main/java/com/das/modules/cache/service/impl/IotModelCacheImpl.java b/das/src/main/java/com/das/modules/cache/service/impl/IotModelCacheImpl.java index fa302467..449fb3fe 100644 --- a/das/src/main/java/com/das/modules/cache/service/impl/IotModelCacheImpl.java +++ b/das/src/main/java/com/das/modules/cache/service/impl/IotModelCacheImpl.java @@ -3,6 +3,8 @@ package com.das.modules.cache.service.impl; import com.das.modules.cache.domain.IotFieldInfoCache; import com.das.modules.cache.domain.IotModelInfoCache; import com.das.modules.cache.service.IotModelCache; +import com.das.modules.equipment.entity.SysIotModel; +import com.das.modules.equipment.entity.SysIotModelField; import com.das.modules.equipment.mapper.SysIotModelMapper; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; @@ -38,6 +40,8 @@ public class IotModelCacheImpl implements IotModelCache { fieldInfoCache.setAttributeType(item.getAttributeType()); fieldInfoCache.setHighspeed(item.getHighSpeed()); fieldInfoCache.setDatatype(item.getDataType()); + fieldInfoCache.setLevel(item.getLevel()); + fieldInfoCache.setStateDesc(item.getStateDesc()); iotFieldsMap.put(String.format("%d_%s", k, item.getAttributeCode()), fieldInfoCache); }); }); @@ -75,4 +79,42 @@ public class IotModelCacheImpl implements IotModelCache { } return fieldInfoCache.isCalculate(); } + + @Override + public void refreshIotFieldCache(SysIotModelField sysIotModelField) { + IotFieldInfoCache fieldInfoCache = new IotFieldInfoCache(); + fieldInfoCache.setAttributeCode(sysIotModelField.getAttributeCode()); + fieldInfoCache.setPorder(sysIotModelField.getPorder()); + fieldInfoCache.setAttributeName(sysIotModelField.getAttributeName()); + fieldInfoCache.setAttributeType(sysIotModelField.getAttributeType()); + fieldInfoCache.setHighspeed(sysIotModelField.getHighSpeed()); + fieldInfoCache.setDatatype(sysIotModelField.getDataType()); + fieldInfoCache.setLevel(sysIotModelField.getLevel()); + fieldInfoCache.setStateDesc(sysIotModelField.getStateDesc()); + iotFieldsMap.put(String.format("%d_%s", sysIotModelField.getIotModelId(), sysIotModelField.getAttributeCode()), fieldInfoCache); + } + + @Override + public void removeIotFieldCache(Long modelId, String attributeCode){ + iotFieldsMap.remove(String.format("%d_%s", modelId, attributeCode)); + } + + + @Override + public void refreshIotModelInfoIdMap(SysIotModel sysIotModel){ + IotModelInfoCache info = new IotModelInfoCache(); + info.setIotModelId(sysIotModel.getId()); + info.setIodModelCode(sysIotModel.getIotModelCode()); + iotModelInfoIdMap.put(sysIotModel.getId(), info); + } + + @Override + public void removeIotModelInfoIdMap(Long modelId) { + iotModelInfoIdMap.remove(modelId); + } + + @Override + public IotFieldInfoCache getIotFiledCache(Long modelId, String attr) { + return iotFieldsMap.get(String.format("%d_%s", modelId, attr)); + } } diff --git a/das/src/main/java/com/das/modules/equipment/service/impl/SysIotModelServiceImpl.java b/das/src/main/java/com/das/modules/equipment/service/impl/SysIotModelServiceImpl.java index 7e0a3b6c..29087a52 100644 --- a/das/src/main/java/com/das/modules/equipment/service/impl/SysIotModelServiceImpl.java +++ b/das/src/main/java/com/das/modules/equipment/service/impl/SysIotModelServiceImpl.java @@ -10,6 +10,7 @@ import com.das.common.config.SessionUtil; import com.das.common.exceptions.ServiceException; import com.das.common.utils.*; import com.das.modules.auth.domain.vo.SysUserVo; +import com.das.modules.cache.service.CacheService; import com.das.modules.data.service.impl.DataServiceImpl; import com.das.modules.equipment.domain.dto.SysIotModelDto; import com.das.modules.equipment.domain.dto.SysIotModelFieldDto; @@ -65,6 +66,9 @@ public class SysIotModelServiceImpl implements SysIotModelService { @Autowired SysRecordLogService sysRecordLogService; + @Autowired + CacheService cacheService; + public SysIotModelVo creatSysIotModel(SysIotModelDto sysIotModelDto) { SysIotModel sysIotModel = new SysIotModel(); BeanCopyUtils.copy(sysIotModelDto, sysIotModel); @@ -81,7 +85,9 @@ public class SysIotModelServiceImpl implements SysIotModelService { sysIotModel.setRevision(1); sysIotModelMapper.insert(sysIotModel); + //刷新缓存 addModelCache(sysIotModel); + cacheService.getIotModelCache().refreshIotModelInfoIdMap(sysIotModel); SysIotModelVo sysIotModelVo = new SysIotModelVo(); BeanCopyUtils.copy(sysIotModel, sysIotModelVo); sysIotModelVo.setIotModelCode(sysIotModelDto.getIotModelCode()); @@ -119,6 +125,8 @@ public class SysIotModelServiceImpl implements SysIotModelService { throw new RuntimeException("该物模型下面有类型,不能删除"); } sysIotModelMapper.deleteById(sysIotModelDto.getId()); + //刷新缓存 + cacheService.getIotModelCache().removeIotModelInfoIdMap(sysIotModelDto.getId()); deleteModelCache(sysIotModelDto.getId()); } @@ -184,6 +192,7 @@ public class SysIotModelServiceImpl implements SysIotModelService { sysIotModelFieldMapper.insert(sysIotModelField); //新增物模型属性缓存 + cacheService.getIotModelCache().refreshIotFieldCache(sysIotModelField); addModelFieldCache(sysIotModelField); SysIotModelFieldVo sysIotModelFieldVo = new SysIotModelFieldVo(); BeanCopyUtils.copy(sysIotModelField, sysIotModelFieldVo); @@ -216,6 +225,7 @@ public class SysIotModelServiceImpl implements SysIotModelService { if (!oldSysIotField.getAttributeCode().equals(sysIotModelField.getAttributeCode()) || !oldSysIotField.getDataType().equals(sysIotModelField.getDataType()) || Objects.equals(oldSysIotField.getHighSpeed(), sysIotModelField.getHighSpeed())) { //更新td表结构 updateTDStableOrColumn(sysIotModelField, oldSysIotField); + cacheService.getIotModelCache().refreshIotFieldCache(sysIotModelField); updateModelFieldCache(sysIotModelField, oldSysIotField); } sysIotModelFieldMapper.updateById(sysIotModelField); @@ -232,6 +242,7 @@ public class SysIotModelServiceImpl implements SysIotModelService { sysIotModelFieldMapper.deleteById(sysIotModelFieldDto.getId()); //删除物模型属性缓存 + cacheService.getIotModelCache().removeIotFieldCache(sysIotModelField.getIotModelId(), sysIotModelField.getAttributeCode()); deleteModelFieldCache(sysIotModelField); } @@ -488,6 +499,10 @@ public class SysIotModelServiceImpl implements SysIotModelService { } //新增pg数据库 sysIotModelFieldMapper.insertBatch(sysIotModelFieldList); + //刷新缓存 + for (SysIotModelField item : sysIotModelFieldList){ + cacheService.getIotModelCache().refreshIotFieldCache(item); + } } if (CollectionUtils.isNotEmpty(updateSysIotModelFieldList)) { for (SysIotModelField item : updateSysIotModelFieldList) { @@ -496,6 +511,7 @@ public class SysIotModelServiceImpl implements SysIotModelService { if (!oldSysIotField.getAttributeCode().equals(item.getAttributeCode()) && oldSysIotField.getDataType().equals(item.getDataType()) && Objects.equals(oldSysIotField.getHighSpeed(), item.getHighSpeed())) { //更新td表结构 updateTDStableOrColumn(item, oldSysIotField); + cacheService.getIotModelCache().refreshIotFieldCache(item); updateModelFieldCache(item, oldSysIotField); } } @@ -509,6 +525,7 @@ public class SysIotModelServiceImpl implements SysIotModelService { for (SysIotModelField item : delSysIotModelFieldList) { deleteTDStableOrColumn(item); sysIotModelFieldMapper.deleteById(item); + cacheService.getIotModelCache().removeIotFieldCache(item.getIotModelId(), item.getAttributeCode()); deleteModelFieldCache(item); } } diff --git a/das/src/main/java/com/das/modules/node/command/DeviceEventCommand.java b/das/src/main/java/com/das/modules/node/command/DeviceEventCommand.java index 3598a7c9..e8de4c2e 100644 --- a/das/src/main/java/com/das/modules/node/command/DeviceEventCommand.java +++ b/das/src/main/java/com/das/modules/node/command/DeviceEventCommand.java @@ -1,17 +1,17 @@ package com.das.modules.node.command; import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.das.common.exceptions.ServiceException; import com.das.common.utils.AdminRedisTemplate; import com.das.common.utils.StringUtils; import com.das.modules.cache.domain.DeviceInfoCache; +import com.das.modules.cache.domain.IotFieldInfoCache; import com.das.modules.cache.service.CacheService; import com.das.modules.data.domain.DeviceEventInfo; import com.das.modules.data.service.TDEngineService; -import com.das.modules.data.service.impl.DataServiceImpl; import com.das.modules.node.constant.NodeConstant; import com.das.modules.node.domain.bo.TerminalMessage; import com.das.modules.node.domain.vo.DeviceEventVo; -import com.das.modules.node.service.NodeMessageService; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -29,9 +29,6 @@ public class DeviceEventCommand implements BaseCommand{ @Autowired AdminRedisTemplate adminRedisTemplate; - @Autowired - private DataServiceImpl dataService; - @Autowired TDEngineService tdEngineService; @@ -72,18 +69,20 @@ public class DeviceEventCommand implements BaseCommand{ deviceEventInfo.setDeviceCode(deviceInfoCache.getDeviceCode()); deviceEventInfo.setFirstTriggeredCode(firstTriggeredCode); String eventType = getEventType(item.getEventType()); - String model = dataService.deviceModelMap.get(item.getDeviceId()); - if (StringUtils.isEmpty(model)) { + Long iotModelId = deviceInfoCache.getIotModelId(); + if (iotModelId == null) { log.debug("未查询到物模型code,设备id:{}", item.getDeviceId()); } - String fieldName = dataService.fieldCodeNameMap.get(model).get(item.getAttrCode()); - if (StringUtils.isEmpty(fieldName)) { - log.debug("未查询到物模型属性code,设备id:{}", item.getDeviceId()); + IotFieldInfoCache iotFiledCache = cacheService.getIotModelCache().getIotFiledCache(iotModelId, item.getAttrCode()); + if (iotFiledCache == null) { + log.debug("未查询到物模型属性,设备id:{},属性AttrCode:{}", item.getDeviceId(),item.getAttrCode()); + throw new ServiceException("未查询到物模型属性,设备id:"+item.getDeviceId()+",属性AttrCode:"+item.getAttrCode()); } + String fieldName = iotFiledCache.getAttributeName(); deviceEventInfo.setEventType(item.getEventType()); deviceEventInfo.setConfirmed(0); if (!StringUtils.isEmpty(eventType) && eventType.equals("遥信变位")) { - String stateDesc = dataService.stateDescMap.get(model).get(item.getAttrCode()); + String stateDesc = iotFiledCache.getStateDesc(); if (item.getAttrValue().equals(0)) { deviceEventInfo.setEventText(item.getAttrCode() + fieldName + " 复归"); if (StringUtils.isNotEmpty(stateDesc)) { @@ -97,7 +96,7 @@ public class DeviceEventCommand implements BaseCommand{ List descList = Arrays.stream(stateDesc.split("\\|")).toList(); deviceEventInfo.setEventText(item.getAttrCode() + fieldName + descList.get(1)); } - Integer level = dataService.eventLevelMap.get(model).get(item.getAttrCode()); + Integer level = iotFiledCache.getLevel(); log.debug("level:{}", level); log.debug("fieldname{}", fieldName); deviceEventInfo.setEventLevel(level == null ? 0 : level); From dacf6eda316f5d47f571963a054bb5787842e79d Mon Sep 17 00:00:00 2001 From: yu Date: Thu, 9 Jan 2025 15:26:22 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E5=AF=BC=E5=87=BAexcel,=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E5=9B=BE=E8=A1=A8;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- das/pom.xml | 6 - .../impl/StatisticalAnalysisServiceImpl.java | 130 ++---------------- 2 files changed, 13 insertions(+), 123 deletions(-) diff --git a/das/pom.xml b/das/pom.xml index aea4ba76..6666105e 100644 --- a/das/pom.xml +++ b/das/pom.xml @@ -32,7 +32,6 @@ 3.4.4 5.4.3 8.4.3 - 1.5.3 @@ -217,11 +216,6 @@ minio ${minio.version} - - org.jfree - jfreechart - ${jfreechart.version} - diff --git a/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java b/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java index 22f6c198..b3ee1b0a 100644 --- a/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java +++ b/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java @@ -28,35 +28,18 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xddf.usermodel.chart.*; import org.apache.poi.xssf.usermodel.XSSFChart; -import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFDrawing; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.jetbrains.annotations.NotNull; -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartUtils; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.axis.CategoryAxis; -import org.jfree.chart.axis.CategoryLabelPositions; -import org.jfree.chart.plot.CategoryPlot; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.renderer.category.CategoryItemRenderer; -import org.jfree.chart.title.LegendTitle; -import org.jfree.chart.title.TextTitle; -import org.jfree.data.category.DefaultCategoryDataset; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.awt.*; -import java.io.File; -import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; -import java.util.List; import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -105,13 +88,9 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic List> dataList = new ArrayList<>(); // 遍历数据,填充Excel数据集 setTrendAnalyseExcelValue(mapsList, dataList); - //获取图表类别集 - List chartKey = getCharKey(map); ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); //设置Excel样式 setExcelStyle(writer, map, dataList); - //生成折线图 - addChartToExcel(writer,dataList,StatisticalAnalysisConstant.TREND_ANALYSE,chartKey); //下载Excel downloadExcel(response, writer,StatisticalAnalysisConstant.TREND_ANALYSE); } @@ -150,18 +129,9 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic setPowerCurveExcelValue(resultMap, dataList, curveItemEntitieList); //获取功率曲线的列 LinkedHashMap map = getPowerCurveColumnName(param); - //获取图表类别集 - List chartKey = getCharKey(map); ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); //设置Excel样式 setExcelStyle(writer, map, dataList); - //生成折线图 - if (param.getDisplayCurve()==1){ - addChartToExcel(writer,dataList,StatisticalAnalysisConstant.POWER_CURVE,chartKey); - }else { - //生成散点图 - addScattersChartToExcel(writer,dataList,StatisticalAnalysisConstant.POWER_CURVE,chartKey); - } //下载Excel downloadExcel(response, writer,StatisticalAnalysisConstant.POWER_CURVE); } @@ -191,15 +161,11 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic //自定义别名 别名的key和实体类中的名称要对应上! LinkedHashMap map = gettrendContrastColumnName(param); List> dataList = new ArrayList<>(); - //图表类别集 - List charKey = getCharKey(map); // 遍历数据,将数据添加到dataList中 setTrendContrastExcelValue(maps, dataList); ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); //设置Excel样式 setExcelStyle(writer, map, dataList); - //生成折线图 - addChartToExcel(writer,dataList,StatisticalAnalysisConstant.TREND_CONTRAST,charKey); //下载Excel downloadExcel(response, writer,StatisticalAnalysisConstant.TREND_CONTRAST); } @@ -284,22 +250,7 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic } } - /** - * 获取图表类别集 - * @param map Excel的列 - * @return 图表类别集 - */ - private List getCharKey(LinkedHashMap map) { - //获取图表类别集 - List chartKey = new ArrayList<>(); - for (Map.Entry stringStringEntry : map.entrySet()) { - String value = stringStringEntry.getValue(); - if (!value.contains("时间")){ - chartKey.add(value); - } - } - return chartKey; - } + /** * 趋势对比填充Excel数据集 @@ -542,75 +493,20 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic } /** - * 使用JFreeChart生成折线图(图片),已弃用 - * @param data excel数据集 - * @param writer excel对象 - * @param dataset 图表数据集 - * @param titleStr 标题 + * 获取图表类别集 + * @param map Excel的列 + * @return 图表类别集 */ - private void createChart(List> data, ExcelWriter writer, - DefaultCategoryDataset dataset, String titleStr) { - // 获取Sheet对象 - XSSFSheet xssfSheet = (XSSFSheet) writer.getSheet(); - Workbook workbook = writer.getWorkbook(); - JFreeChart chart = ChartFactory.createLineChart( - titleStr, // 图表标题 - "", // 横轴标签 - "", // 纵轴标签 - dataset, // 数据集 - PlotOrientation.VERTICAL, // 图表方向 - true, // 是否显示图例 - true, // 是否使用工具提示 - false // 是否生成URL链接 - ); - // 设置图表标题的字体 - TextTitle title = chart.getTitle(); - title.setFont(new java.awt.Font("SimSun", java.awt.Font.BOLD, 16)); - // 获取图表的绘图区域 - CategoryPlot plot = chart.getCategoryPlot(); - // 设置横轴标签 - CategoryAxis domainAxis = plot.getDomainAxis(); - domainAxis.setLabelFont(new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12)); - domainAxis.setMaximumCategoryLabelLines(1); // 可以控制标签行数 - domainAxis.setCategoryMargin(3); // 控制类别之间的间距 - domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 旋转横轴标签为45度,90度为:UP_90 - domainAxis.setLabelFont(new Font("SansSerif", Font.PLAIN, 7));//调整字体大小 -// if (data.size() > 50) { -// domainAxis.setVisible(false); // 隐藏横坐标 -// } - // 设置图例的字体 - LegendTitle legend = chart.getLegend(); - if (legend != null) { - legend.setItemFont(new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12)); + private List getCharKey(LinkedHashMap map) { + //获取图表类别集 + List chartKey = new ArrayList<>(); + for (Map.Entry stringStringEntry : map.entrySet()) { + String value = stringStringEntry.getValue(); + if (!value.contains("时间")){ + chartKey.add(value); + } } - // 设置绘图区域的背景颜色 - plot.setBackgroundPaint(Color.WHITE); - // 设置绘图区域的边框 - plot.setOutlinePaint(Color.LIGHT_GRAY); - plot.setOutlineVisible(true); - // 设置网格线的颜色 - plot.setDomainGridlinePaint(Color.LIGHT_GRAY); - plot.setRangeGridlinePaint(Color.LIGHT_GRAY); - // 设置线条的宽度 - CategoryItemRenderer renderer1 = plot.getRenderer(); - renderer1.setSeriesStroke(0, new BasicStroke(2.0f)); // 设置线条宽度 - // 将图表保存为 PNG 文件 - String chartFilePath = "lineChart.png"; - // 调整图表尺寸 - int width = 750; - int height = 400; - try { - ChartUtils.saveChartAsPNG(new File(chartFilePath), chart, width, height); - byte[] bytes = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(chartFilePath)); - int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); - // 计算数据的最后一行,创建图表插入位置的锚点 - XSSFClientAnchor anchor = new XSSFClientAnchor(0, 1, 0, 1, 0, data.size() + 2, 15, data.size() + 30); - XSSFDrawing drawing = xssfSheet.createDrawingPatriarch(); - drawing.createPicture(anchor, pictureIdx); - } catch (IOException e) { - throw new ServiceException("图表保存失败==" + e); - } - + return chartKey; } /** From 5c2ff8bb3d360b527ca64c42a92930a41458409c Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Fri, 10 Jan 2025 09:12:01 +0800 Subject: [PATCH 03/11] update --- das-dn/CMakeLists.txt | 2 +- das-dn/cmg/ry.cpp | 8 ++++++ das-dn/comm/process.cpp | 13 +++------- das-dn/hostadsbf/hostadsbf.cpp | 25 ++++++++----------- das-dn/hostadsbf/hostadsbf.h | 2 +- das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp | 12 ++++----- das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h | 1 + 7 files changed, 31 insertions(+), 32 deletions(-) diff --git a/das-dn/CMakeLists.txt b/das-dn/CMakeLists.txt index 00ec2e22..7d1f7e6b 100644 --- a/das-dn/CMakeLists.txt +++ b/das-dn/CMakeLists.txt @@ -20,7 +20,7 @@ if (USE_SQLITE3) endif () endif () -set (CMAKE_BUILD_TYPE Release) +# set (CMAKE_BUILD_TYPE Release) option (USE_32BITS "Build 32Bits application?" OFF) if (USE_32BITS) diff --git a/das-dn/cmg/ry.cpp b/das-dn/cmg/ry.cpp index 007f22b6..6ca930e9 100644 --- a/das-dn/cmg/ry.cpp +++ b/das-dn/cmg/ry.cpp @@ -2829,10 +2829,12 @@ void CRYDevice::heart_beat(int status) #endif jsonValue["linkId"] = linkId; jsonValue["online"] = (config.processes[i].real_softdog >= PROCESS_WATCHDOG_TIME) ? false : true; +#if 1 jsonValue["real"] = (config.processes[i].real_softdog >= PROCESS_WATCHDOG_TIME) ? false : true; if ((config.processes[i].state & 0x20) == 0x20) { jsonValue["ftp"] = (config.processes[i].real_softdog >= PROCESS_WATCHDOG_TIME) ? false : true; } +#endif jsonLink.append(jsonValue); } } @@ -2853,6 +2855,12 @@ void CRYDevice::heart_beat(int status) #endif jsonValue["deviceId"] = deviceId; jsonValue["online"] = (config.units[i].real_softdog >= UNIT_WATCHDOG_TIME) ? false : true; +#if 0 + jsonValue["real"] = (config.units[i].real_softdog >= UNIT_WATCHDOG_TIME) ? false : true; + if ((config.units[i].state & 0x20) == 0x20) { + jsonValue["ftp"] = (config.units[i].real_softdog >= UNIT_WATCHDOG_TIME) ? false : true; + } +#endif jsonDevice.append(jsonValue); } } diff --git a/das-dn/comm/process.cpp b/das-dn/comm/process.cpp index 994baf0b..0f1b3905 100644 --- a/das-dn/comm/process.cpp +++ b/das-dn/comm/process.cpp @@ -1740,15 +1740,8 @@ BOOLEAN CProcess::OnCreated(int id) void CProcess::Destroy(void) { m_bRunFlag = FALSE; - - char name[16]; - memset(name, '\0', sizeof(name)); - if (pthread_getname_np(m_pid, name, sizeof(name)) != 0) - { - memset(name, '\0', sizeof(name)); - } - - vLog(LOG_DEBUG, "waiting for protocol thread [%d,%s] destroy.\n", m_nProcess, (name[0] != '\0') ? name : "unknow"); + + vLog(LOG_DEBUG, "waiting for protocol thread [%d,%s] destroy.\n", m_nProcess, config.processes[m_nProcess].name); pthread_join(m_pid, NULL); int i = 0; @@ -1757,7 +1750,7 @@ void CProcess::Destroy(void) DestroyItem(i, FALSE); } - vLog(LOG_DEBUG, "current protocol thread [%d,%s] is destroyed.\n", m_nProcess, (name[0] != '\0') ? name : "unknow"); + vLog(LOG_DEBUG, "current protocol thread [%d,%s] is destroyed.\n", m_nProcess, config.processes[m_nProcess].name); } BOOLEAN CProcess::Run(void) diff --git a/das-dn/hostadsbf/hostadsbf.cpp b/das-dn/hostadsbf/hostadsbf.cpp index ffb32b54..2e13f739 100644 --- a/das-dn/hostadsbf/hostadsbf.cpp +++ b/das-dn/hostadsbf/hostadsbf.cpp @@ -703,15 +703,10 @@ CHostADSBFProcess::~CHostADSBFProcess() fwrite(&m_currentDirStartFileNo, sizeof(LONG), 1, pf); fclose(pf); } - char name[16]; - memset(name, '\0', sizeof(name)); - if (pthread_getname_np(m_cpid, name, sizeof(name)) != 0) - { - memset(name, '\0', sizeof(name)); - } - vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (name[0] != '\0') ? name : "unknow"); + + vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow"); pthread_join(m_cpid, NULL); - vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (name[0] != '\0') ? name : "unknow"); + vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow"); } } @@ -857,14 +852,17 @@ BOOLEAN CHostADSBFProcess::OnPreCreate(int id) //需要给单元添加一个是否有ftp数据的标识 int uid = GetCurUnitID(); - if (uid < 0 || uid >= UNIT_NUM) return FALSE; + //if (uid < 0 || uid >= UNIT_NUM) return FALSE; if (m_bHaveFTP) { - config.units[uid].state |= 0x20; //存在ftp标识 + if (uid >= 0 && uid < UNIT_NUM) + { + config.units[uid].state |= 0x20; //存在ftp标识 + } config.processes[id].state |= 0x20; } calc(); - //vLog(LOG_DEBUG, "%s local ip is: %s, netid is: %s, remote ip is: %s, and netid is: %s\n", m_pidName.c_str(), m_localIp.c_str(), m_localNetId.c_str(), m_remoteIp.c_str(), m_remoteNetId.c_str()); + vLog(LOG_DEBUG, "%s local ip is: %s, netid is: %s, remote ip is: %s, and netid is: %s\n", m_pidName.c_str(), m_localIp.c_str(), m_localNetId.c_str(), m_remoteIp.c_str(), m_remoteNetId.c_str()); m_turbine = NULL; m_bRouteAdded = FALSE; @@ -911,9 +909,8 @@ BOOLEAN CHostADSBFProcess::OnPreCreate(int id) vLog(LOG_ERROR, "ads create ryftp_process error(%d,%s).\n", errno, strerror(errno)); return TRUE; } - char name[17]; - snprintf(name, 16, "%s_ftp", m_pidName.c_str()); - pthread_setname_np(m_cpid, name); + snprintf(m_cpidName, 16, "%s_ftp", m_pidName.c_str()); + pthread_setname_np(m_cpid, m_cpidName); pthread_attr_destroy(&attr); } diff --git a/das-dn/hostadsbf/hostadsbf.h b/das-dn/hostadsbf/hostadsbf.h index 176429a3..e273c1cf 100644 --- a/das-dn/hostadsbf/hostadsbf.h +++ b/das-dn/hostadsbf/hostadsbf.h @@ -103,8 +103,8 @@ private: public: std::string m_pidName; - BOOLEAN m_bHaveFTP; //存在FTP协议 + char m_cpidName[16]; //ftp参数信息 char m_user[64]; diff --git a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp index 8ebf3ae4..2f855c1a 100644 --- a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp +++ b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp @@ -794,9 +794,9 @@ CHostModbusTcpBFProcess::~CHostModbusTcpBFProcess() { memset(name, '\0', sizeof(name)); } - vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (name[0] != '\0') ? name : "unknow"); + vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow"); pthread_join(m_cpid, NULL); - vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (name[0] != '\0') ? name : "unknow"); + vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow"); } } @@ -1175,13 +1175,13 @@ BOOLEAN CHostModbusTcpBFProcess::OnPreCreate(int id) pthread_attr_setstacksize(&attr, MEMERY_1M); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - if (pthread_create(&m_cpid, &attr, ryftp_process, this) < 0) { + if (pthread_create(&m_cpid, &attr, ryftp_process, this) < 0) + { vLog(LOG_ERROR, "rymodbus create ryftp_process error(%d,%s).\n", errno, strerror(errno)); return TRUE; } - char name[17]; - snprintf(name, 16, "%s_ftp", m_pidName.c_str()); - pthread_setname_np(m_cpid, name); + snprintf(m_cpidName, 16, "%s_ftp", m_pidName.c_str()); + pthread_setname_np(m_cpid, m_cpidName); pthread_attr_destroy(&attr); } diff --git a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h index 770ca85a..a8afce0b 100644 --- a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h +++ b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h @@ -65,6 +65,7 @@ private: public: std::string m_pidName; BOOLEAN m_bHaveFTP; //存在FTP协议 + char m_cpidName[16]; //ftp参数信息 char m_user[64]; From 71e468624556ad4626c1ce8324fe03957fc3eb76 Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Mon, 13 Jan 2025 09:26:27 +0800 Subject: [PATCH 04/11] update --- das-dn/hostadsbf/hostadsbf.h | 1 + das-dn/third_party/AdsLib/AdsDevice.cpp | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/das-dn/hostadsbf/hostadsbf.h b/das-dn/hostadsbf/hostadsbf.h index e273c1cf..a221b098 100644 --- a/das-dn/hostadsbf/hostadsbf.h +++ b/das-dn/hostadsbf/hostadsbf.h @@ -33,6 +33,7 @@ struct myAdsVariable { { if (!m_Route.IsConnected()) return FALSE; uint32_t bytesRead = 0; + if (m_Handle.get() == 0) return FALSE; auto error = m_Route.ReadReqEx2(m_IndexGroup, *m_Handle, size, diff --git a/das-dn/third_party/AdsLib/AdsDevice.cpp b/das-dn/third_party/AdsLib/AdsDevice.cpp index 66011c65..00a5ef5f 100644 --- a/das-dn/third_party/AdsLib/AdsDevice.cpp +++ b/das-dn/third_party/AdsLib/AdsDevice.cpp @@ -108,7 +108,7 @@ AdsHandle AdsDevice::GetHandle(const uint32_t offset) const AdsHandle AdsDevice::GetHandle(const std::string& symbolName) const { - if(m_Connected == true) + if (m_Connected == true) { uint32_t handle = 0; uint32_t bytesRead = 0; @@ -121,9 +121,11 @@ AdsHandle AdsDevice::GetHandle(const std::string& symbolName) const ); if (error || (sizeof(handle) != bytesRead)) { - LOG_ERROR("AdsDevice GetSymbolHandle is failed: "< Date: Mon, 13 Jan 2025 09:43:46 +0800 Subject: [PATCH 05/11] update --- das-dn/hostadsbf/hostadsbf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/das-dn/hostadsbf/hostadsbf.h b/das-dn/hostadsbf/hostadsbf.h index a221b098..1819952c 100644 --- a/das-dn/hostadsbf/hostadsbf.h +++ b/das-dn/hostadsbf/hostadsbf.h @@ -33,7 +33,7 @@ struct myAdsVariable { { if (!m_Route.IsConnected()) return FALSE; uint32_t bytesRead = 0; - if (m_Handle.get() == 0) return FALSE; + if (*m_Handle.get() == 0) return FALSE; auto error = m_Route.ReadReqEx2(m_IndexGroup, *m_Handle, size, From 5a4928b4d2b4add99fbebd4ec93194dd0ad2b69f Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Mon, 13 Jan 2025 09:48:06 +0800 Subject: [PATCH 06/11] update --- das-dn/hostadsbf/hostadsbf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/das-dn/hostadsbf/hostadsbf.h b/das-dn/hostadsbf/hostadsbf.h index 1819952c..0f9eb423 100644 --- a/das-dn/hostadsbf/hostadsbf.h +++ b/das-dn/hostadsbf/hostadsbf.h @@ -33,7 +33,7 @@ struct myAdsVariable { { if (!m_Route.IsConnected()) return FALSE; uint32_t bytesRead = 0; - if (*m_Handle.get() == 0) return FALSE; + //if (*m_Handle.get() == 0) return FALSE; auto error = m_Route.ReadReqEx2(m_IndexGroup, *m_Handle, size, From 1b455c7e3baea44646d2f3ed071e81688eed2c1b Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Mon, 13 Jan 2025 10:13:48 +0800 Subject: [PATCH 07/11] update --- das-dn/hostadsbf/hostadsbf.cpp | 4 ++++ das-dn/hostadsbf/hostadsbf.h | 4 +++- das-dn/third_party/AdsLib/AdsDevice.cpp | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/das-dn/hostadsbf/hostadsbf.cpp b/das-dn/hostadsbf/hostadsbf.cpp index 2e13f739..c9079503 100644 --- a/das-dn/hostadsbf/hostadsbf.cpp +++ b/das-dn/hostadsbf/hostadsbf.cpp @@ -743,6 +743,7 @@ BOOLEAN CHostADSBFProcess::calc(void) pData = GetUnitYCParamByPoint(uid, n); if (pData[4] == 1) continue; registerAddr = MAKEWORD(pData[0], pData[1]); + if (registerAddr <= 0) continue; if (registerAddr < DATA_BLOCK_BOUNDARY) { if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE; @@ -770,6 +771,7 @@ BOOLEAN CHostADSBFProcess::calc(void) pData = GetUnitYMParamByPoint(uid, n); if (pData[4] == 1) continue; registerAddr = MAKEWORD(pData[0], pData[1]); + if (registerAddr <= 0) continue; if (registerAddr < DATA_BLOCK_BOUNDARY) { if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE; @@ -797,6 +799,7 @@ BOOLEAN CHostADSBFProcess::calc(void) pData = GetUnitYXParamByPoint(uid, n); if (pData[4] == 1) continue; registerAddr = MAKEWORD(pData[0], pData[1]); + if (registerAddr <= 0) continue; value_type = pData[2]; if (registerAddr < DATA_BLOCK_BOUNDARY) { @@ -1028,6 +1031,7 @@ BOOLEAN CHostADSBFProcess::readFileID() myAdsVariable myPathInfoInvalid {*m_turbine, ".gwPathInfoInvalid"}; if (!myPathInfoInvalid.Read(2, &wPathInfoInvalid)) { + vLog(LOG_ERROR, "Read .gwPathInfoInvalid error.\n"); m_bRouteAdded = FALSE; delete m_turbine; m_turbine = NULL; diff --git a/das-dn/hostadsbf/hostadsbf.h b/das-dn/hostadsbf/hostadsbf.h index 0f9eb423..fdf86aba 100644 --- a/das-dn/hostadsbf/hostadsbf.h +++ b/das-dn/hostadsbf/hostadsbf.h @@ -33,7 +33,9 @@ struct myAdsVariable { { if (!m_Route.IsConnected()) return FALSE; uint32_t bytesRead = 0; - //if (*m_Handle.get() == 0) return FALSE; + if (*m_Handle.get() == 0xffffffff) { + return FALSE; + } auto error = m_Route.ReadReqEx2(m_IndexGroup, *m_Handle, size, diff --git a/das-dn/third_party/AdsLib/AdsDevice.cpp b/das-dn/third_party/AdsLib/AdsDevice.cpp index 00a5ef5f..cbb1a44e 100644 --- a/das-dn/third_party/AdsLib/AdsDevice.cpp +++ b/das-dn/third_party/AdsLib/AdsDevice.cpp @@ -123,6 +123,7 @@ AdsHandle AdsDevice::GetHandle(const std::string& symbolName) const if (error || (sizeof(handle) != bytesRead)) { LOG_ERROR("AdsDevice GetSymbolHandle is failed: " << symbolName << "."); //throw AdsException(error); + return {new uint32_t {0xffffffff}, {[](uint32_t){ return 0; }}}; } else { From fe20bf1e3429449dcc8652ff72770c97a795fb2a Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Mon, 13 Jan 2025 10:18:26 +0800 Subject: [PATCH 08/11] update --- das-dn/hostadsbf/hostadsbf.cpp | 4 ++-- das-dn/hostadsbf/hostadsbf.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/das-dn/hostadsbf/hostadsbf.cpp b/das-dn/hostadsbf/hostadsbf.cpp index c9079503..f50b67c5 100644 --- a/das-dn/hostadsbf/hostadsbf.cpp +++ b/das-dn/hostadsbf/hostadsbf.cpp @@ -1027,7 +1027,7 @@ BOOLEAN CHostADSBFProcess::readFileID() AdsVariable wFirstFileNoRecoverable {*m_turbine, ".gwFirstFileNoRecoverable"}; //vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoRecoverable); #else - WORD wPathInfoInvalid; + WORD wPathInfoInvalid = 0; myAdsVariable myPathInfoInvalid {*m_turbine, ".gwPathInfoInvalid"}; if (!myPathInfoInvalid.Read(2, &wPathInfoInvalid)) { @@ -1108,7 +1108,7 @@ BOOLEAN CHostADSBFProcess::readFileID() m_iv = (WORD)wPathInfoInvalid; if (m_iv) { vLog(LOG_DEBUG, "路径信息无效\n"); - return FALSE; + return TRUE; } //当前文件夹路径名 m_currentDirNo = (DWORD)wCurrentFolderNo; diff --git a/das-dn/hostadsbf/hostadsbf.h b/das-dn/hostadsbf/hostadsbf.h index fdf86aba..c24b4e70 100644 --- a/das-dn/hostadsbf/hostadsbf.h +++ b/das-dn/hostadsbf/hostadsbf.h @@ -34,7 +34,7 @@ struct myAdsVariable { if (!m_Route.IsConnected()) return FALSE; uint32_t bytesRead = 0; if (*m_Handle.get() == 0xffffffff) { - return FALSE; + return TRUE; } auto error = m_Route.ReadReqEx2(m_IndexGroup, *m_Handle, From 2910ea7ee03ff1532de8f274216c3767d45cd1be Mon Sep 17 00:00:00 2001 From: zhouhuang Date: Mon, 13 Jan 2025 10:20:13 +0800 Subject: [PATCH 09/11] update --- das-dn/hostadsbf/hostadsbf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/das-dn/hostadsbf/hostadsbf.cpp b/das-dn/hostadsbf/hostadsbf.cpp index f50b67c5..0c11fe5d 100644 --- a/das-dn/hostadsbf/hostadsbf.cpp +++ b/das-dn/hostadsbf/hostadsbf.cpp @@ -1027,7 +1027,7 @@ BOOLEAN CHostADSBFProcess::readFileID() AdsVariable wFirstFileNoRecoverable {*m_turbine, ".gwFirstFileNoRecoverable"}; //vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoRecoverable); #else - WORD wPathInfoInvalid = 0; + WORD wPathInfoInvalid = 1; myAdsVariable myPathInfoInvalid {*m_turbine, ".gwPathInfoInvalid"}; if (!myPathInfoInvalid.Read(2, &wPathInfoInvalid)) { @@ -1105,8 +1105,8 @@ BOOLEAN CHostADSBFProcess::readFileID() } #endif - m_iv = (WORD)wPathInfoInvalid; - if (m_iv) { + m_iv = (int)wPathInfoInvalid; + if (m_iv == 1) { vLog(LOG_DEBUG, "路径信息无效\n"); return TRUE; } From 160650c0862c4077191b66356db6385e1c48f412 Mon Sep 17 00:00:00 2001 From: huguanghan Date: Mon, 13 Jan 2025 17:33:39 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/data/service/TDEngineService.java | 3 + .../data/service/impl/DataServiceImpl.java | 1 + .../service/impl/ExportTdDataServiceImpl.java | 120 ++++++++++++++++++ das/src/main/resources/application-dev.yml | 4 +- das/src/main/resources/application.yml | 4 +- 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java diff --git a/das/src/main/java/com/das/modules/data/service/TDEngineService.java b/das/src/main/java/com/das/modules/data/service/TDEngineService.java index 184ed25a..625ab571 100644 --- a/das/src/main/java/com/das/modules/data/service/TDEngineService.java +++ b/das/src/main/java/com/das/modules/data/service/TDEngineService.java @@ -67,6 +67,9 @@ public class TDEngineService { } } + public HikariDataSource getHikariDataSource(){ + return hikariDataSource; + } /** * 创建超级表 */ diff --git a/das/src/main/java/com/das/modules/data/service/impl/DataServiceImpl.java b/das/src/main/java/com/das/modules/data/service/impl/DataServiceImpl.java index e88d9d07..3495fd23 100644 --- a/das/src/main/java/com/das/modules/data/service/impl/DataServiceImpl.java +++ b/das/src/main/java/com/das/modules/data/service/impl/DataServiceImpl.java @@ -25,6 +25,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StopWatch; +import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; diff --git a/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java b/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java new file mode 100644 index 00000000..4bd1aecc --- /dev/null +++ b/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java @@ -0,0 +1,120 @@ +package com.das.modules.data.service.impl; + +import cn.hutool.core.util.ZipUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.das.modules.data.service.TDEngineService; +import com.das.modules.equipment.entity.SysEquipment; +import com.das.modules.equipment.mapper.SysEquipmentMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.StopWatch; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +public class ExportTdDataServiceImpl { + + @Autowired + SysEquipmentMapper sysEquipmentMapper; + + @Autowired + private TDEngineService tdEngineService; + + @Value("${zipUrl}") + private String fileUrl; + + + public void exportDataCsvZip() throws IOException, SQLException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start("导出风机数据zip"); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_MONTH, -1); + String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()); + + //获取所有风机数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("object_type", 10002); + List sysEquipments = sysEquipmentMapper.selectList(queryWrapper); + //获取临时目录文件路径 + String tempDir = String.valueOf(Files.createTempDirectory(null)); + File zipFile = new File(fileUrl + "/data_"+yesterday+".zip"); + List fileList = new ArrayList<>(); + try { + for (SysEquipment item : sysEquipments) { + + String hTableName = "h" + item.getId(); + String lTableName = "l" + item.getId(); + File fileHighSpeed = new File(tempDir +"/" + "h_"+item.getCode()+"_"+yesterday + ".csv"); + File fileLowSpeed = new File(tempDir +"/" + "l_"+item.getCode()+"_"+yesterday + ".csv"); + getYesterdayData(hTableName, yesterday, fileHighSpeed.getPath()); + getYesterdayData(lTableName, yesterday, fileLowSpeed.getPath()); + fileList.add(fileLowSpeed); + fileList.add(fileHighSpeed); + } + //压缩文件 + // 将文件添加到压缩文件中 + ZipUtil.zip(zipFile, false, fileList.toArray(new File[0])); + stopWatch.stop(); + log.debug(stopWatch.prettyPrint(TimeUnit.SECONDS)); + }catch (Exception e){ + log.error("导出风机数据zip失败{}",e); + } +// finally { +// if (!CollectionUtils.isEmpty(fileList)){ +// FileUtil.del(new File(fileList.get(0).getParent())); +// } +// } + + } + + public void getYesterdayData(String tableName, String time, String csvFilePath) { + // TDengine 查询语句 + String query = "SELECT * FROM " + tableName + " WHERE updatetime >= '" + time + " 00:00:00' AND updatetime < '" + time + " 23:59:59.999'"; + try (Connection conn = tdEngineService.getHikariDataSource().getConnection(); + Statement smt = conn.createStatement(); + ResultSet rs = smt.executeQuery(query)) { + writeResultSetToCsv(rs, csvFilePath); + }catch (Exception e){ + log.error(tableName +"获取数据异常{}",e); + } + + } + + private void writeResultSetToCsv(ResultSet resultSet, String csvFilePath) throws IOException, SQLException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(csvFilePath))) { + // 写入列名 + ResultSetMetaData metaData = resultSet.getMetaData(); + int columnCount = metaData.getColumnCount(); + for (int i = 1; i <= columnCount; i++) { + writer.write(metaData.getColumnName(i)); + if (i < columnCount) writer.write(","); + } + writer.newLine(); + + // 写入数据 + while (resultSet.next()) { + for (int i = 1; i <= columnCount; i++) { + String value = resultSet.getString(i); + writer.write(value == null ? "" : resultSet.getString(i)); + if (i < columnCount) writer.write(","); + } + writer.newLine(); + } + }catch (Exception e){ + log.error("数据写入csv文件失败{}",e); + } + } +} diff --git a/das/src/main/resources/application-dev.yml b/das/src/main/resources/application-dev.yml index bb481740..1c1a88fb 100644 --- a/das/src/main/resources/application-dev.yml +++ b/das/src/main/resources/application-dev.yml @@ -110,4 +110,6 @@ minio: url: http://192.168.109.187:9000 bucket: das accessKey: das - secretKey: zaq12WSX \ No newline at end of file + secretKey: zaq12WSX + +zipUrl: /log/zip/ \ No newline at end of file diff --git a/das/src/main/resources/application.yml b/das/src/main/resources/application.yml index cdd4455a..4dcd6bb7 100644 --- a/das/src/main/resources/application.yml +++ b/das/src/main/resources/application.yml @@ -113,4 +113,6 @@ minio: bucket: das publicBucket: das-dock accessKey: das - secretKey: zaq12WSX \ No newline at end of file + secretKey: zaq12WSX + +zipUrl: /log/zip/ \ No newline at end of file From 6c50871947c1c150781b2c7212912521b27e3959 Mon Sep 17 00:00:00 2001 From: huguanghan Date: Mon, 13 Jan 2025 17:35:33 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/service/impl/ExportTdDataServiceImpl.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java b/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java index 4bd1aecc..a9d9754b 100644 --- a/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java +++ b/das/src/main/java/com/das/modules/data/service/impl/ExportTdDataServiceImpl.java @@ -1,5 +1,6 @@ package com.das.modules.data.service.impl; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ZipUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.das.modules.data.service.TDEngineService; @@ -9,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.util.StopWatch; import java.io.BufferedWriter; @@ -72,11 +74,11 @@ public class ExportTdDataServiceImpl { }catch (Exception e){ log.error("导出风机数据zip失败{}",e); } -// finally { -// if (!CollectionUtils.isEmpty(fileList)){ -// FileUtil.del(new File(fileList.get(0).getParent())); -// } -// } + finally { + if (!CollectionUtils.isEmpty(fileList)){ + FileUtil.del(new File(fileList.get(0).getParent())); + } + } }