From 95735bb65f64fd1e3700cea191e56ceadf75e873 Mon Sep 17 00:00:00 2001 From: maxiangong <298222784@qq.com> Date: Mon, 25 May 2026 09:48:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=83=BD=E8=80=97=E7=9B=AE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BsEnergyMonitorController.java | 49 ++--- .../controller/BsEnergyTargetController.java | 190 ++++-------------- .../excel/BsEnergyTargetElectricExcel.java | 76 ------- ...terExcel.java => BsEnergyTargetExcel.java} | 57 +++++- .../energy/mapper/BsEnergyTargetMapper.java | 48 +++-- .../desk/energy/mapper/EnergyTargetMapper.xml | 70 ++++--- .../desk/energy/pojo/vo/BsEnergyTargetVO.java | 113 ++++++++++- .../service/IBsEnergyTargetService.java | 38 +--- .../impl/BsEnergyTargetServiceImpl.java | 91 +++++---- .../resources/Excel/energy/用电目标.xls | Bin 20480 -> 0 bytes .../{用水目标.xls => 能耗目标.xls} | Bin 20480 -> 20480 bytes 11 files changed, 333 insertions(+), 399 deletions(-) delete mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetElectricExcel.java rename blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/{BsEnergyTargetWaterExcel.java => BsEnergyTargetExcel.java} (60%) delete mode 100644 blade-service/blade-desk/src/main/resources/Excel/energy/用电目标.xls rename blade-service/blade-desk/src/main/resources/Excel/energy/{用水目标.xls => 能耗目标.xls} (95%) diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyMonitorController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyMonitorController.java index ebbb8456d..99ec4406b 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyMonitorController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyMonitorController.java @@ -104,16 +104,16 @@ public class BsEnergyMonitorController extends BladeController { if (exist != null && !exist.getId().equals(bsEnergyMonitor.getId())) { return R.fail(bsEnergyMonitor.getMonth() + "月份能源监控表已存在"); } - if(bsEnergyMonitor.getLastWater() != null && bsEnergyMonitor.getLastOutput() != null){ + if (bsEnergyMonitor.getLastWater() != null && bsEnergyMonitor.getLastOutput() != null) { bsEnergyMonitor.setLastWaterRate(bsEnergyMonitor.getLastWater().divide(bsEnergyMonitor.getLastOutput(), 6, RoundingMode.HALF_UP)); } - if(bsEnergyMonitor.getLastElectric() != null && bsEnergyMonitor.getLastOutput() != null){ + if (bsEnergyMonitor.getLastElectric() != null && bsEnergyMonitor.getLastOutput() != null) { bsEnergyMonitor.setLastElectricRate(bsEnergyMonitor.getLastElectric().divide(bsEnergyMonitor.getLastOutput(), 6, RoundingMode.HALF_UP)); } - if(bsEnergyMonitor.getCurrentWater() != null && bsEnergyMonitor.getCurrentOutput() != null){ + if (bsEnergyMonitor.getCurrentWater() != null && bsEnergyMonitor.getCurrentOutput() != null) { bsEnergyMonitor.setCurrentWaterRate(bsEnergyMonitor.getCurrentWater().divide(bsEnergyMonitor.getCurrentOutput(), 6, RoundingMode.HALF_UP)); } - if(bsEnergyMonitor.getCurrentElectric() != null && bsEnergyMonitor.getCurrentOutput() != null){ + if (bsEnergyMonitor.getCurrentElectric() != null && bsEnergyMonitor.getCurrentOutput() != null) { bsEnergyMonitor.setCurrentElectricRate(bsEnergyMonitor.getCurrentElectric().divide(bsEnergyMonitor.getCurrentOutput(), 6, RoundingMode.HALF_UP)); } } @@ -148,28 +148,17 @@ public class BsEnergyMonitorController extends BladeController { @GetMapping("/getLastYearDetail") @Operation(summary = "上年度详情", description = "传入bsEnergyMonitor") public R getLastYearDetail(BsEnergyMonitorEntity bsEnergyMonitor) { - YearMonth currentMonth = YearMonth.parse(bsEnergyMonitor.getMonth()); - String currentYear = String.valueOf(currentMonth.getYear()); - YearMonth lastYearMonth = currentMonth.minusYears(1); - String lastMonth = lastYearMonth.toString(); + YearMonth currentYearMonth = YearMonth.parse(bsEnergyMonitor.getMonth()); + String currentYear = String.valueOf(currentYearMonth.getYear()); + String month = String.format("%02d", currentYearMonth.getMonthValue()); + YearMonth lastYearMonth = currentYearMonth.minusYears(1); String lastYear = String.valueOf(lastYearMonth.getYear()); - String quarter = this.getQuarter(currentMonth.getMonth().getValue()); BsEnergyMonitorEntity detail = new BsEnergyMonitorEntity(); - BsEnergyMonitorEntity lastYearDetail = bsEnergyMonitorService.getOne(new LambdaQueryWrapper().eq(BsEnergyMonitorEntity::getMonth, lastMonth)); - BsEnergyTargetEntity lastYearWaterTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, lastYear) - .eq(BsEnergyTargetEntity::getType, "1")); - BsEnergyTargetEntity currentYearWaterTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, currentYear) - .eq(BsEnergyTargetEntity::getType, "1")); - BsEnergyTargetEntity lastYearElectricTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, lastYear) - .eq(BsEnergyTargetEntity::getQuarter, quarter) - .eq(BsEnergyTargetEntity::getType, "2")); - BsEnergyTargetEntity currentYearElectricTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, currentYear) - .eq(BsEnergyTargetEntity::getQuarter, quarter) - .eq(BsEnergyTargetEntity::getType, "2")); + BsEnergyMonitorEntity lastYearDetail = bsEnergyMonitorService.getOne(new LambdaQueryWrapper().eq(BsEnergyMonitorEntity::getMonth, lastYearMonth.toString())); + BsEnergyTargetEntity lastYearWaterTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper().eq(BsEnergyTargetEntity::getYear, lastYear).eq(BsEnergyTargetEntity::getMonth, month).eq(BsEnergyTargetEntity::getType, "1")); + BsEnergyTargetEntity currentYearWaterTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper().eq(BsEnergyTargetEntity::getYear, currentYear).eq(BsEnergyTargetEntity::getMonth, month).eq(BsEnergyTargetEntity::getType, "1")); + BsEnergyTargetEntity lastYearElectricTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper().eq(BsEnergyTargetEntity::getYear, lastYear).eq(BsEnergyTargetEntity::getMonth, month).eq(BsEnergyTargetEntity::getType, "2")); + BsEnergyTargetEntity currentYearElectricTarget = bsEnergyTargetService.getOne(new LambdaQueryWrapper().eq(BsEnergyTargetEntity::getYear, currentYear).eq(BsEnergyTargetEntity::getMonth, month).eq(BsEnergyTargetEntity::getType, "2")); if (lastYearDetail != null) { detail.setLastWater(lastYearDetail.getCurrentWater()); detail.setLastElectric(lastYearDetail.getCurrentElectric()); @@ -192,16 +181,4 @@ public class BsEnergyMonitorController extends BladeController { return R.data(detail); } - - public static String getQuarter(int month) { - if (month <= 3) { - return "1"; - } else if (month <= 6) { - return "2"; - } else if (month <= 9) { - return "3"; - } else { - return "4"; - } - } } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyTargetController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyTargetController.java index c46dcb003..5af06a124 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyTargetController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/controller/BsEnergyTargetController.java @@ -26,9 +26,10 @@ package org.springblade.desk.energy.controller; import cn.hutool.core.bean.BeanUtil; +import com.alibaba.excel.util.StringUtils; +import com.alibaba.nacos.common.utils.CollectionUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -45,21 +46,19 @@ import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.DateUtil; import org.springblade.core.tool.utils.Func; import org.springblade.desk.basic.util.ExcelExtUtil; -import org.springblade.desk.energy.excel.BsEnergyTargetElectricExcel; -import org.springblade.desk.energy.excel.BsEnergyTargetWaterExcel; +import org.springblade.desk.energy.excel.BsEnergyTargetExcel; import org.springblade.desk.energy.pojo.entity.BsEnergyTargetEntity; import org.springblade.desk.energy.pojo.vo.BsEnergyTargetVO; import org.springblade.desk.energy.service.IBsEnergyTargetService; -import org.springblade.desk.energy.wrapper.BsEnergyTargetWrapper; -import org.springframework.beans.BeanUtils; import org.springframework.core.io.Resource; -import org.springframework.data.redis.hash.HashMapper; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * 能耗目标表 控制器 @@ -80,29 +79,16 @@ public class BsEnergyTargetController extends BladeController { */ @GetMapping("/detail") @Operation(summary = "详情", description = "传入bsEnergyTarget") - public R detail(BsEnergyTargetEntity bsEnergyTarget) { - BsEnergyTargetEntity detail = bsEnergyTargetService.getOne(Condition.getQueryWrapper(bsEnergyTarget)); - return R.data(BsEnergyTargetWrapper.build().entityVO(detail)); - } - - /** - * 能耗目标表 获取用水目标 - */ - @GetMapping("/detailByWater") - @Operation(summary = "根据月份获取用水目标", description = "获取用水目标") - public R getWaterTargetByMonth(String month) { - BigDecimal waterTarget = bsEnergyTargetService.getWaterTargetByMonth(month); - return R.data(waterTarget); - } - - /** - * 能耗目标表 获取用水目标 - */ - @GetMapping("/detailByElectric") - @Operation(summary = "根据月份获取用电目标", description = "获取用电目标") - public R getElectricTargetByMonth(String month) { - BigDecimal electricTarget = bsEnergyTargetService.getElectricTargetByMonth(month); - return R.data(electricTarget); + public R detail(BsEnergyTargetVO bsEnergyTarget) { + if (StringUtils.isEmpty(bsEnergyTarget.getYear()) || StringUtils.isEmpty(bsEnergyTarget.getType())) { + return R.fail("参数错误"); + } + List list = bsEnergyTargetService.selectBsEnergyTargetList(bsEnergyTarget); + if (CollectionUtils.isNotEmpty(list)) { + return R.data(list.get(0)); + } else { + return R.fail("能耗目标详情查询失败"); + } } /** @@ -119,21 +105,23 @@ public class BsEnergyTargetController extends BladeController { * 能耗目标表 新增或修改 */ @PostMapping("/submit") - @Operation(summary = "新增或修改", description = "传入bsEnergyTarget") - public R submit(@Valid @RequestBody BsEnergyTargetEntity bsEnergyTarget) { - BsEnergyTargetEntity bsEnergyTargetEntity = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, bsEnergyTarget.getYear()) - .eq(BsEnergyTargetEntity::getType, bsEnergyTarget.getType()) - .eq(bsEnergyTarget.getQuarter() != null, BsEnergyTargetEntity::getQuarter, bsEnergyTarget.getQuarter())); - if (bsEnergyTargetEntity != null && !bsEnergyTargetEntity.getId().equals(bsEnergyTarget.getId())) { - if ("1".equals(bsEnergyTarget.getType())) { - return R.fail("该年份能耗目标已存在"); - } - if ("2".equals(bsEnergyTarget.getType())) { - return R.fail("该季度能耗目标已存在"); + @Operation(summary = "新增或修改", description = "传入bsEnergyTargetList") + public R submit(@Valid @RequestBody List bsEnergyTargetList) { + List years = bsEnergyTargetList.stream().map(BsEnergyTargetVO::getYear).collect(Collectors.toList()); + List existList = bsEnergyTargetService.list(new LambdaQueryWrapper().in(BsEnergyTargetEntity::getYear, years)); + Map existMap = existList.stream().collect(Collectors.toMap(e -> e.getYear() + "-" + e.getMonth() + "-" + e.getType(), BsEnergyTargetEntity::getId, (oldValue, newValue) -> oldValue)); + List saves = new ArrayList<>(); + for (BsEnergyTargetVO bsEnergyTargetVO : bsEnergyTargetList) { + List bsEnergyTargetEntities = bsEnergyTargetVO.parseEntities(); + for (BsEnergyTargetEntity bsEnergyTarget : bsEnergyTargetEntities) { + String key = bsEnergyTarget.getYear() + "-" + bsEnergyTarget.getMonth() + "-" + bsEnergyTarget.getType(); + if (existMap.containsKey(key)) { + bsEnergyTarget.setId(existMap.get(key)); + } } + saves.addAll(bsEnergyTargetEntities); } - return R.status(bsEnergyTargetService.saveOrUpdate(bsEnergyTarget)); + return R.status(bsEnergyTargetService.saveOrUpdateBatch(saves)); } /** @@ -152,130 +140,40 @@ public class BsEnergyTargetController extends BladeController { @GetMapping("/export-bsEnergyTarget") @Operation(summary = "导出数据", description = "传入bsEnergyTarget") public void exportBsEnergyTarget(@Parameter(hidden = true) @RequestParam Map bsEnergyTarget, BladeUser bladeUser, HttpServletResponse response) { - Map conMap = new HashMap(); - conMap.put("type", bsEnergyTarget.get("type")); - conMap.put("isDeleted", 0); - List list = bsEnergyTargetService.listByMap(conMap); - if ("1".equals(bsEnergyTarget.get("type"))) { - List bsEnergyTargetWaterExcels = BeanUtil.copyToList(list, BsEnergyTargetWaterExcel.class); - ExcelUtil.export(response, "用水目标" + DateUtil.time(), "用水目标", bsEnergyTargetWaterExcels, BsEnergyTargetWaterExcel.class); - } else { - List bsEnergyTargetElectricExcels = BeanUtil.copyToList(list, BsEnergyTargetElectricExcel.class); - ExcelUtil.export(response, "用电目标" + DateUtil.time(), "用电目标", bsEnergyTargetElectricExcels, BsEnergyTargetElectricExcel.class); - } + BsEnergyTargetVO vo = new BsEnergyTargetVO(); + vo.setYear((String) bsEnergyTarget.get("year")); + vo.setType((String) bsEnergyTarget.get("type")); + List list = bsEnergyTargetService.selectBsEnergyTargetList(vo); + List bsEnergyTargetExcels = BeanUtil.copyToList(list, BsEnergyTargetExcel.class); + ExcelUtil.export(response, "能耗目标" + DateUtil.time(), "能耗目标", bsEnergyTargetExcels, BsEnergyTargetExcel.class); } @GetMapping("/water-download-excel-template") @Operation(summary = "下载Excel模板", description = "") public ResponseEntity waterDownloadExcelTemplate() { return ExcelExtUtil.downloadXlsTemplate( - "Excel/energy/用水目标.xls", - "导入模版-用水目标.xls"); + "Excel/energy/能耗目标.xls", + "导入模版-能耗目标.xls"); } @GetMapping("/electric-download-excel-template") @Operation(summary = "下载Excel模板", description = "") public ResponseEntity electricDownloadExcelTemplate() { return ExcelExtUtil.downloadXlsTemplate( - "Excel/energy/用电目标.xls", - "导入模版-用电目标.xls"); + "Excel/energy/能耗目标.xls", + "导入模版-能耗目标.xls"); } @PostMapping("/water-import-excel") @Operation(summary = "导入Excel", description = "MultipartFile") public R waterImportExcel(@RequestParam("file") MultipartFile file) { - R checkR = ExcelExtUtil.importExcelCheck(file); - if (checkR != null) { - return checkR; - } - List importList = ExcelUtil.read( - file, 0, 1, BsEnergyTargetWaterExcel.class - ); - boolean result = true; - Set existSet = new HashSet<>(); - StringBuffer msg = new StringBuffer(); - List list = new ArrayList<>(); - for (BsEnergyTargetWaterExcel excel : importList) { - if (existSet.contains(excel.getYear())) { - msg.append("Excel里【" + excel.getYear() + "】重复了\rn"); - result = false; - continue; - } - existSet.add(excel.getYear()); - BsEnergyTargetEntity exist = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, excel.getYear()) - .eq(BsEnergyTargetEntity::getType, "1")); - if (exist != null) { - msg.append(excel.getYear() + "能耗目标已存在\n"); - result = false; - continue; - } - BsEnergyTargetEntity bsEnergyTargetEntity = new BsEnergyTargetEntity(); - BeanUtils.copyProperties(excel, bsEnergyTargetEntity); - bsEnergyTargetEntity.setType("1"); - list.add(bsEnergyTargetEntity); - } - bsEnergyTargetService.saveBatch(list); - if (result) { - return R.success("导入成功"); - } else { - return R.fail(msg.toString()); - } + return bsEnergyTargetService.importExcelData(file, "1"); } @PostMapping("/electric-import-excel") @Operation(summary = "导入Excel", description = "MultipartFile") public R electricImportExcel(@RequestParam("file") MultipartFile file) { - R checkR = ExcelExtUtil.importExcelCheck(file); - if (checkR != null) { - return checkR; - } - List importList = ExcelUtil.read( - file, 0, 1, BsEnergyTargetElectricExcel.class - ); - boolean result = true; - Set existSet = new HashSet<>(); - StringBuffer msg = new StringBuffer(); - List list = new ArrayList<>(); - for (BsEnergyTargetElectricExcel excel : importList) { - String key = excel.getYear() + "-" + excel.getQuarter(); - if (existSet.contains(key)) { - msg.append("Excel里【" + key + "】重复了\rn"); - result = false; - continue; - } - existSet.add(key); - if("第一季度".equals(excel.getQuarter())){ - excel.setQuarter("1"); - } else if("第二季度".equals(excel.getQuarter())){ - excel.setQuarter("2"); - } else if("第三季度".equals(excel.getQuarter())){ - excel.setQuarter("3"); - } else if("第四季度".equals(excel.getQuarter())){ - excel.setQuarter("4"); - } - BsEnergyTargetEntity exist = bsEnergyTargetService.getOne(new LambdaQueryWrapper(). - eq(BsEnergyTargetEntity::getYear, excel.getYear()) - .eq(BsEnergyTargetEntity::getType, "2") - .eq(BsEnergyTargetEntity::getQuarter, excel.getQuarter())); - if (exist != null) { - msg.append(key + "能耗目标已存在\n"); - result = false; - continue; - } - BsEnergyTargetEntity bsEnergyTargetEntity = new BsEnergyTargetEntity(); - BeanUtils.copyProperties(excel, bsEnergyTargetEntity); - bsEnergyTargetEntity.setType("2"); - list.add(bsEnergyTargetEntity); - } - bsEnergyTargetService.saveBatch(list); - if (result) { - return R.success("导入成功"); - } else { - return R.fail(msg.toString()); - } + return bsEnergyTargetService.importExcelData(file, "2"); } - - } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetElectricExcel.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetElectricExcel.java deleted file mode 100644 index 38a727d1e..000000000 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetElectricExcel.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * BladeX Commercial License Agreement - * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. - *

- * Use of this software is governed by the Commercial License Agreement - * obtained after purchasing a license from BladeX. - *

- * 1. This software is for development use only under a valid license - * from BladeX. - *

- * 2. Redistribution of this software's source code to any third party - * without a commercial license is strictly prohibited. - *

- * 3. Licensees may copyright their own code but cannot use segments - * from this software for such purposes. Copyright of this software - * remains with BladeX. - *

- * Using this software signifies agreement to this License, and the software - * must not be used for illegal purposes. - *

- * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is - * not liable for any claims arising from secondary or illegal development. - *

- * Author: Chill Zhuang (bladejava@qq.com) - */ -package org.springblade.desk.energy.excel; - - -import com.alibaba.excel.annotation.ExcelProperty; -import com.alibaba.excel.annotation.write.style.ColumnWidth; -import com.alibaba.excel.annotation.write.style.ContentRowHeight; -import com.alibaba.excel.annotation.write.style.HeadRowHeight; -import lombok.Data; - -import java.io.Serial; -import java.io.Serializable; -import java.math.BigDecimal; - - -/** - * 能耗目标表 Excel实体类 - * - * @author BladeX - * @since 2026-03-02 - */ -@Data -@ColumnWidth(25) -@HeadRowHeight(20) -@ContentRowHeight(18) -public class BsEnergyTargetElectricExcel implements Serializable { - - @Serial - private static final long serialVersionUID = 1L; - - /** - * 年份 - */ - @ColumnWidth(50) - @ExcelProperty("年份") - private String year; - - /** - * 季度 - */ - @ColumnWidth(50) - @ExcelProperty("季度") - private String quarter; - - /** - * 用电目标(kWh/dm²) - */ - @ColumnWidth(50) - @ExcelProperty("用电目标(kWh/dm²)") - private BigDecimal target; - -} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetWaterExcel.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetExcel.java similarity index 60% rename from blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetWaterExcel.java rename to blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetExcel.java index 19c4ebba8..993486b61 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetWaterExcel.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/excel/BsEnergyTargetExcel.java @@ -49,7 +49,7 @@ import java.io.Serial; @ColumnWidth(25) @HeadRowHeight(20) @ContentRowHeight(18) -public class BsEnergyTargetWaterExcel implements Serializable { +public class BsEnergyTargetExcel implements Serializable { @Serial private static final long serialVersionUID = 1L; @@ -57,15 +57,56 @@ public class BsEnergyTargetWaterExcel implements Serializable { /** * 年份 */ - @ColumnWidth(50) + @ColumnWidth(20) @ExcelProperty("年份") private String year; - /** - * 用水目标(L/d㎡) - */ - @ColumnWidth(50) - @ExcelProperty("用水目标(L/d㎡)") - private BigDecimal target; + @ColumnWidth(20) + @ExcelProperty("1月") + private BigDecimal m01Target; + + @ColumnWidth(20) + @ExcelProperty("2月") + private BigDecimal m02Target; + + @ColumnWidth(20) + @ExcelProperty("3月") + private BigDecimal m03Target; + + @ColumnWidth(20) + @ExcelProperty("4月") + private BigDecimal m04Target; + + @ColumnWidth(20) + @ExcelProperty("5月") + private BigDecimal m05Target; + + @ColumnWidth(20) + @ExcelProperty("6月") + private BigDecimal m06Target; + + @ColumnWidth(20) + @ExcelProperty("7月") + private BigDecimal m07Target; + + @ColumnWidth(20) + @ExcelProperty("8月") + private BigDecimal m08Target; + + @ColumnWidth(20) + @ExcelProperty("9月") + private BigDecimal m09Target; + + @ColumnWidth(20) + @ExcelProperty("10月") + private BigDecimal m10Target; + + @ColumnWidth(20) + @ExcelProperty("11月") + private BigDecimal m11Target; + + @ColumnWidth(20) + @ExcelProperty("12月") + private BigDecimal m12Target; } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/BsEnergyTargetMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/BsEnergyTargetMapper.java index d26c8c08c..792058043 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/BsEnergyTargetMapper.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/BsEnergyTargetMapper.java @@ -27,11 +27,9 @@ package org.springblade.desk.energy.mapper; import org.springblade.desk.energy.pojo.entity.BsEnergyTargetEntity; import org.springblade.desk.energy.pojo.vo.BsEnergyTargetVO; -import org.springblade.desk.energy.excel.BsEnergyTargetWaterExcel; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; -import org.apache.ibatis.annotations.Param; + import java.util.List; import java.util.Map; @@ -43,29 +41,29 @@ import java.util.Map; */ public interface BsEnergyTargetMapper extends BaseMapper { - /** - * 自定义分页 - * - * @param page 分页参数 - * @param bsEnergyTarget 查询参数 - * @return List - */ - List selectBsEnergyTargetPage(IPage page, BsEnergyTargetVO bsEnergyTarget); - + /** + * 自定义分页 + * + * @param page 分页参数 + * @param bsEnergyTarget 查询参数 + * @return List + */ + List selectBsEnergyTargetPage(IPage page, BsEnergyTargetVO bsEnergyTarget); - /** - * 获取导出数据 - * - * @param queryWrapper 查询条件 - * @return List - */ - List exportBsEnergyTarget(@Param("ew") Wrapper queryWrapper); + /** + * 自定义查询 + * + * @param bsEnergyTarget + * @return + */ + List selectBsEnergyTargetList(BsEnergyTargetVO bsEnergyTarget); - /** - * 根据条件查询列表 - * @param conMap - * @return - */ - List listByMap(Map conMap); + /** + * 根据条件查询列表 + * + * @param conMap + * @return + */ + List listByMap(Map conMap); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/EnergyTargetMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/EnergyTargetMapper.xml index 88a1bd18c..99c757c6a 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/EnergyTargetMapper.xml +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/mapper/EnergyTargetMapper.xml @@ -20,8 +20,24 @@ - + SELECT * FROM ( + SELECT + year, + TYPE, + MAX(CASE WHEN month = '01' THEN target ELSE NULL END ) AS m01Target, + MAX(CASE WHEN month = '02' THEN target ELSE NULL END ) AS m02Target, + MAX(CASE WHEN month = '03' THEN target ELSE NULL END ) AS m03Target, + MAX(CASE WHEN month = '04' THEN target ELSE NULL END ) AS m04Target, + MAX(CASE WHEN month = '05' THEN target ELSE NULL END ) AS m05Target, + MAX(CASE WHEN month = '06' THEN target ELSE NULL END ) AS m06Target, + MAX(CASE WHEN month = '07' THEN target ELSE NULL END ) AS m07Target, + MAX(CASE WHEN month = '08' THEN target ELSE NULL END ) AS m08Target, + MAX(CASE WHEN month = '09' THEN target ELSE NULL END ) AS m09Target, + MAX(CASE WHEN month = '10' THEN target ELSE NULL END ) AS m10Target, + MAX(CASE WHEN month = '11' THEN target ELSE NULL END ) AS m11Target, + MAX(CASE WHEN month = '12' THEN target ELSE NULL END ) AS m12Target + FROM BS_ENERGY_TARGET is_deleted = 0 @@ -30,13 +46,9 @@ and year = #{bsEnergyTarget.year} - - and quarter = #{bsEnergyTarget.quarter} - - - and status = #{bsEnergyTarget.status} - + GROUP BY year, type + ) ORDER BY ${bsEnergyTarget.orderByField} @@ -44,36 +56,40 @@ DESC - ORDER BY CREATE_TIME DESC + ORDER BY year DESC - - - + SELECT + year, + TYPE, + MAX(CASE WHEN month = '01' THEN target ELSE NULL END ) AS m01Target, + MAX(CASE WHEN month = '02' THEN target ELSE NULL END ) AS m02Target, + MAX(CASE WHEN month = '03' THEN target ELSE NULL END ) AS m03Target, + MAX(CASE WHEN month = '04' THEN target ELSE NULL END ) AS m04Target, + MAX(CASE WHEN month = '05' THEN target ELSE NULL END ) AS m05Target, + MAX(CASE WHEN month = '06' THEN target ELSE NULL END ) AS m06Target, + MAX(CASE WHEN month = '07' THEN target ELSE NULL END ) AS m07Target, + MAX(CASE WHEN month = '08' THEN target ELSE NULL END ) AS m08Target, + MAX(CASE WHEN month = '09' THEN target ELSE NULL END ) AS m09Target, + MAX(CASE WHEN month = '10' THEN target ELSE NULL END ) AS m10Target, + MAX(CASE WHEN month = '11' THEN target ELSE NULL END ) AS m11Target, + MAX(CASE WHEN month = '12' THEN target ELSE NULL END ) AS m12Target FROM BS_ENERGY_TARGET - - and YEAR = #{year} - - - and MONTH = #{month} - - - and QUARTER = #{quarter} - + is_deleted = 0 - and TYPE = #{type} + and type = #{type} - - and IS_DELETED = #{isDeleted} + + and year = #{year} + GROUP BY year, TYPE + ORDER BY year DESC diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/pojo/vo/BsEnergyTargetVO.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/pojo/vo/BsEnergyTargetVO.java index 39414a3b5..a1b7dd058 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/pojo/vo/BsEnergyTargetVO.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/pojo/vo/BsEnergyTargetVO.java @@ -25,10 +25,15 @@ */ package org.springblade.desk.energy.pojo.vo; +import io.swagger.v3.oas.annotations.media.Schema; import org.springblade.desk.energy.pojo.entity.BsEnergyTargetEntity; import lombok.Data; import lombok.EqualsAndHashCode; + import java.io.Serial; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; /** * 能耗目标表 视图实体类 @@ -39,16 +44,102 @@ import java.io.Serial; @Data @EqualsAndHashCode(callSuper = true) public class BsEnergyTargetVO extends BsEnergyTargetEntity { - @Serial - private static final long serialVersionUID = 1L; - - /** - * 排序字段 - */ - private String orderByField; - /** - * true: 升序,false: 降序 - */ - private boolean isAsc; + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "1月") + private BigDecimal m01Target; + + @Schema(description = "2月") + private BigDecimal m02Target; + + @Schema(description = "3月") + private BigDecimal m03Target; + + @Schema(description = "4月") + private BigDecimal m04Target; + + @Schema(description = "5月") + private BigDecimal m05Target; + + @Schema(description = "6月") + private BigDecimal m06Target; + + @Schema(description = "7月") + private BigDecimal m07Target; + + @Schema(description = "8月") + private BigDecimal m08Target; + + @Schema(description = "9月") + private BigDecimal m09Target; + + @Schema(description = "10月") + private BigDecimal m10Target; + + @Schema(description = "11月") + private BigDecimal m11Target; + + @Schema(description = "12月") + private BigDecimal m12Target; + + /** + * 排序字段 + */ + private String orderByField; + /** + * true: 升序,false: 降序 + */ + private boolean isAsc; + + public List parseEntities() { + List list = new ArrayList<>(); + if (m01Target != null) { + list.add(buildEntity("01", m01Target)); + } + if (m02Target != null) { + list.add(buildEntity("02", m02Target)); + } + if (m03Target != null) { + list.add(buildEntity("03", m03Target)); + } + if (m04Target != null) { + list.add(buildEntity("04", m04Target)); + } + if (m05Target != null) { + list.add(buildEntity("05", m05Target)); + } + if (m06Target != null) { + list.add(buildEntity("06", m06Target)); + } + if (m07Target != null) { + list.add(buildEntity("07", m07Target)); + } + if (m08Target != null) { + list.add(buildEntity("08", m08Target)); + } + if (m09Target != null) { + list.add(buildEntity("09", m09Target)); + } + if (m10Target != null) { + list.add(buildEntity("10", m10Target)); + } + if (m11Target != null) { + list.add(buildEntity("11", m11Target)); + } + if (m12Target != null) { + list.add(buildEntity("12", m12Target)); + } + return list; + } + + private BsEnergyTargetEntity buildEntity(String month, BigDecimal target) { + BsEnergyTargetEntity entity = new BsEnergyTargetEntity(); + entity.setYear(super.getYear()); + entity.setMonth(month); + entity.setTarget(target); + entity.setType(super.getType()); + return entity; + } } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/IBsEnergyTargetService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/IBsEnergyTargetService.java index 8247f41b3..d46a192f7 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/IBsEnergyTargetService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/IBsEnergyTargetService.java @@ -25,16 +25,14 @@ */ package org.springblade.desk.energy.service; -import com.baomidou.mybatisplus.core.conditions.Wrapper; +import org.springblade.core.tool.api.R; import org.springblade.desk.energy.pojo.entity.BsEnergyTargetEntity; import org.springblade.desk.energy.pojo.vo.BsEnergyTargetVO; -import org.springblade.desk.energy.excel.BsEnergyTargetWaterExcel; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseService; +import org.springframework.web.multipart.MultipartFile; -import java.math.BigDecimal; import java.util.List; -import java.util.Map; /** * 能耗目标表 服务类 @@ -52,36 +50,20 @@ public interface IBsEnergyTargetService extends BaseService selectBsEnergyTargetPage(IPage page, BsEnergyTargetVO bsEnergyTarget); - - /** - * 导出数据 - * - * @param queryWrapper 查询条件 - * @return List - */ - List exportBsEnergyTarget(Wrapper queryWrapper); - /** - * 根据月份获取用水目标 + * 自定义查询 * - * @param month 月份 - * @return 用水目标 - */ - BigDecimal getWaterTargetByMonth(String month); - - /** - * 根据月份获取用电目标 - * - * @param month 月份 - * @return 用电目标 + * @param bsEnergyTarget + * @return */ - BigDecimal getElectricTargetByMonth(String month); + List selectBsEnergyTargetList(BsEnergyTargetVO bsEnergyTarget); /** - * 根据条件查询列表 + * 数据导入 * - * @param conMap + * @param file + * @param type * @return */ - List listByMap(Map conMap); + R importExcelData(MultipartFile file, String type); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/impl/BsEnergyTargetServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/impl/BsEnergyTargetServiceImpl.java index b65eb467c..fb0c600b7 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/impl/BsEnergyTargetServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/energy/service/impl/BsEnergyTargetServiceImpl.java @@ -26,20 +26,24 @@ package org.springblade.desk.energy.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.springblade.desk.dashboard.utils.DateUtils; +import org.springblade.core.excel.util.ExcelUtil; +import org.springblade.core.tool.api.R; +import org.springblade.desk.basic.util.ExcelExtUtil; +import org.springblade.desk.energy.excel.BsEnergyTargetExcel; import org.springblade.desk.energy.pojo.entity.BsEnergyTargetEntity; import org.springblade.desk.energy.pojo.vo.BsEnergyTargetVO; -import org.springblade.desk.energy.excel.BsEnergyTargetWaterExcel; import org.springblade.desk.energy.mapper.BsEnergyTargetMapper; import org.springblade.desk.energy.service.IBsEnergyTargetService; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; -import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseServiceImpl; +import org.springframework.web.multipart.MultipartFile; -import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * 能耗目标表 服务实现类 @@ -50,46 +54,49 @@ import java.util.Map; @Service public class BsEnergyTargetServiceImpl extends BaseServiceImpl implements IBsEnergyTargetService { - @Override - public IPage selectBsEnergyTargetPage(IPage page, BsEnergyTargetVO bsEnergyTarget) { - return page.setRecords(baseMapper.selectBsEnergyTargetPage(page, bsEnergyTarget)); - } + @Override + public IPage selectBsEnergyTargetPage(IPage page, BsEnergyTargetVO bsEnergyTarget) { + return page.setRecords(baseMapper.selectBsEnergyTargetPage(page, bsEnergyTarget)); + } + @Override + public List selectBsEnergyTargetList(BsEnergyTargetVO bsEnergyTarget) { + return baseMapper.selectBsEnergyTargetList(bsEnergyTarget); + } - @Override - public List exportBsEnergyTarget(Wrapper queryWrapper) { - List bsEnergyTargetList = baseMapper.exportBsEnergyTarget(queryWrapper); - //bsEnergyTargetList.forEach(bsEnergyTarget -> { - // bsEnergyTarget.setTypeName(DictCache.getValue(DictEnum.YES_NO, BsEnergyTarget.getType())); - //}); - return bsEnergyTargetList; - } + @Override + public R importExcelData(MultipartFile file, String type) { + R checkR = ExcelExtUtil.importExcelCheck(file); + if (checkR != null) { + return checkR; + } + List importList = ExcelUtil.read( + file, 0, 1, BsEnergyTargetExcel.class + ); + List voList = importList.stream() + .map(excel -> { + BsEnergyTargetVO vo = new BsEnergyTargetVO(); + BeanUtils.copyProperties(excel, vo); + vo.setType(type); + return vo; + }) + .collect(Collectors.toList()); + List years = importList.stream().map(BsEnergyTargetExcel::getYear).collect(Collectors.toList()); + List existList = this.list(new LambdaQueryWrapper().in(BsEnergyTargetEntity::getYear, years).eq(BsEnergyTargetEntity::getType, type)); + Map existMap = existList.stream().collect(Collectors.toMap(e -> e.getYear() + "-" + e.getMonth() + "-" + e.getType(), BsEnergyTargetEntity::getId, (oldValue, newValue) -> oldValue)); + List saves = new ArrayList<>(); + for (BsEnergyTargetVO bsEnergyTargetVO : voList) { + List bsEnergyTargetEntities = bsEnergyTargetVO.parseEntities(); + for (BsEnergyTargetEntity bsEnergyTarget : bsEnergyTargetEntities) { + String key = bsEnergyTarget.getYear() + "-" + bsEnergyTarget.getMonth() + "-" + bsEnergyTarget.getType(); + if (existMap.containsKey(key)) { + bsEnergyTarget.setId(existMap.get(key)); + } + } + saves.addAll(bsEnergyTargetEntities); + } + return R.status(this.saveOrUpdateBatch(saves)); + } - @Override - public BigDecimal getWaterTargetByMonth(String month) { - BsEnergyTargetEntity energyTargetEntity = this.getOne(new LambdaQueryWrapper() - .eq(BsEnergyTargetEntity::getMonth, month)); - if(energyTargetEntity != null){ - return energyTargetEntity.getTarget(); - } - return new BigDecimal(0); - } - @Override - public BigDecimal getElectricTargetByMonth(String month) { - String year = month.substring(0, 4); - int quarter = DateUtils.getQuarter(Integer.parseInt(month.substring(5, 7))); - BsEnergyTargetEntity energyTargetEntity = this.getOne(new LambdaQueryWrapper() - .eq(BsEnergyTargetEntity::getYear, year) - .eq(BsEnergyTargetEntity::getQuarter, quarter)); - if (energyTargetEntity != null) { - return energyTargetEntity.getTarget(); - } - return new BigDecimal(0); - } - - @Override - public List listByMap(Map conMap){ - return baseMapper.listByMap(conMap); - } } diff --git a/blade-service/blade-desk/src/main/resources/Excel/energy/用电目标.xls b/blade-service/blade-desk/src/main/resources/Excel/energy/用电目标.xls deleted file mode 100644 index 56513094cef29b6d7ca786a5b56000966329c38c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 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 Vwb+|2%kPV45v0_mUimV*WWO%ZKo0-_ delta 218 zcmZozz}T>WaYGIZ+lB1=+se;QE@Ek8ns2xH7mK|u&sG}-AYftCC^gBM?CNButH!_t z6o6pHlDNNqTnu2zcV+Au8Vo)R`V1)y3yn1y{xfhfa7=#fWXfc0H(AN~hbaTY0vUdw zMiz!z1|9}RAbg+<;WIGtfh+-vfB?v74kiHzd$PTYI_q@?HU@*qtgdD}AVG*K28PM* mt~)0S_@CY6_Jf6ufu#uO^3DIemN2uLGFUK}ZC>sd$p`==t1vnM