diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/impl/EventWaveAnalysisServiceImpl.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/impl/EventWaveAnalysisServiceImpl.java index 2f5462a8c..dc9b453c0 100644 --- a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/impl/EventWaveAnalysisServiceImpl.java +++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/impl/EventWaveAnalysisServiceImpl.java @@ -2,6 +2,7 @@ package com.njcn.advance.service.impl; import cn.hutool.core.date.TimeInterval; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.njcn.advance.enums.EnumEvt; import com.njcn.advance.mapper.RmpEventAdvanceMapper; @@ -323,6 +324,14 @@ public class EventWaveAnalysisServiceImpl implements EventWaveAnalysisService { if (rmpEventDetailPO.getDealFlag() != 1) { //如果存在三个文件但是没有调用dll/so计算 getDataFromDLL(rmpEventDetailPO, waveOriginalData, rect, entityAdvancedData, causeStruct); + } else { + //已经处理过了,那就根据id获取暂降原因 + String reason = rmpEventDetailPO.getAdvanceReason(); + List reasonList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_REASON.getCode()).getData(); + Map eventReasonMap = reasonList.stream().collect(Collectors.toMap(DictData::getId, Function.identity())); + if (ObjectUtil.isNotNull(eventReasonMap.get(reason))) { + entityAdvancedData.sagReason[0] = eventReasonMap.get(reason).getName(); + } } String hdrStr = null; diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/utils/PublicDataUtils.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/utils/PublicDataUtils.java index 2024737aa..f3b3ddf19 100644 --- a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/utils/PublicDataUtils.java +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/utils/PublicDataUtils.java @@ -4,6 +4,8 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.njcn.common.pojo.exception.BusinessException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.Date; /** @@ -70,4 +72,55 @@ public class PublicDataUtils { throw new BusinessException("时间格式不正确,请使用 yyyy-MM 格式"); } } + + /** + * 根据传入的月份字符串获取时间范围 + * 如果传入的月份是当前月份,返回该月1号到昨天 + * 如果传入的月份不是当前月份,返回该月的第一天和最后一天 + * + * @param timeStr 月份字符串,格式:yyyy-MM + * @return 包含 startTime 和 endTime 的数组,格式:yyyy-MM-dd + */ + /** + * 根据传入的月份字符串获取时间范围 + * 如果传入的月份是当前月份,返回该月 1 号到昨天 + * 如果传入的月份不是当前月份,返回该月的第一天和最后一天 + * + * @param timeStr 月份字符串,格式:yyyy-MM + * @return 包含 startTime 和 endTime 的数组,格式:yyyy-MM-dd + */ + public static String[] calculateTimeRange(String timeStr) { + LocalDate now = LocalDate.now(); + LocalDate inputMonth; + + try { + // 解析传入的月份 + inputMonth = LocalDate.parse(timeStr + "-01", DateTimeFormatter.ISO_LOCAL_DATE); + } catch (Exception e) { + throw new BusinessException("时间格式不正确,请使用 yyyy-MM 格式"); + } + + // 判断是否是当前月份 + boolean isCurrentMonth = inputMonth.getYear() == now.getYear() && + inputMonth.getMonthValue() == now.getMonthValue(); + + String startTime; + String endTime; + + startTime = inputMonth.withDayOfMonth(1).format(DateTimeFormatter.ISO_LOCAL_DATE); + if (isCurrentMonth) { + // 如果今天是 1 号,则结束时间也为 1 号,避免时间范围无效 + endTime = now.minusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE); + // 确保结束时间不小于开始时间 + if (LocalDate.parse(endTime).isBefore(LocalDate.parse(startTime))) { + endTime = startTime; + } + } else { + // 如果不是当前月份,开始时间是该月 1 号,结束时间是该月最后一天 + endTime = inputMonth.withDayOfMonth(inputMonth.lengthOfMonth()).format(DateTimeFormatter.ISO_LOCAL_DATE); + } + + return new String[]{startTime, endTime}; + } + } diff --git a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java index 2880c0918..9a70fada4 100644 --- a/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java +++ b/pqs-harmonic/harmonic-common/src/main/java/com/njcn/harmonic/common/service/impl/CustomReportTableServiceImpl.java @@ -39,10 +39,8 @@ import com.njcn.system.pojo.po.EleEpdPqd; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.stereotype.Service; @@ -311,6 +309,8 @@ public class CustomReportTableServiceImpl implements CustomReportTableService { } } + + private String saveReport(JSONArray jsonArray, Map dataMap) { String filePath = ""; Workbook workbook = new XSSFWorkbook(); @@ -322,46 +322,118 @@ public class CustomReportTableServiceImpl implements CustomReportTableService { Sheet sheet = workbook.createSheet(sheetName); - if (data != null) { + List mergeRegions = new ArrayList<>(); + List mergedCellInfos = new ArrayList<>(); + + if (data != null && !data.isEmpty()) { + boolean hasMergeMark = false; + for (int j = 0; j < data.size(); j++) { Row row = sheet.createRow(j); JSONArray rowData = data.getJSONArray(j); if (rowData != null) { for (int k = 0; k < rowData.size(); k++) { - Cell cell = row.createCell(k); JSONObject cellObj = rowData.getJSONObject(k); - if (cellObj != null && !cellObj.isEmpty()) { - Object v = cellObj.get("v"); - if (v != null) { - Object vData = dataMap.get(v); - if (vData != null) { - if (vData instanceof String) { - cell.setCellValue((String) vData); - } else if (vData instanceof Number) { - cell.setCellValue(((Number) vData).doubleValue()); - } else if (vData instanceof Boolean) { - cell.setCellValue((Boolean) vData); - } else { - cell.setCellValue(vData.toString()); + if (cellObj == null || cellObj.isEmpty()) { + continue; + } + + JSONObject mc = cellObj.getJSONObject("mc"); + + if (mc != null && !mc.isEmpty()) { + hasMergeMark = true; + + Integer rs = mc.getInt("rs"); + Integer cs = mc.getInt("cs"); + Integer mr = mc.getInt("r"); + Integer mcCol = mc.getInt("c"); + + if (rs != null && cs != null && mr != null && mcCol != null) { + if (mr == j && mcCol == k) { + int endRow = j + rs - 1; + int endCol = k + cs - 1; + if (endRow > j || endCol > k) { + mergeRegions.add(new CellRangeAddress(j, endRow, k, endCol)); + + MergedCellInfo info = new MergedCellInfo(); + info.row = j; + info.col = k; + info.cellObj = cellObj; + mergedCellInfos.add(info); } } else { - if (v instanceof String) { - cell.setCellValue((String) v); - } else if (v instanceof Number) { - cell.setCellValue(((Number) v).doubleValue()); - } else if (v instanceof Boolean) { - cell.setCellValue((Boolean) v); - } else { - cell.setCellValue(v.toString()); - } + continue; } } } + + Cell cell = row.createCell(k); + Object v = cellObj.get("v"); + + if (v != null) { + Object vData = dataMap.get(v); + if (vData != null) { + setCellValue(cell, vData); + } else { + setCellValue(cell, v); + } + } } } } + + if (!hasMergeMark) { + detectAndMergeCells(data, mergeRegions, mergedCellInfos); + } + } + + for (CellRangeAddress mergeRegion : mergeRegions) { + try { + sheet.addMergedRegion(mergeRegion); + } catch (Exception e) { + log.warn("添加合并单元格失败:{}", mergeRegion.formatAsString()); + } + } + + for (MergedCellInfo info : mergedCellInfos) { + Row row = sheet.getRow(info.row); + if (row != null) { + Cell cell = row.getCell(info.col); + if (cell != null) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + + Font font = workbook.createFont(); + font.setFontName("宋体"); + font.setFontHeightInPoints((short) 11); + style.setFont(font); + style.setWrapText(true); + + if (Objects.equals(cell.getStringCellValue(),"非谐波统计报表") + || Objects.equals(cell.getStringCellValue(),"谐波电压统计报表") + || Objects.equals(cell.getStringCellValue(),"谐波电流统计报表")) { + font.setFontHeightInPoints((short) 18); + font.setBold(true); + } + if (Objects.equals(cell.getStringCellValue(),"有效值") + || Objects.equals(cell.getStringCellValue(),"功率") + || Objects.equals(cell.getStringCellValue(),"电压闪变") + || Objects.equals(cell.getStringCellValue(),"畸变率") + || Objects.equals(cell.getStringCellValue(),"电压偏差") + || Objects.equals(cell.getStringCellValue(),"频率") + || Objects.equals(cell.getStringCellValue(),"三相不平衡度") + || Objects.equals(cell.getStringCellValue(),"谐波电压含有率") + || Objects.equals(cell.getStringCellValue(),"谐波电流幅值")) { + font.setFontHeightInPoints((short) 15); + font.setBold(true); + } + + cell.setCellStyle(style); + } + } } } @@ -384,6 +456,106 @@ public class CustomReportTableServiceImpl implements CustomReportTableService { return filePath; } + /** + * 检测并合并单元格(当没有 mc 标记时) + */ + private void detectAndMergeCells(JSONArray data, List mergeRegions, + List mergedCellInfos) { + int rows = data.size(); + if (rows == 0) return; + + int cols = 0; + JSONArray firstRow = data.getJSONArray(0); + if (firstRow != null) { + cols = firstRow.size(); + } + + boolean[][] merged = new boolean[rows][cols]; + + for (int j = 0; j < rows; j++) { + JSONArray rowData = data.getJSONArray(j); + if (rowData == null) continue; + + for (int k = 0; k < rowData.size(); k++) { + if (merged[j][k]) continue; + + JSONObject cellObj = rowData.getJSONObject(k); + if (cellObj == null || cellObj.isEmpty()) continue; + + Object v = cellObj.get("v"); + if (v == null || StrUtil.isBlank(v.toString())) continue; + + int mergeEndRow = j; + int mergeEndCol = k; + + for (int r = j + 1; r < rows; r++) { + JSONArray nextRow = data.getJSONArray(r); + if (nextRow == null || k >= nextRow.size()) break; + + JSONObject nextCellObj = nextRow.getJSONObject(k); + if (nextCellObj == null || nextCellObj.isEmpty()) break; + + Object nextV = nextCellObj.get("v"); + if (nextV == null || !String.valueOf(v).equals(String.valueOf(nextV))) break; + + mergeEndRow = r; + merged[r][k] = true; + } + + for (int c = k + 1; c < cols; c++) { + if (j >= rowData.size()) break; + + JSONObject rightCellObj = rowData.getJSONObject(c); + if (rightCellObj == null || rightCellObj.isEmpty()) break; + + Object rightV = rightCellObj.get("v"); + if (rightV == null || !String.valueOf(v).equals(String.valueOf(rightV))) break; + + mergeEndCol = c; + merged[j][c] = true; + } + + if (mergeEndRow > j || mergeEndCol > k) { + mergeRegions.add(new CellRangeAddress(j, mergeEndRow, k, mergeEndCol)); + + MergedCellInfo info = new MergedCellInfo(); + info.row = j; + info.col = k; + info.cellObj = cellObj; + mergedCellInfos.add(info); + } + } + } + } + + /** + * 设置单元格值 + */ + private void setCellValue(Cell cell, Object value) { + if (value == null) { + return; + } + if (value instanceof String) { + cell.setCellValue((String) value); + } else if (value instanceof Number) { + cell.setCellValue(((Number) value).doubleValue()); + } else if (value instanceof Boolean) { + cell.setCellValue((Boolean) value); + } else if (value instanceof Date) { + cell.setCellValue((Date) value); + } else { + cell.setCellValue(value.toString()); + } + } + + /** + * 合并单元格信息内部类 + */ + private static class MergedCellInfo { + int row; + int col; + JSONObject cellObj; + } /** * 处理 diff --git a/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/UserServiceImpl.java b/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/UserServiceImpl.java index a33970662..abef285ac 100644 --- a/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/UserServiceImpl.java +++ b/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/UserServiceImpl.java @@ -580,7 +580,15 @@ public class UserServiceImpl extends ServiceImpl implements IU if (CollectionUtil.isEmpty(ids)) { return new ArrayList<>(); } - return this.baseMapper.getUserVOByIdList(ids); + List list = this.baseMapper.getUserVOByIdList(ids); + if (CollectionUtil.isNotEmpty(list)) { + list.forEach(item->{ + List roles = userRoleService.getRoleListByUserId(item.getId()); + item.setRoleList(roles.stream().map(Role::getId).collect(Collectors.toList())); + item.setRoleCode(roles.stream().map(Role::getCode).collect(Collectors.toList())); + }); + } + return list; } @Override