diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java index eb037d9..44a1929 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java @@ -31,6 +31,9 @@ public class ExcelUtils { */ public static void write(HttpServletResponse response, String filename, String sheetName, Class head, List data) throws IOException { + response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename)); +// response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + response.setContentType("application/vnd.opencmlformats-officedocument.spreadsheetml.sheet"); // 输出 Excel EasyExcel.write(response.getOutputStream(), head) .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 @@ -39,8 +42,10 @@ public class ExcelUtils { .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度 .sheet(sheetName).doWrite(data); // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了 - response.addHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename)); - response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename)); +// response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + response.setContentType("application/vnd.opencmlformats-officedocument.spreadsheetml.sheet"); + } public static List read(MultipartFile file, Class head) throws IOException { diff --git a/yudao-module-alert/yudao-module-alert-biz/pom.xml b/yudao-module-alert/yudao-module-alert-biz/pom.xml index ebed9cf..6eac1ef 100644 --- a/yudao-module-alert/yudao-module-alert-biz/pom.xml +++ b/yudao-module-alert/yudao-module-alert-biz/pom.xml @@ -53,6 +53,15 @@ cn.iocoder.boot yudao-spring-boot-starter-mybatis + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java index 4cc0147..e5002bb 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java @@ -1,25 +1,27 @@ package cn.iocoder.yudao.module.alert.controller.admin.exa; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAHttp; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAPageReqVO; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAVO; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.*; import cn.iocoder.yudao.module.alert.service.exa.EXAService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.net.URISyntaxException; +import java.util.Arrays; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -36,19 +38,91 @@ public class EXAController { @GetMapping("/page") @Operation(summary = "获取测点分页列表") - @PreAuthorize("@ss.hasPermission('system:dept:query')") + @PreAuthorize("@ss.hasPermission('alert:exa:query')") public CommonResult> getEXAList(EXAPageReqVO reqVO) throws IOException, URISyntaxException { PageResult pageResult = exaService.getEXAPage(reqVO); return success(BeanUtils.toBean(pageResult, EXAHttp.class)); } - @GetMapping("/now") - @Operation(summary = "获取带EXA测点实时值的列表") - @PreAuthorize("@ss.hasPermission('system:dept:query')") - public CommonResult> getNowData(List list) throws IOException, URISyntaxException { + @GetMapping("/nowList") + @Operation(summary = "获取带实时值的列表") + @PreAuthorize("@ss.hasPermission('alert:exa:query')") + public CommonResult> getNowDataList(List list) throws IOException, URISyntaxException { List nowList=exaService.getEXAListNow(list); return success(nowList); } + @GetMapping("/now") + @Operation(summary = "根据点号获取测点实时值-单点或多点") + @PreAuthorize("@ss.hasPermission('alert:exa:query')") + public CommonResult getNowData(String itemName) throws IOException, URISyntaxException { + String nowData=exaService.getEXANow(itemName); + return success(nowData); + } + + + @GetMapping("/historys") + @Operation(summary = "获取点号历史-支持多点(点号之间用逗号分割)") + @PreAuthorize("@ss.hasPermission('alert:exa:query')") + public CommonResult>> getEXAHistorys(EXAHistoryReqVO exaHistoryReqVo) { + List> historyLists=exaService.getEXAHistorys(exaHistoryReqVo); + return success(historyLists); + } + + @PostMapping("/create") + @Operation(summary = "新增EXA点号") + @PreAuthorize("@ss.hasPermission('alert:exa:create')") + public CommonResult createPoint(@Valid @RequestBody Point pointVo) throws IOException { + String id = exaService.createPoint(pointVo); + return success(id); + } + + @GetMapping("/group") + @Operation(summary = "获取EXA所有组名") + @PreAuthorize("@ss.hasPermission('alert:exa:query')") + public CommonResult> getEXAGroupInfo() throws URISyntaxException, IOException { + List groupList=exaService.getEXAGroupInfo(); + return success(groupList); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除点号") + @Parameter(name = "ItemName", description = "点号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('alert:exa:delete')") + public CommonResult deleteUser(@RequestParam("ItemName") String ItemName) { + String result= exaService.deletePoint(ItemName); + + return success(true); + } + + @GetMapping("/get-import-template") + @Operation(summary = "获得导入测点模板") + public void importTemplate(HttpServletResponse response) throws IOException { + // 手动创建导出 demo + List list = Arrays.asList( + Point.builder().ItemName("gbqegj").GroupName("test").ItemType(5).Descriptor("fqnewfej") + .EngUnits("ge").Source("批量录入").AutoSave(true).build(), + Point.builder().ItemName("gbqegj").GroupName("test").ItemType(5).Descriptor("fqnewfej") + .EngUnits("ge").Source("批量录入").AutoSave(true).build() + ); + // 输出 + ExcelUtils.write(response, "用户导入模板.xls", "测点列表", Point.class, list); + } + + @PostMapping("/import") + @Operation(summary = "导入EXA测点") + @Parameters({ + @Parameter(name = "file", description = "Excel 文件", required = true), + @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") + }) + @PreAuthorize("@ss.hasPermission('system:user:import')") + public CommonResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + System.out.println(file); + List list = ExcelUtils.read(file, Point.class); + return success(exaService.importPointList(list, updateSupport)); + } + + } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHistoryReqVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHistoryReqVO.java new file mode 100644 index 0000000..99455fb --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHistoryReqVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.alert.controller.admin.exa.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class EXAHistoryReqVO { + + @Schema(description = "点号") + private String itemName; + @Schema(description = "开始时间") + private String startTime; + @Schema(description = "结束时间") + private String endTime; +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHttp.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHttp.java index d3dec61..49de24d 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHttp.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAHttp.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.alert.controller.admin.exa.vo; +import com.alibaba.fastjson.annotation.JSONField; import com.google.gson.annotations.Expose; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -15,7 +16,6 @@ public class EXAHttp { private Integer ItemType; private String Descriptor; -@Expose(serialize = false,deserialize = false) private String EngUnits; private String Source; private Boolean AutoSave; @@ -25,5 +25,7 @@ public class EXAHttp { private String LowerLimit; private String UpperUpperLimit; private String LowerLowerLimit; + @JSONField(name = "Value") // 映射JSON字段名 +// 解析时自动将JSON中的"desc"映射到description字段 private String Value; } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAPointImportExcelVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAPointImportExcelVO.java new file mode 100644 index 0000000..6c772f5 --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAPointImportExcelVO.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.alert.controller.admin.exa.vo; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.system.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + * EXA点号 Excel 导入 VO + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题 +public class EXAPointImportExcelVO { + @ExcelProperty("点号名称") + private String ItemName; + + @ExcelProperty("组名") + private String GroupName; + @ExcelProperty("数据类型") + private Integer ItemType; + @ExcelProperty("描述") + private String Descriptor; + @ExcelProperty("单位") + private String EngUnits; + @ExcelProperty("数据来源") + private String Source; + @ExcelProperty("自动保存") + private Boolean AutoSave; +// @ExcelProperty("登录名称") +// private String UpperBound; +// @ExcelProperty("登录名称") +// private String LowerBound; +// @ExcelProperty("登录名称") +// private String UpperLimit; +// @ExcelProperty("登录名称") +// private String LowerLimit; +// @ExcelProperty("登录名称") +// private String UpperUpperLimit; +// @ExcelProperty("登录名称") +// private String LowerLowerLimit; + + +// @ExcelProperty("登录名称") +// private String username; +// +// @ExcelProperty("用户名称") +// private String nickname; +// +// @ExcelProperty("部门编号") +// private Long deptId; +// +// @ExcelProperty("用户邮箱") +// private String email; +// +// @ExcelProperty("手机号码") +// private String mobile; +// +// @ExcelProperty(value = "用户性别", converter = DictConvert.class) +// @DictFormat(DictTypeConstants.USER_SEX) +// private Integer sex; +// +// @ExcelProperty(value = "账号状态", converter = DictConvert.class) +// @DictFormat(DictTypeConstants.COMMON_STATUS) +// private Integer status; + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAPointImportRespVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAPointImportRespVO.java new file mode 100644 index 0000000..b2ded9c --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAPointImportRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.alert.controller.admin.exa.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Schema(description = "管理后台 - 点号导入 Response VO") +@Data +@Builder +public class EXAPointImportRespVO { + + @Schema(description = "创建成功的点号数组", requiredMode = Schema.RequiredMode.REQUIRED) + private List createNames; + + @Schema(description = "更新成功的点号数组", requiredMode = Schema.RequiredMode.REQUIRED) + private List updateNames; + + @Schema(description = "导入失败的点号集合,key 为点号,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED) + private Map failureNames; + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAResult.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAResult.java new file mode 100644 index 0000000..679f2e8 --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/EXAResult.java @@ -0,0 +1,8 @@ +package cn.iocoder.yudao.module.alert.controller.admin.exa.vo; + +import com.alibaba.fastjson.annotation.JSONField; + +public class EXAResult { + @JSONField(name="ReturnValue") + public Long ReturnValue; +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/Point.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/Point.java new file mode 100644 index 0000000..5cd03a6 --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/vo/Point.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.alert.controller.admin.exa.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题 +public class Point { + @Schema(description = "", example = "芋道") + public String AssetCode; + + @ExcelProperty("点号名称") + @Schema(description = "点号", example = "芋道") + public String ItemName; + + @ExcelProperty("组名") + @Schema(description = "组名", example = "芋道") + public String GroupName; + + @ExcelProperty("数据类型") + public Integer ItemType; + + @ExcelProperty("描述") + @Schema(description = "描述", example = "芋道") + public String Descriptor; + + @ExcelProperty("单位") + @Schema(description = "单位", example = "芋道") + public String EngUnits; + + @ExcelProperty("数据来源") + public String Source; + + @ExcelProperty("自动保存") + public Boolean AutoSave; + public Double UpperBound; + public Double LowerBound; + public Double UpperLimit; + public Double LowerLimit; + public Double UpperUpperLimit; + public Double LowerLowerLimit; + public String Comment; + public String Note; + + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAService.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAService.java index 76a4b89..7f01df9 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAService.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAService.java @@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.alert.service.exa; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAHttp; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAPageReqVO; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAVO; +import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.*; import java.io.IOException; import java.net.URISyntaxException; @@ -23,6 +21,16 @@ public interface EXAService { List getEXAListNow(List list) throws URISyntaxException, IOException; + String getEXANow(String itemName) throws URISyntaxException, IOException; + List getEXAHistory(EXAHistoryReqVO exaHistoryReqVo); + List> getEXAHistorys(EXAHistoryReqVO exaHistoryReqVo); + + String createPoint(Point pointVo) throws IOException; + + public List getEXAGroupInfo() throws URISyntaxException, IOException; + + public String deletePoint(String ItemName); + EXAPointImportRespVO importPointList(List importPoints, boolean isUpdateSupport); } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAServiceImpl.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAServiceImpl.java index 842d8c0..9995b11 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAServiceImpl.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/exa/EXAServiceImpl.java @@ -1,13 +1,18 @@ package cn.iocoder.yudao.module.alert.service.exa; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAHttp; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAPageReqVO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; +import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.*; import cn.iocoder.yudao.module.alert.utils.EXAUtils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; +import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; @@ -17,7 +22,9 @@ import org.apache.http.client.utils.URIBuilder; 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 org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.io.IOException; @@ -25,7 +32,9 @@ import java.lang.reflect.Type; import java.net.URISyntaxException; import java.util.*; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.alert.utils.PageUtils.getPartList; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; @Service @Validated @@ -34,9 +43,11 @@ public class EXAServiceImpl implements EXAService { EXAUtils exaUtils = new EXAUtils(); + @Value("${EXA.ip}") + private String EXA_IP; @Override public PageResult getEXAPage(EXAPageReqVO reqVO) throws IOException, URISyntaxException { - List exaListAll = exaUtils.getPointInfo(reqVO); + List exaListAll = exaUtils.getPointInfo(EXA_IP,reqVO); Long total = Long.valueOf(exaListAll.size()); List exaList = getPartList(exaListAll, reqVO.getPageNo(), reqVO.getPageSize()); @@ -50,7 +61,7 @@ public class EXAServiceImpl implements EXAService { list.forEach(entity -> { try { - entity.setValue(exaUtils.getNowData(entity.getItemName()).get(0)); + entity.setValue(exaUtils.getNowData(EXA_IP,entity.getItemName()).get(0)); } catch (URISyntaxException e) { throw new RuntimeException(e); } catch (IOException e) { @@ -61,4 +72,58 @@ public class EXAServiceImpl implements EXAService { return list; } + @Override + public String getEXANow(String itemName) throws URISyntaxException, IOException { + return exaUtils.getNowData(EXA_IP,itemName).get(0); + + } + @Override + public List getEXAHistory(EXAHistoryReqVO exaHistoryReqVo) { + return exaUtils.getHistory(EXA_IP,exaHistoryReqVo); + } + + @Override + public List> getEXAHistorys(EXAHistoryReqVO exaHistoryReqVo) { + return exaUtils.getHistorys(EXA_IP,exaHistoryReqVo); + } + + @Override + public String createPoint(Point pointVo) throws IOException { + return exaUtils.setPoint(EXA_IP,pointVo); + } + @Override + public List getEXAGroupInfo() throws URISyntaxException, IOException { + return exaUtils.getGroup(EXA_IP); + } + + public String deletePoint(String ItemName){ + return exaUtils.deletePoint(EXA_IP,ItemName); + + } + + @Override + @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 + public EXAPointImportRespVO importPointList(List importPoints, boolean isUpdateSupport) { + // 1.1 参数校验 + if (CollUtil.isEmpty(importPoints)) { + throw exception(EXA_POINT_IMPORT_LIST_IS_EMPTY); + } + + // 2. 遍历,逐个创建 or 更新 + EXAPointImportRespVO respVO = EXAPointImportRespVO.builder().createNames(new ArrayList<>()) + .updateNames(new ArrayList<>()).failureNames(new LinkedHashMap<>()).build(); + importPoints.forEach(importUser -> { + try { + String createResult=createPoint(importUser); + if(createResult.equals("1")){ + respVO.getCreateNames().add(importUser.getItemName()); + } + + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + return respVO; + } + } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java index 64e65fb..485d524 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java @@ -1,41 +1,49 @@ package cn.iocoder.yudao.module.alert.utils; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAHttp; -import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAPageReqVO; +import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.*; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import org.apache.http.HttpEntity; +import org.apache.http.client.fluent.Request; import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; 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 java.io.IOException; import java.lang.reflect.Type; import java.net.URISyntaxException; +import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import static cn.iocoder.yudao.module.alert.utils.PageUtils.getPartList; - public class EXAUtils { + + + /** * 根据分页条件和测点名称测点描述模糊查询 * - * @param reqVO 传入对象,页数、页数量、查询条件 - * + * @param reqVO 传入对象,页数、页数量、查询条件 * @return exa列表 */ - public List getPointInfo(EXAPageReqVO reqVO) throws URISyntaxException, IOException { + public List getPointInfo(String EXA_IP,EXAPageReqVO reqVO) throws URISyntaxException, IOException { // PageResult result = new PageResult<>(); List exaListAll = new ArrayList(); try { // 目标 RPC 服务的 URL - String url = "http://47.98.32.148:9000/exawebapi/exaitem/getitems"; + String url = "http://"+EXA_IP+":9000/exawebapi/exaitem/getitems"; //创建HttpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); /* @@ -56,8 +64,7 @@ public class EXAUtils { int statusCode = response.getStatusLine().getStatusCode(); System.out.println("服务端返回成功的状态码为:" + statusCode); HttpEntity entity = response.getEntity(); - String body = EntityUtils.toString(entity).replaceAll("\\\\", ""); - System.out.println("服务端返回的数据为:" + body); + String body = EntityUtils.toString(entity).replaceAll("\\\\\\\\\\\\\"", "").replaceAll("\\\\", ""); // 步骤1:检查字符串是否为空 // if (body == null || body.isEmpty()) { // return body; // 如果字符串为空或为null,直接返回 @@ -68,10 +75,17 @@ public class EXAUtils { body = body.substring(1, body.length() - 1); // 去掉首尾的双引号 } - Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); - Type listType = new TypeToken>() { - }.getType(); - exaListAll = gson.fromJson(body, listType); + try { + exaListAll = JSONArray.parseArray(body, EXAHttp.class); + } catch (Exception e) { + System.out.println(e); + + } + +// Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); +// Type listType = new TypeToken>() { +// }.getType(); +// exaListAll = gson.fromJson(body, listType); //关闭资源 @@ -83,11 +97,18 @@ public class EXAUtils { return exaListAll; } - public List getNowData(String itemNames) throws URISyntaxException, IOException { + /** + * 根据多个点号查询实时值 + * + * @param itemNames 多个点号,用逗号隔开 传入对象,页数、页数量、查询条件 + * @return exa列表 + */ + + public List getNowData(String EXA_IP,String itemNames) throws URISyntaxException, IOException { List result = new ArrayList<>(); try { // 目标 RPC 服务的 URL - String url = "http://47.98.32.148:9000/exawebapi/exanow/getfloatvaluebatch"; + String url = "http://"+EXA_IP+":9000/exawebapi/exanow/getfloatvaluebatch"; //创建HttpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); /* @@ -127,5 +148,160 @@ public class EXAUtils { return result; } + /** + * 根据分页条件和测点名称测点描述模糊查询 + * + * @param exaHistoryReqVo 传入对象,点号、开始时间、结束时间 + * @return exa列表 + */ + public List getHistory(String EXA_IP,EXAHistoryReqVO exaHistoryReqVo) { + List result = new ArrayList<>(); + try { + // 目标 RPC 服务的 URL + String url = "http://"+EXA_IP+":9000/exawebapi/exatime/GetRawValueArrayFloat"; + //创建HttpClient对象 + CloseableHttpClient httpClient = HttpClients.createDefault(); + /* + * 由于GET请求的参数都是拼装在URL地址后方,所以我们要构建一个URL,带参数 + */ + URIBuilder uriBuilder = new URIBuilder(url); + + /** 添加参数 */ + uriBuilder.addParameter("ItemName", exaHistoryReqVo.getItemName()); + uriBuilder.addParameter("StartingTime", exaHistoryReqVo.getStartTime()); + uriBuilder.addParameter("TerminalTime", exaHistoryReqVo.getEndTime()); + + //创建请求对象 + HttpGet httpGet = new HttpGet(uriBuilder.build()); + + // 传输的类型 + httpGet.addHeader("Content-Type", "application/json"); + //发送请求,请求响应结果 + CloseableHttpResponse response = httpClient.execute(httpGet); + //获取服务器返回的状态码 + int statusCode = response.getStatusLine().getStatusCode(); + System.out.println("服务端返回成功的状态码为:" + statusCode); + HttpEntity entity = response.getEntity(); + String body = EntityUtils.toString(entity).replaceAll("\\\\", ""); + System.out.println("服务端返回的数据为:" + body); + if (body.startsWith("\"") && body.endsWith("\"")) { + // 步骤3:去掉双引号 + body = body.substring(1, body.length() - 1); // 去掉首尾的双引号 + } + Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); + Type listType = new TypeToken>>() { + }.getType(); + result = gson.fromJson(body, listType); + + //关闭资源 + response.close(); + httpClient.close(); + } catch (Exception e) { + + } + return result; + } + + public List> getHistorys(String EXA_IP,EXAHistoryReqVO exaHistoryReqVo) { + List> results = new ArrayList<>(); + + try { + String itemNames = exaHistoryReqVo.getItemName(); + List pointName = Arrays.asList(itemNames.split(",")); + pointName.forEach(entity -> { + List result = new ArrayList<>(); + exaHistoryReqVo.setItemName(entity); + result = getHistory(EXA_IP,exaHistoryReqVo); + results.add(result); + }); + } catch (Exception e) { + + } + return results; + } + + //写入点号 + public String setPoint(String EXA_IP,Point point) throws IOException { + String requestPathAddItem = "http://"+EXA_IP+":9000/exawebapi/exaitem/AddItem"; + String param = JSON.toJSONString(point); + String result = Request.Post(requestPathAddItem) + .addHeader("Content-type", "application/json") + .bodyString(param, ContentType.APPLICATION_JSON) + .execute().returnContent().asString(Charset.forName("utf-8")); + +// 反序列化--之前的版本是这个样子,新版本没有了 +// EXAResult vo = JSON.parseObject(result, EXAResult.class); + + return result; + } + + public List getGroup(String EXA_IP) throws URISyntaxException, IOException { + List result = new ArrayList<>(); + try { + // 目标 RPC 服务的 URL + String url = "http://"+EXA_IP+":9000/exawebapi/exagroup/getgroups"; + //创建HttpClient对象 + CloseableHttpClient httpClient = HttpClients.createDefault(); + /* + * 由于GET请求的参数都是拼装在URL地址后方,所以我们要构建一个URL,带参数 + */ + URIBuilder uriBuilder = new URIBuilder(url); + + /** 添加参数 */ +// uriBuilder.addParameter("ItemNames", itemNames); + + //创建请求对象 + HttpGet httpGet = new HttpGet(uriBuilder.build()); + + // 传输的类型 + httpGet.addHeader("Content-Type", "application/json"); + //发送请求,请求响应结果 + CloseableHttpResponse response = httpClient.execute(httpGet); + //获取服务器返回的状态码 + int statusCode = response.getStatusLine().getStatusCode(); + System.out.println("服务端返回成功的状态码为:" + statusCode); + HttpEntity entity = response.getEntity(); + String body = EntityUtils.toString(entity).replaceAll("\\\\", ""); + System.out.println("服务端返回的数据为:" + body); + if (body.startsWith("\"") && body.endsWith("\"")) { + // 步骤3:去掉双引号 + body = body.substring(1, body.length() - 1); // 去掉首尾的双引号 + } + + Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); + Type listType = new TypeToken>() { + }.getType(); + result = gson.fromJson(body, listType); + + //关闭资源 + response.close(); + httpClient.close(); + } catch (Exception e) { + + } + return result; + } + + public String deletePoint(String EXA_IP,String ItemName){ + String requestPathDeleteItem ="http://"+EXA_IP+":9000/exawebapi/exaitem/DeleteItem?ItemName="+ItemName; + // 创建HttpClient + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + // 创建HttpDelete请求 + HttpDelete request = new HttpDelete(requestPathDeleteItem); + // 执行请求 + try (CloseableHttpResponse response = httpClient.execute(request)) { + // 获取HTTP响应状态 + System.out.println("Response Code: " + response.getStatusLine().getStatusCode()); + // 获取HTTP响应内容 + String content = EntityUtils.toString(response.getEntity()); + System.out.println("Response Content: \n" + content); + return content; + + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index c692b4a..268706f 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -166,4 +166,7 @@ public interface ErrorCodeConstants { // ========== 站内信发送 1-002-028-000 ========== ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_028_000, "模板参数({})缺失"); + + ErrorCode EXA_POINT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_002_029_000, "导入EXA测点数据不能为空!"); + } diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index b28a0a5..05c90a4 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -48,7 +48,7 @@ spring: datasource: master: url: jdbc:mysql://120.26.116.243:3306/alert?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例 - # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例 +# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例 @@ -269,4 +269,6 @@ justauth: --- #################### iot相关配置 TODO 芋艿【IOT】:再瞅瞅 #################### pf4j: # pluginsDir: /tmp/ - pluginsDir: ../plugins \ No newline at end of file + pluginsDir: ../plugins +EXA: + ip: 47.98.32.148 \ No newline at end of file