diff --git a/das/src/main/java/com/das/modules/page/controller/WindSpeedCorrectController.java b/das/src/main/java/com/das/modules/page/controller/WindSpeedCorrectController.java new file mode 100644 index 00000000..51cf4393 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/controller/WindSpeedCorrectController.java @@ -0,0 +1,48 @@ +package com.das.modules.page.controller; + +import com.das.common.result.R; +import com.das.common.utils.PageDataInfo; +import com.das.modules.page.domian.dto.SysPowerCurveFactorDto; +import com.das.modules.page.domian.vo.SysPowerCurveFactorVo; +import com.das.modules.page.service.WindSpeedCorrectService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.text.ParseException; +/** + * @description: 风机风速功率修正系数 + */ +@Slf4j +@RequestMapping("/api/page/windSpeedCorrect") +@RestController +public class WindSpeedCorrectController { + + @Autowired + private WindSpeedCorrectService sysEquipmentService; + + /** 导入 */ + @PostMapping("/import") + public R importWindSpeedCorrect( @RequestParam("file") MultipartFile file) throws IOException, ParseException { + sysEquipmentService.importWindSpeedCorrect( file); + return R.success("导入成功"); + } + /** 获取风机风速功率修正系数列表 */ + @PostMapping("/getList") + public R> getList(@RequestBody SysPowerCurveFactorDto dto) { + PageDataInfo list = sysEquipmentService.getList(dto); + return R.success(list); + } + + /** 导出 */ + @PostMapping("/export") + public void exportWindSpeedCorrect(@RequestBody SysPowerCurveFactorDto dto, HttpServletRequest request, HttpServletResponse response) { + sysEquipmentService.exportWindSpeedCorrect(dto,request, response); + } + + +} diff --git a/das/src/main/java/com/das/modules/page/domian/dto/IntervalDto.java b/das/src/main/java/com/das/modules/page/domian/dto/IntervalDto.java new file mode 100644 index 00000000..d6eff572 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/domian/dto/IntervalDto.java @@ -0,0 +1,11 @@ +package com.das.modules.page.domian.dto; + +import lombok.Data; + +@Data +public class IntervalDto { + + private Double minValue; + private Double maxValue; + +} diff --git a/das/src/main/java/com/das/modules/page/domian/dto/SysPowerCurveFactorDto.java b/das/src/main/java/com/das/modules/page/domian/dto/SysPowerCurveFactorDto.java new file mode 100644 index 00000000..e72102a9 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/domian/dto/SysPowerCurveFactorDto.java @@ -0,0 +1,27 @@ +package com.das.modules.page.domian.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class SysPowerCurveFactorDto { + + private Long id; + + private List listId; + + private Long turbineId; + + private double speedMin; + + private double speedMax; + + private double factorK; + + private double factorB; + + private Integer pageNum; + + private Integer pageSize; +} diff --git a/das/src/main/java/com/das/modules/page/domian/vo/SysPowerCurveFactorExcelVo.java b/das/src/main/java/com/das/modules/page/domian/vo/SysPowerCurveFactorExcelVo.java new file mode 100644 index 00000000..5210e151 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/domian/vo/SysPowerCurveFactorExcelVo.java @@ -0,0 +1,18 @@ +package com.das.modules.page.domian.vo; + +import lombok.Data; + +@Data +public class SysPowerCurveFactorExcelVo { + + + + private double factorK; + + private double factorB; + + private String name; + + private String windSpeed; + +} diff --git a/das/src/main/java/com/das/modules/page/domian/vo/SysPowerCurveFactorVo.java b/das/src/main/java/com/das/modules/page/domian/vo/SysPowerCurveFactorVo.java new file mode 100644 index 00000000..c8148e75 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/domian/vo/SysPowerCurveFactorVo.java @@ -0,0 +1,24 @@ +package com.das.modules.page.domian.vo; + +import lombok.Data; + +@Data +public class SysPowerCurveFactorVo { + + private Long id; + + private Long turbineId; + + private Double speedMin; + + private Double speedMax; + + private double factorK; + + private double factorB; + + private String name; + + private String windSpeed; + +} diff --git a/das/src/main/java/com/das/modules/page/entity/SysPowerCurveFactor.java b/das/src/main/java/com/das/modules/page/entity/SysPowerCurveFactor.java new file mode 100644 index 00000000..83ceb37f --- /dev/null +++ b/das/src/main/java/com/das/modules/page/entity/SysPowerCurveFactor.java @@ -0,0 +1,36 @@ +package com.das.modules.page.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.das.common.constant.BaseEntity; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.io.Serial; + +@TableName("sys_power_curve_factor") +@Data +public class SysPowerCurveFactor extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + private Long turbineId; + + private Double speedMin; + + private Double speedMax; + + private double factorK; + + private double factorB; +} diff --git a/das/src/main/java/com/das/modules/page/mapper/SysPowerCurveFactorMapper.java b/das/src/main/java/com/das/modules/page/mapper/SysPowerCurveFactorMapper.java new file mode 100644 index 00000000..ee5c001e --- /dev/null +++ b/das/src/main/java/com/das/modules/page/mapper/SysPowerCurveFactorMapper.java @@ -0,0 +1,20 @@ +package com.das.modules.page.mapper; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.das.modules.auth.mapper.BaseMapperPlus; +import com.das.modules.page.domian.dto.SysPowerCurveFactorDto; +import com.das.modules.page.domian.vo.SysPowerCurveFactorVo; +import com.das.modules.page.entity.SysPowerCurveFactor; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface SysPowerCurveFactorMapper extends BaseMapperPlus { + + IPage querySysPowerCurveFactorListInPage(IPage page, @Param("info") SysPowerCurveFactorDto sysPowerCurveFactorDto); + + List querySysPowerCurveFactorList(@Param("info") SysPowerCurveFactorDto sysPowerCurveFactorDto); + +} diff --git a/das/src/main/java/com/das/modules/page/service/WindSpeedCorrectService.java b/das/src/main/java/com/das/modules/page/service/WindSpeedCorrectService.java new file mode 100644 index 00000000..31cf1210 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/service/WindSpeedCorrectService.java @@ -0,0 +1,19 @@ +package com.das.modules.page.service; + +import com.das.common.utils.PageDataInfo; +import com.das.modules.page.domian.dto.SysPowerCurveFactorDto; +import com.das.modules.page.domian.vo.SysPowerCurveFactorVo; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +public interface WindSpeedCorrectService { + + void importWindSpeedCorrect(MultipartFile file) throws IOException; + + PageDataInfo getList(SysPowerCurveFactorDto dto) ; + + void exportWindSpeedCorrect(SysPowerCurveFactorDto dto, HttpServletRequest request, HttpServletResponse response); +} 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 1da74722..5c9560ec 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 @@ -4,6 +4,7 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.das.common.constant.StatisticalAnalysisConstant; import com.das.common.exceptions.ServiceException; @@ -21,6 +22,7 @@ import com.das.modules.page.service.StatisticalAnalysisService; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +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; @@ -76,6 +78,9 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic */ @Override public void trendAnalyseExport(List param, HttpServletRequest request, HttpServletResponse response) { + if (param == null || param.isEmpty()) { + throw new ServiceException("参数列表不能为空"); + } //根据条件获取历史数据 List>>> mapsList = new ArrayList<>(); for (TrendAnalyseDto trendAnalyseDto : param) { @@ -224,6 +229,14 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic dataList.add(dataMap); } } else { + if (dataList.size()< timesListstr.size()){ + for (int j = dataList.size(); j < timesListstr.size(); j++) { + Map dataMap = new HashMap<>(); + dataMap.put(timeKey, timesListstr.get(j)); + dataMap.put(pointNameKey, valuesList.get(j)); + dataList.add(dataMap); + } + } for (int j = 0; j < timesListstr.size(); j++) { Map stringObjectMap = dataList.get(j); stringObjectMap.put(timeKey, timesListstr.get(j)); @@ -546,6 +559,9 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic private static void addChartToExcel(ExcelWriter writer, List> data, String titleText,List chartKey) { try { + if (CollectionUtils.isEmpty(data)){ + return; + } // 获取Sheet对象 XSSFSheet sheet = (XSSFSheet) writer.getSheet(); // 创建绘图区域 diff --git a/das/src/main/java/com/das/modules/page/service/impl/WindSpeedCorrectServiceImpl.java b/das/src/main/java/com/das/modules/page/service/impl/WindSpeedCorrectServiceImpl.java new file mode 100644 index 00000000..93e3726f --- /dev/null +++ b/das/src/main/java/com/das/modules/page/service/impl/WindSpeedCorrectServiceImpl.java @@ -0,0 +1,269 @@ +package com.das.modules.page.service.impl; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.poi.excel.ExcelReader; +import cn.hutool.poi.excel.ExcelUtil; +import cn.hutool.poi.excel.ExcelWriter; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.das.common.config.SessionUtil; +import com.das.common.exceptions.ServiceException; +import com.das.common.utils.BeanCopyUtils; +import com.das.common.utils.PageDataInfo; +import com.das.common.utils.PageQuery; +import com.das.modules.auth.domain.vo.SysUserVo; +import com.das.modules.equipment.entity.SysEquipment; +import com.das.modules.equipment.mapper.SysEquipmentMapper; +import com.das.modules.page.domian.dto.IntervalDto; +import com.das.modules.page.domian.dto.SysPowerCurveFactorDto; +import com.das.modules.page.domian.vo.SysPowerCurveFactorExcelVo; +import com.das.modules.page.domian.vo.SysPowerCurveFactorVo; +import com.das.modules.page.entity.SysPowerCurveFactor; +import com.das.modules.page.mapper.SysPowerCurveFactorMapper; +import com.das.modules.page.service.WindSpeedCorrectService; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellRangeAddress; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Service +public class WindSpeedCorrectServiceImpl implements WindSpeedCorrectService { + + @Autowired + private SysEquipmentMapper sysEquipmentMapper; + + @Autowired + private SysPowerCurveFactorMapper sysPowerCurveFactorMapper; + + @Override + public void importWindSpeedCorrect(MultipartFile file) throws IOException { + // 通过文件获取输入流 + InputStream is = file.getInputStream(); + // 借助hutool读取 + ExcelReader reader = ExcelUtil.getReader(is); + List> list = reader.read(1); // 从第二行开始读 + Map windId = getWindId(); + List listData = new ArrayList<>(); + // 遍历 + for (List row : list) { + String windName = (String) row.get(0); + Long id = windId.get(windName); + String windSpeed = (String) row.get(1); + Object coefficientK = row.get(2); + double k = setCoefficientValue(coefficientK); + Object coefficientB =row.get(3); + double b =setCoefficientValue(coefficientB); + //获取最小值,最大值 + IntervalDto intervalDto = parseInterval(windSpeed); + SysPowerCurveFactor sysPowerCurveFactor = new SysPowerCurveFactor(); + sysPowerCurveFactor.setTurbineId(id); + sysPowerCurveFactor.setSpeedMin(intervalDto.getMinValue()); + if (intervalDto.getMaxValue() !=null){ + sysPowerCurveFactor.setSpeedMax(intervalDto.getMaxValue()); + } + sysPowerCurveFactor.setFactorK(k); + sysPowerCurveFactor.setFactorB(b); + SysUserVo sysUserVo = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY); + sysPowerCurveFactor.setCreatedBy(sysUserVo.getAccount()); + sysPowerCurveFactor.setUpdatedBy(sysUserVo.getAccount()); + sysPowerCurveFactor.setCreatedTime(new Date()); + sysPowerCurveFactor.setUpdatedTime(new Date()); + sysPowerCurveFactor.setRevision(1); + listData.add(sysPowerCurveFactor); + } + //批量插入数据库 + sysPowerCurveFactorMapper.insertBatch(listData); + } + + @Override + public PageDataInfo getList(SysPowerCurveFactorDto dto) { + PageQuery pageQuery = new PageQuery(); + pageQuery.setPageNum(dto.getPageNum()); + pageQuery.setPageSize(dto.getPageSize()); + IPage iPage =sysPowerCurveFactorMapper.querySysPowerCurveFactorListInPage(pageQuery.build(),dto); + return PageDataInfo.build(iPage.getRecords(), iPage.getTotal()); + } + + @Override + public void exportWindSpeedCorrect(SysPowerCurveFactorDto dto, HttpServletRequest request, HttpServletResponse response) { + List sysPowerCurveFactorVos = sysPowerCurveFactorMapper.querySysPowerCurveFactorList(dto); + List listData = new ArrayList<>(); + for (SysPowerCurveFactorVo sysPowerCurveFactorVo : sysPowerCurveFactorVos) { + if (sysPowerCurveFactorVo.getSpeedMax() ==null){ + sysPowerCurveFactorVo.setWindSpeed("大于等于"+sysPowerCurveFactorVo.getSpeedMin()); + }else { + StringBuilder stb = new StringBuilder("["); + stb.append(sysPowerCurveFactorVo.getSpeedMin()).append(",").append(sysPowerCurveFactorVo.getSpeedMax()).append(")"); + sysPowerCurveFactorVo.setWindSpeed(stb.toString()); + } + SysPowerCurveFactorExcelVo sysPowerCurveFactorExcelVo = new SysPowerCurveFactorExcelVo(); + BeanCopyUtils.copy(sysPowerCurveFactorVo,sysPowerCurveFactorExcelVo); + listData.add(sysPowerCurveFactorExcelVo); + } + listData.sort(Comparator.comparing(SysPowerCurveFactorExcelVo::getName)); + //自定义别名 别名的key和实体类中的名称要对应上!! + LinkedHashMap map = new LinkedHashMap<>(); + map.put("name", "风机名称"); + map.put("windSpeed", "风速"); + map.put("factorK", "系数K"); + map.put("factorB", "系数B"); + ExcelWriter writer = new ExcelWriter(); + writer.setHeaderAlias(map); + //水平居中对齐,垂直中间对齐 + writer.getStyleSet().setAlign(HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + //所有单元格宽25个字符 + writer.setColumnWidth(-1, 25); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(listData, true); + // 获取底层的Workbook和Sheet对象 + Workbook workbook = writer.getWorkbook(); + Sheet sheet = workbook.getSheetAt(0); + // 合并name相同的数据单元格 + int rowIndex = 1; + List mergedRegions = new ArrayList<>(); + for (int i = 0; i < listData.size(); ) { + SysPowerCurveFactorExcelVo current = listData.get(i); + int startRow = rowIndex; + int endRow = startRow; + // 找到所有连续的相同 name 的行 + while (i + 1 < listData.size() && current.getName().equals(listData.get(i + 1).getName())) { + i++; + endRow++; + } + // 如果有重复的名字,并且 startRow 和 endRow 不相等,则合并单元格 + if (startRow != endRow) { // 确保合并区域至少包含两个单元格 + CellRangeAddress cellRangeAddress = new CellRangeAddress(startRow, endRow, 0, 0); // 假设name是第一列 + mergedRegions.add(cellRangeAddress); + } + i++; + rowIndex = endRow + 1; // 更新 rowIndex 到下一行 + } + + // 添加合并区域到Sheet + for (CellRangeAddress region : mergedRegions) { + sheet.addMergedRegion(region); + } + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); + response.setContentType("application/vnd.ms-excel"); + ServletOutputStream out = null; + try { + // 设置请求头属性 + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("风速功率修正系数.xls", StandardCharsets.UTF_8)); + out = response.getOutputStream(); + // 写出到文件 + writer.flush(out, true); + // 关闭writer,释放内存 + writer.close(); + // 此处记得关闭输出Servlet流 + IoUtil.close(out); + } catch (IOException e) { + throw new ServiceException("文件下载失败==" + e); + } + } + + private double setCoefficientValue(Object coefficient){ + if (coefficient instanceof String){ + return Double.parseDouble(coefficient.toString()); + } + if (coefficient instanceof Double) { + return (double) coefficient; + } + if (coefficient instanceof BigDecimal) { + BigDecimal bigDecimal = new BigDecimal(coefficient+""); + return bigDecimal.doubleValue(); + } + if (coefficient instanceof Long) { + return Double.valueOf((Long) coefficient+""); + } + return 0; + } + private Map getWindId() { + //获取所有风机 + List sysEquipments = sysEquipmentMapper.selectList(); + // 定义一个 Map 用于存储 name 和 id + Map nameIdMap = new HashMap<>(); + // 遍历 sysEquipments 列表 + sysEquipments.forEach(equipment -> { + // 获取设备的 name 和 id + String name = equipment.getName(); + Long id = equipment.getId(); + // 将 name 和 id 添加到 Map 中 + nameIdMap.put(name, id); + }); + return nameIdMap; + } + + + /** + * 解析区间字符串,提取所有数字以及它们是否包括在内。 + * + * @param intervalStr 区间字符串,格式可以是标准区间或包含多个数字 + * @return 包含解析结果的 IntervalResult 对象 + * @throws IllegalArgumentException 如果字符串格式不正确 + */ + public static IntervalDto parseInterval(String intervalStr) { + // 定义正则表达式来匹配区间字符串中的数字 + Pattern pattern = Pattern.compile("\\[?\\s*(-?\\d+(\\.\\d+)?)\\s*(,\\s*(-?\\d+(\\.\\d+)?))*\\s*\\)?"); + Matcher matcher = pattern.matcher(intervalStr); + IntervalDto intervalDto = new IntervalDto(); + if (!matcher.matches()) { + Pattern pattern2 = Pattern.compile("大于等于\\s*([\\d.]+)"); + Matcher matcher2 = pattern2.matcher(intervalStr); + if (matcher2.find()) { + // 提取匹配的数字 + String numberStr = matcher2.group(1); + // 将数字字符串转换为double类型 + double number = Double.parseDouble(numberStr); + // 设置IntervalDto的minValue + intervalDto.setMinValue(number); + } else { + throw new ServiceException("无效的区间格式: " + intervalStr); + } + + } + // 提取所有数字 + List values = new ArrayList<>(); + Pattern numberPattern = Pattern.compile("-?\\d+(\\.\\d+)?"); + Matcher numberMatcher = numberPattern.matcher(intervalStr); + + while (numberMatcher.find()) { + values.add(Double.parseDouble(numberMatcher.group())); + } + + // 如果只有一个数字,认为它是唯一的值 + if (values.size() == 1) { + double value = values.get(0); + intervalDto.setMinValue(value); + return intervalDto; + } + + // 如果有两个数字,按标准区间处理 + if (values.size() == 2) { + double min = Math.min(values.get(0), values.get(1)); + double max = Math.max(values.get(0), values.get(1)); + intervalDto.setMinValue(min); + intervalDto.setMaxValue(max); + return intervalDto; + } + if (values.size() > 2) { + throw new ServiceException("无效的区间格式: " + intervalStr); + } + return intervalDto; + } +} diff --git a/das/src/main/resources/mapper/SysPowerCurveFactorMapper.xml b/das/src/main/resources/mapper/SysPowerCurveFactorMapper.xml new file mode 100644 index 00000000..ef20551d --- /dev/null +++ b/das/src/main/resources/mapper/SysPowerCurveFactorMapper.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + +