diff --git a/src/main/java/com/gunshi/project/hsz/controller/HisWaterDataController.java b/src/main/java/com/gunshi/project/hsz/controller/HisWaterDataController.java index ea55c32..78a63e8 100644 --- a/src/main/java/com/gunshi/project/hsz/controller/HisWaterDataController.java +++ b/src/main/java/com/gunshi/project/hsz/controller/HisWaterDataController.java @@ -7,6 +7,7 @@ import com.gunshi.project.hsz.common.model.so.JcskSlBPageSo; import com.gunshi.project.hsz.common.validate.markers.Insert; import com.gunshi.project.hsz.common.validate.markers.Update; import com.gunshi.project.hsz.entity.so.HisWaterDataPageSo; +import com.gunshi.project.hsz.entity.vo.HisWaterDataVo; import com.gunshi.project.hsz.mapper.HisWaterDataMapper; import com.gunshi.project.hsz.model.HisWaterData; import com.gunshi.project.hsz.service.HisWaterDataService; @@ -35,40 +36,37 @@ public class HisWaterDataController { @Operation(summary = "分页") @PostMapping("/page") - public R> page(@RequestBody @Validated HisWaterDataPageSo page) { + public R> page(@RequestBody @Validated HisWaterDataPageSo page) { return R.ok(hisWaterDataService.pageQuery(page)); } @Operation(summary = "新增") @PostMapping("/insert") - public R insert(@Validated(Insert.class) @RequestBody HisWaterData dto) { + public R insert(@Validated(Insert.class) @RequestBody HisWaterDataVo dto) { boolean result = hisWaterDataService.saveData(dto); - return R.ok(result ? dto : null); + return R.ok(result); } @Operation(summary = "修改") @PostMapping("/update") - public R update(@Validated(Update.class) @RequestBody HisWaterData dto) { - boolean result = hisWaterDataService.updateById(dto); - return R.ok(result ? dto : null); + public R update(@Validated(Update.class) @RequestBody HisWaterDataVo dto) { + boolean result = hisWaterDataService.updateData(dto); + return R.ok(result); } @Operation(summary = "删除") @GetMapping("/del/{id}") public R del(@Schema(name = "id") @PathVariable("id") Serializable id) { - if (Objects.isNull(hisWaterDataService.getById(id))) { - throw new IllegalArgumentException("当前数据不存在"); - } - return R.ok(hisWaterDataService.removeById(id)); + return R.ok(hisWaterDataService.removeData(id)); } @Operation(summary = "导出") @PostMapping("/export") public void export(@RequestBody @Validated HisWaterDataPageSo pageSo, HttpServletResponse response) { pageSo.getPageSo().setPageSize(99999); - Page hisWaterDataPage = hisWaterDataService.pageQuery(pageSo); - List records = hisWaterDataPage.getRecords(); + Page hisWaterDataPage = hisWaterDataService.pageQuery(pageSo); + List records = hisWaterDataPage.getRecords(); hisWaterDataService.export(records,response); } } diff --git a/src/main/java/com/gunshi/project/hsz/entity/vo/HisWaterDataVo.java b/src/main/java/com/gunshi/project/hsz/entity/vo/HisWaterDataVo.java index e3d0d9c..70aa89a 100644 --- a/src/main/java/com/gunshi/project/hsz/entity/vo/HisWaterDataVo.java +++ b/src/main/java/com/gunshi/project/hsz/entity/vo/HisWaterDataVo.java @@ -2,8 +2,13 @@ package com.gunshi.project.hsz.entity.vo; import com.gunshi.project.hsz.model.HisWaterData; import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) @Data -public class HisWaterDataVo { +public class HisWaterDataVo extends HisWaterData{ + private List list; } diff --git a/src/main/java/com/gunshi/project/hsz/mapper/HisWaterDataMapper.java b/src/main/java/com/gunshi/project/hsz/mapper/HisWaterDataMapper.java index e12b910..95eb39c 100644 --- a/src/main/java/com/gunshi/project/hsz/mapper/HisWaterDataMapper.java +++ b/src/main/java/com/gunshi/project/hsz/mapper/HisWaterDataMapper.java @@ -1,9 +1,22 @@ package com.gunshi.project.hsz.mapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gunshi.project.hsz.entity.so.HisWaterDataPageSo; +import com.gunshi.project.hsz.entity.vo.HisWaterDataVo; import com.gunshi.project.hsz.model.HisWaterData; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; @Mapper public interface HisWaterDataMapper extends BaseMapper { + + @Select(""" + select * from his_water_data where type = 1 + order by year desc +""") + Page queryPage(Page page, @Param("obj") HisWaterDataPageSo queryWrapper); + } diff --git a/src/main/java/com/gunshi/project/hsz/model/HisWaterData.java b/src/main/java/com/gunshi/project/hsz/model/HisWaterData.java index f194012..a8af5ba 100644 --- a/src/main/java/com/gunshi/project/hsz/model/HisWaterData.java +++ b/src/main/java/com/gunshi/project/hsz/model/HisWaterData.java @@ -20,11 +20,11 @@ public class HisWaterData { @TableField("year") @Schema(description = "年度") - private String year; + private Integer year; @TableField("month") @Schema(description = "月份") - private String month; + private Integer month; @TableField("avg_water") @Schema(description = "月份平均蓄水量") @@ -35,4 +35,11 @@ public class HisWaterData { private BigDecimal totalWater; + /** + * 类型(1年 2月) + */ + @TableField(value="type") + @Schema(description="类型(1年 2月)") + private Integer type; + } diff --git a/src/main/java/com/gunshi/project/hsz/service/HisWaterDataService.java b/src/main/java/com/gunshi/project/hsz/service/HisWaterDataService.java index 0aabe36..2faa86d 100644 --- a/src/main/java/com/gunshi/project/hsz/service/HisWaterDataService.java +++ b/src/main/java/com/gunshi/project/hsz/service/HisWaterDataService.java @@ -1,128 +1,176 @@ package com.gunshi.project.hsz.service; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.WriteTable; +import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gunshi.project.hsz.entity.so.HisWaterDataPageSo; +import com.gunshi.project.hsz.entity.vo.HisWaterDataVo; import com.gunshi.project.hsz.mapper.HisWaterDataMapper; import com.gunshi.project.hsz.model.HisWaterData; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; -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.xssf.usermodel.XSSFWorkbook; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.math.BigDecimal; +import java.io.IOException; +import java.io.Serializable; +import java.net.URLEncoder; +import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; @Service @Slf4j @Transactional(rollbackFor = Exception.class) public class HisWaterDataService extends ServiceImpl { - public Page pageQuery(HisWaterDataPageSo page) { - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.last("order by year desc,month asc"); - Page hisWaterDataPage = this.baseMapper.selectPage(page.getPageSo().toPage(), queryWrapper); - List records = hisWaterDataPage.getRecords(); - // 按年度分组 - Map> groupedByYear = records.stream() - .collect(Collectors.groupingBy(HisWaterData::getYear)); - // 遍历每个年度,计算并设置年度总蓄水量 - for (Map.Entry> entry : groupedByYear.entrySet()) { - String year = entry.getKey(); - List yearData = entry.getValue(); - // 计算年度总蓄水量 - BigDecimal totalWater = yearData.stream() - .map(HisWaterData::getAvgWater) - .filter(Objects::nonNull) - .reduce(BigDecimal.ZERO, BigDecimal::add); - // 为每个该年度的数据设置总蓄水量 - for (HisWaterData data : yearData) { - data.setTotalWater(totalWater); - } - } + public Page pageQuery(HisWaterDataPageSo page) { + Page hisWaterDataPage = this.baseMapper.queryPage(page.getPageSo().toPage(),page); + fillList(hisWaterDataPage); return hisWaterDataPage; } - public boolean saveData(HisWaterData dto) { - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(HisWaterData::getYear,dto.getYear()); - queryWrapper.eq(HisWaterData::getMonth,dto.getMonth()); - HisWaterData hisWaterData = this.baseMapper.selectOne(queryWrapper); - if (hisWaterData != null) { - throw new IllegalArgumentException(dto.getYear() + "年-" + dto.getMonth() +"月,数据已存在,请勿重复添加"); + private void fillList(Page ret) { + if (ret.getRecords() != null) { + queryChild(ret.getRecords()); } - return this.baseMapper.insert(dto) > 0; } - public void export(List records, HttpServletResponse response) { + private void queryChild(List records) { + for (HisWaterDataVo record : records) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(HisWaterData::getYear, record.getYear()) + .eq(HisWaterData::getType,record.getType()) + .orderByAsc(HisWaterData::getMonth); + record.setList(this.list(queryWrapper)); + } + } + + public boolean saveData(HisWaterDataVo dto) { + checkParam(dto); + HisWaterData hisWaterData = new HisWaterData(); + BeanUtils.copyProperties(dto,hisWaterData); + List list = dto.getList(); + list.add(hisWaterData); + boolean flag = saveBatch(list); + return flag; + } + + private void checkParam(HisWaterDataVo dto) { + Long id = dto.getId(); + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(HisWaterData::getYear,dto.getYear()) + .eq(HisWaterData::getType,1); + if(id != null){ + queryWrapper.ne(HisWaterData::getId,id); + } + if(this.count(queryWrapper ) > 0){ + throw new IllegalArgumentException("该年份已存在历史降雨资料"); + } + Long len = dto.getList().stream().map(HisWaterData::getMonth).distinct().collect(Collectors.counting()); + if(dto.getList().size() != len.intValue()){ + throw new IllegalArgumentException("月份不可重复"); + } + } + + + public boolean updateData(HisWaterDataVo dto) { + checkParam(dto); + HisWaterData hisWaterData = new HisWaterData(); + BeanUtils.copyProperties(dto,hisWaterData); + updateById(hisWaterData); + deleteMonthData(dto.getYear()); + List list = dto.getList(); + return saveBatch(list); + } + + private void deleteMonthData(Integer year) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(HisWaterData::getYear,year) + .eq(HisWaterData::getType,2); + this.remove(queryWrapper); + } + + public Boolean removeData(Serializable id) { + HisWaterData hisWaterData = this.getById(id); + deleteMonthData(hisWaterData.getYear()); + return this.removeById(id); + } + + public void export(List records, HttpServletResponse response) { try { - Workbook workbook = new XSSFWorkbook(); - Sheet sheet = workbook.createSheet("蓄水量数据"); + // 设置响应头 + String fileName = URLEncoder.encode("历史蓄水量数据", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); - int rowNum = 0; + // 创建ExcelWriter + ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自动列宽 + .build(); - // 按年度分组 - Map> groupedByYear = records.stream() - .collect(Collectors.groupingBy(HisWaterData::getYear)); + // 创建主工作表 + WriteSheet writeSheet = EasyExcel.writerSheet("历史蓄水量数据").build(); - // 遍历每个年度 - for (Map.Entry> entry : groupedByYear.entrySet()) { - String year = entry.getKey(); - List yearData = entry.getValue(); + // 当前行数据 + List> dataList = new ArrayList<>(); - // 计算年度总蓄水量 - BigDecimal totalWater = yearData.stream() - .map(HisWaterData::getAvgWater) - .filter(Objects::nonNull) - .reduce(BigDecimal.ZERO, BigDecimal::add); + // 遍历每年的数据 + for (HisWaterDataVo yearData : records) { + // 添加年份标题行 + List yearRow = new ArrayList<>(); + yearRow.add(yearData.getYear() + "年"); + yearRow.add(""); // 第二列为空 + dataList.add(yearRow); - // 写入年度和总蓄水量(每个值单独单元格) - Row yearRow = sheet.createRow(rowNum++); - yearRow.createCell(0).setCellValue("年:"); - yearRow.createCell(1).setCellValue(year); - yearRow.createCell(2).setCellValue("总蓄水量(万m³):"); - yearRow.createCell(3).setCellValue(totalWater.toString()); + // 添加表头 + List headerRow = new ArrayList<>(); + headerRow.add("月份"); + headerRow.add("月份平均蓄水量"); + dataList.add(headerRow); - // 写入月份数据 - for (HisWaterData data : yearData) { - Row monthRow = sheet.createRow(rowNum++); - monthRow.createCell(0).setCellValue("月份:"); - monthRow.createCell(1).setCellValue(data.getMonth()); - monthRow.createCell(2).setCellValue("平均蓄水量(万m³):"); - if (data.getAvgWater() != null) { - monthRow.createCell(3).setCellValue(data.getAvgWater().toString()); - } else { - monthRow.createCell(3).setCellValue(""); + // 添加月份数据 + if (yearData.getList() != null) { + for (HisWaterData monthData : yearData.getList()) { + List monthRow = new ArrayList<>(); + monthRow.add(monthData.getMonth() + "月"); + monthRow.add(monthData.getAvgWater()); + dataList.add(monthRow); } } - // 年度之间空一行 - rowNum++; + // 添加年度总蓄水量行 + List totalRow = new ArrayList<>(); + totalRow.add("年度总蓄水量"); + totalRow.add(yearData.getTotalWater()); + dataList.add(totalRow); + + // 添加空行分隔 + dataList.add(new ArrayList<>()); + dataList.add(new ArrayList<>()); } - // 简单自适应列宽 - for (int i = 0; i < 4; i++) { - sheet.autoSizeColumn(i); - } + // 创建表格并写入数据 + WriteTable writeTable = EasyExcel.writerTable() + .needHead(false) // 不显示表头,因为我们手动添加了 + .build(); - // 设置响应头 - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setHeader("Content-Disposition", "attachment; filename=water_data.xlsx"); + // 写入数据 + excelWriter.write(dataList, writeSheet, writeTable); - // 写入响应流 - workbook.write(response.getOutputStream()); - workbook.close(); + // 关闭流 + excelWriter.finish(); - } catch (Exception e) { + } catch (IOException e) { throw new RuntimeException("导出Excel失败", e); } } diff --git a/src/main/java/com/gunshi/project/hsz/timetask/WarningRuleTask.java b/src/main/java/com/gunshi/project/hsz/timetask/WarningRuleTask.java index 821472b..7af1698 100644 --- a/src/main/java/com/gunshi/project/hsz/timetask/WarningRuleTask.java +++ b/src/main/java/com/gunshi/project/hsz/timetask/WarningRuleTask.java @@ -352,6 +352,7 @@ public class WarningRuleTask { List hisWaterDataList = hisWaterDataService.lambdaQuery() .eq(HisWaterData::getYear, year) .eq(HisWaterData::getMonth, month) + .eq(HisWaterData::getType,2) .list(); BigDecimal baseWaterStorage = BigDecimal.ZERO;