风机的风速功率修正系数维护界面;

趋势导出优化;
This commit is contained in:
yu 2024-12-02 17:24:26 +08:00
parent 44b7b590cb
commit a78bdbd8c3
11 changed files with 540 additions and 0 deletions

View File

@ -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<Void> importWindSpeedCorrect( @RequestParam("file") MultipartFile file) throws IOException, ParseException {
sysEquipmentService.importWindSpeedCorrect( file);
return R.success("导入成功");
}
/** 获取风机风速功率修正系数列表 */
@PostMapping("/getList")
public R<PageDataInfo<SysPowerCurveFactorVo>> getList(@RequestBody SysPowerCurveFactorDto dto) {
PageDataInfo<SysPowerCurveFactorVo> 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);
}
}

View File

@ -0,0 +1,11 @@
package com.das.modules.page.domian.dto;
import lombok.Data;
@Data
public class IntervalDto {
private Double minValue;
private Double maxValue;
}

View File

@ -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<Long> listId;
private Long turbineId;
private double speedMin;
private double speedMax;
private double factorK;
private double factorB;
private Integer pageNum;
private Integer pageSize;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<SysPowerCurveFactor,SysPowerCurveFactor> {
IPage<SysPowerCurveFactorVo> querySysPowerCurveFactorListInPage(IPage<SysPowerCurveFactorVo> page, @Param("info") SysPowerCurveFactorDto sysPowerCurveFactorDto);
List<SysPowerCurveFactorVo> querySysPowerCurveFactorList(@Param("info") SysPowerCurveFactorDto sysPowerCurveFactorDto);
}

View File

@ -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<SysPowerCurveFactorVo> getList(SysPowerCurveFactorDto dto) ;
void exportWindSpeedCorrect(SysPowerCurveFactorDto dto, HttpServletRequest request, HttpServletResponse response);
}

View File

@ -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<TrendAnalyseDto> param, HttpServletRequest request, HttpServletResponse response) {
if (param == null || param.isEmpty()) {
throw new ServiceException("参数列表不能为空");
}
//根据条件获取历史数据
List<Map<String, Map<String, Map<String, Object>>>> 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<String, Object> 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<String, Object> 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<Map<String, Object>> data,
String titleText,List<String> chartKey) {
try {
if (CollectionUtils.isEmpty(data)){
return;
}
// 获取Sheet对象
XSSFSheet sheet = (XSSFSheet) writer.getSheet();
// 创建绘图区域

View File

@ -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<Object>> list = reader.read(1); // 从第二行开始读
Map<String, Long> windId = getWindId();
List<SysPowerCurveFactor> listData = new ArrayList<>();
// 遍历
for (List<Object> 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<SysPowerCurveFactorVo> getList(SysPowerCurveFactorDto dto) {
PageQuery pageQuery = new PageQuery();
pageQuery.setPageNum(dto.getPageNum());
pageQuery.setPageSize(dto.getPageSize());
IPage<SysPowerCurveFactorVo> iPage =sysPowerCurveFactorMapper.querySysPowerCurveFactorListInPage(pageQuery.build(),dto);
return PageDataInfo.build(iPage.getRecords(), iPage.getTotal());
}
@Override
public void exportWindSpeedCorrect(SysPowerCurveFactorDto dto, HttpServletRequest request, HttpServletResponse response) {
List<SysPowerCurveFactorVo> sysPowerCurveFactorVos = sysPowerCurveFactorMapper.querySysPowerCurveFactorList(dto);
List<SysPowerCurveFactorExcelVo> 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<String, String> 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<CellRangeAddress> 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<String, Long> getWindId() {
//获取所有风机
List<SysEquipment> sysEquipments = sysEquipmentMapper.selectList();
// 定义一个 Map 用于存储 name id
Map<String, Long> 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<Double> 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;
}
}

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.das.modules.page.mapper.SysPowerCurveFactorMapper">
<resultMap type="com.das.modules.page.domian.vo.SysPowerCurveFactorVo" id="resultMap">
<result property="id" column="id" jdbcType="BIGINT"/>
<result property="turbineId" column="turbine_id" jdbcType="BIGINT"/>
<result property="speedMin" column="speed_min" jdbcType="DOUBLE"/>
<result property="speedMax" column="speed_max" jdbcType="DOUBLE"/>
<result property="factorK" column="factor_k" jdbcType="DOUBLE"/>
<result property="factorB" column="factor_b" jdbcType="DOUBLE"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
</resultMap>
<select id="querySysPowerCurveFactorListInPage" resultMap="resultMap">
select
t.*,
sq.name
from sys_power_curve_factor t
left join sys_equipment sq on t.turbine_id = sq.id
<where>
<if test="info.turbineId != null">
and t.turbine_id = #{info.turbineId}
</if>
</where>
</select>
<select id="querySysPowerCurveFactorList" resultMap="resultMap">
select
t.*,
sq.name
from sys_power_curve_factor t
left join sys_equipment sq on t.turbine_id = sq.id
<where>
<if test="info.turbineId != null">
and t.turbine_id = #{info.turbineId}
</if>
<if test="info.id != null">
and t.id = #{info.id}
</if>
<if test="info.listId!= null and info.listId.size >0">
<foreach collection="info.listId" item="item" open="and t.id in (" close=")" separator=",">
#{item}
</foreach>
</if>
</where>
order by sq.name asc
</select>
</mapper>