From e93ea2fdfd2a0953cc322d210ebf974994e2e647 Mon Sep 17 00:00:00 2001 From: lcj <2331845269@qq.com> Date: Thu, 13 Nov 2025 19:34:24 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/common/excel/utils/ExcelUtil.java | 3 + .../impl/ProjectBigScreenServiceImpl.java | 61 +- .../recognizermanager/RecognizerUtils.java | 6 +- .../PgsProgressCategoryController.java | 244 +------- .../PgsProgressPlanDetailAINumberReq.java | 10 + .../enums/PgsProgressCategoryTypeEnum.java | 38 ++ .../PgsProgressCategoryByDayVo.java | 57 ++ .../PgsProgressCategoryDayTotalVo.java | 27 + .../PgsProgressCategoryDetailByDayVo.java | 57 ++ .../PgsProgressCategoryExportTotalVo.java | 66 ++ .../service/IPgsProgressCategoryService.java | 56 ++ .../impl/PgsProgressCategoryServiceImpl.java | 576 +++++++++++++++++- .../impl/BusProjectTeamMemberServiceImpl.java | 25 +- 13 files changed, 942 insertions(+), 284 deletions(-) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/enums/PgsProgressCategoryTypeEnum.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryByDayVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDayTotalVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDetailByDayVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryExportTotalVo.java diff --git a/xinnengyuan/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/xinnengyuan/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java index 70db2b06..3ef4742b 100644 --- a/xinnengyuan/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java +++ b/xinnengyuan/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java @@ -223,6 +223,9 @@ public class ExcelUtil { .head(clazz) .autoCloseStream(false) .registerConverter(new ExcelBigNumberConvert()) + // 自动适配 + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + .registerWriteHandler(new DataWriteHandler(clazz)) .build(); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java index bc1287e6..95c9e4ab 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bigscreen/service/impl/ProjectBigScreenServiceImpl.java @@ -544,11 +544,10 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { List allChildren = progressCategoryService.list( Wrappers.lambdaQuery() .in(progressName.equals("光伏场区"), PgsProgressCategory::getName, gfcqName) - .and(wrapper -> { + .and(wrapper -> wrapper.like(PgsProgressCategory::getAncestors, "," + topId + ",") .or() - .like(PgsProgressCategory::getAncestors, "," + topId); - }) + .like(PgsProgressCategory::getAncestors, "," + topId)) ); if (allChildren.isEmpty()) { return Collections.emptyList(); @@ -836,38 +835,38 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { if (voList != null && !voList.isEmpty()) { for (GpsEquipmentSonVo item : voList) { JSONObject messageObj = new JSONObject(); - messageObj.put("type", "location"); // 消息类型 + messageObj.set("type", "location"); // 消息类型 JSONObject data = new JSONObject(); - data.put("id", item.getModelId()); + data.set("id", item.getModelId()); // 位置信息 JSONObject position = new JSONObject(); - position.put("lat", item.getLocLatitude()); // 纬度 - position.put("lng", item.getLocLongitude()); // 经度 - position.put("alt", item.getLocAltitude()); // 海拔 + position.set("lat", item.getLocLatitude()); // 纬度 + position.set("lng", item.getLocLongitude()); // 经度 + position.set("alt", item.getLocAltitude()); // 海拔 - data.put("position", position); - messageObj.put("data", data); // 设备唯一标识 + data.set("position", position); + messageObj.set("data", data); // 设备唯一标识 maps.add(messageObj.toString()); } } if (appList != null && !appList.isEmpty()) { for (GpsEquipmentSonVo item : appList) { JSONObject messageObj = new JSONObject(); - messageObj.put("type", "location"); // 消息类型 + messageObj.set("type", "location"); // 消息类型 JSONObject data = new JSONObject(); - data.put("id", item.getModelId()); + data.set("id", item.getModelId()); // 位置信息 JSONObject position = new JSONObject(); - position.put("lat", item.getLocLatitude()); // 纬度 - position.put("lng", item.getLocLongitude()); // 经度 - position.put("alt", item.getLocAltitude()); // 海拔 + position.set("lat", item.getLocLatitude()); // 纬度 + position.set("lng", item.getLocLongitude()); // 经度 + position.set("alt", item.getLocAltitude()); // 海拔 - data.put("position", position); - messageObj.put("data", data); // 设备唯一标识 + data.set("position", position); + messageObj.set("data", data); // 设备唯一标识 maps.add(messageObj.toString()); } } @@ -883,19 +882,19 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { if (object != null) { JSONObject object1 = JSONUtil.parseObj(object); JSONObject messageObj = new JSONObject(); - messageObj.put("type", "location"); // 消息类型 + messageObj.set("type", "location"); // 消息类型 JSONObject data = new JSONObject(); - data.put("id", key.getAirplaneModleId()); + data.set("id", key.getAirplaneModleId()); // 位置信息 JSONObject position = new JSONObject(); - position.put("lat", object1.getJSONObject("data").get("latitude")); // 纬度 - position.put("lng", object1.getJSONObject("data").get("longitude")); // 经度 - position.put("alt", object1.getJSONObject("data").get("height")); // 海拔 + position.set("lat", object1.getJSONObject("data").get("latitude")); // 纬度 + position.set("lng", object1.getJSONObject("data").get("longitude")); // 经度 + position.set("alt", object1.getJSONObject("data").get("height")); // 海拔 - data.put("position", position); - messageObj.put("data", data); // 设备唯一标识 + data.set("position", position); + messageObj.set("data", data); // 设备唯一标识 maps.add(messageObj.toString()); } else { Object object2 = stringRedisTemplate.opsForValue().get("wrj:osd3:" + key); @@ -903,19 +902,19 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { JSONObject object3 = JSONUtil.parseObj(object2); JSONObject messageObj = new JSONObject(); - messageObj.put("type", "location"); // 消息类型 + messageObj.set("type", "location"); // 消息类型 JSONObject data = new JSONObject(); - data.put("id", key.getDroneModleId()); + data.set("id", key.getDroneModleId()); // 位置信息 JSONObject position = new JSONObject(); - position.put("lat", object3.getJSONObject("data").get("latitude")); // 纬度 - position.put("lng", object3.getJSONObject("data").get("longitude")); // 经度 - position.put("alt", object3.getJSONObject("data").get("height")); // 海拔 + position.set("lat", object3.getJSONObject("data").get("latitude")); // 纬度 + position.set("lng", object3.getJSONObject("data").get("longitude")); // 经度 + position.set("alt", object3.getJSONObject("data").get("height")); // 海拔 - data.put("position", position); - messageObj.put("data", data); // 设备唯一标识 + data.set("position", position); + messageObj.set("data", data); // 设备唯一标识 maps.add(messageObj.toString()); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/recognizermanager/RecognizerUtils.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/recognizermanager/RecognizerUtils.java index 56e78e9c..7f8c23b2 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/recognizermanager/RecognizerUtils.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/recognizermanager/RecognizerUtils.java @@ -126,9 +126,11 @@ public class RecognizerUtils { List point = targetVo.getLeftTopPoint(); List size = targetVo.getSize(); JSONObject pos = new JSONObject(); + int x = point.get(0) + size.get(0) / 2; + int y = point.get(1) + size.get(1) / 2; // 中心点 - pos.set("x", (point.get(0) + size.get(0)) / 2); - pos.set("y", (point.get(1) + size.get(1)) / 2); + pos.set("x", x); + pos.set("y", y); positions.add(pos); } reqJson.set("positions", positions); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsProgressCategoryController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsProgressCategoryController.java index db81b535..f6fd1e15 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsProgressCategoryController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsProgressCategoryController.java @@ -1,47 +1,24 @@ package org.dromara.progress.controller; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.collection.CollUtil; -import com.alibaba.excel.EasyExcel; -import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.read.metadata.ReadSheet; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.domain.R; -import org.dromara.common.core.exception.ServiceException; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.excel.core.DefaultExcelListener; -import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.web.core.BaseController; -import org.dromara.progress.domain.PgsProgressCategory; import org.dromara.progress.domain.dto.progresscategory.*; -import org.dromara.progress.domain.enums.PgsRelevancyStructureEnum; import org.dromara.progress.domain.vo.progresscategory.*; import org.dromara.progress.service.IPgsProgressCategoryService; -import org.dromara.project.domain.BusProject; -import org.dromara.project.service.IBusProjectService; -import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; /** * 进度类别 @@ -58,9 +35,6 @@ public class PgsProgressCategoryController extends BaseController { @Resource private IPgsProgressCategoryService pgsProgressCategoryService; - @Resource - private IBusProjectService projectService; - /** * 查询进度类别列表 */ @@ -116,101 +90,31 @@ public class PgsProgressCategoryController extends BaseController { */ @SaCheckPermission("progress:progressCategory:export") @Log(title = "进度类别", businessType = BusinessType.EXPORT) - @Transactional @PostMapping("/export") public void export(@RequestBody PgsProgressCategoryQueryReq req, HttpServletResponse response) { - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - //要导出的整个sheet所需要的names - List names = new ArrayList<>(); - //要导出的list - List> listValues = new ArrayList<>(); - Long parentId = req.getParentId(); - String relevancyStructure = req.getRelevancyStructure(); - if (relevancyStructure.equals("2")) { - // 父类id不为空,导出父类对应的子类 - PgsProgressCategory category = pgsProgressCategoryService.getById(parentId); - if (category == null) { - throw new ServiceException("父进度类别不存在", HttpStatus.NOT_FOUND); - } - names.add(category.getName()); - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.apply("FIND_IN_SET({0}, ancestors)", parentId); - List voList = pgsProgressCategoryService.getVoList(pgsProgressCategoryService.list(queryWrapper)); - listValues.add(voList); - } else { - BusProject project = projectService.getById(req.getProjectId()); - if (project == null) { - throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); - } - List projects; - if (project.getPId().equals(0L)) { - projects = projectService.lambdaQuery() - .eq(BusProject::getPId, req.getProjectId()) - .list(); - projects.add(project); - List ids = projects.stream().map(BusProject::getId).toList(); - lqw.in(CollUtil.isNotEmpty(ids), PgsProgressCategory::getProjectId, ids); - } else { - projects = List.of(project); - lqw.eq(req.getProjectId() != null, PgsProgressCategory::getProjectId, req.getProjectId()); - } - lqw.eq(req.getMatrixId() != null, PgsProgressCategory::getMatrixId, req.getMatrixId()); - // 查询数据 - lqw.eq(PgsProgressCategory::getParentId, 0L); - List list = pgsProgressCategoryService.list(lqw); + pgsProgressCategoryService.export(req, response); + } - Map projectNameMap = projects.stream() - .collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName)); - // 获取非方阵类别name 非方阵类别有多级 暂定只有2级 也有可能没有父子关系 - List unMatrixList = list.stream().filter(category -> - !category.getRelevancyStructure().equals(PgsRelevancyStructureEnum.MATRIX.getValue())).toList(); - if (!unMatrixList.isEmpty()) { - for (PgsProgressCategory unMatrix : unMatrixList) { - //所有非方阵顶类名 - names.add(unMatrix.getName() + "-" + projectNameMap.get(unMatrix.getProjectId())); - //寻找子类 - lqw = new LambdaQueryWrapper<>(); - lqw.eq(PgsProgressCategory::getParentId, unMatrix.getId()); - List children = pgsProgressCategoryService.getVoList(pgsProgressCategoryService.list(lqw)); - if (!children.isEmpty()) { - //寻找孙类 然后添加 - List grandson = new ArrayList<>(); - for (PgsProgressCategoryVo childrenCategory : children) { - lqw = new LambdaQueryWrapper<>(); - lqw.eq(PgsProgressCategory::getParentId, childrenCategory.getId()); - List grandsonCategory = pgsProgressCategoryService.getVoList(pgsProgressCategoryService.list(lqw)); - if (!grandsonCategory.isEmpty()) { - grandson.addAll(grandsonCategory); - } else { - grandson = children; - } - } - listValues.add(grandson); - } - } - } - - //获取矩阵类别name - List matrixList = list.stream().filter(category -> - category.getRelevancyStructure().equals(PgsRelevancyStructureEnum.MATRIX.getValue())).toList(); - if (!matrixList.isEmpty()) { - for (PgsProgressCategory pgsProgressCategory : matrixList) { - //增加矩阵名 - names.add(pgsProgressCategory.getName() + "-" + pgsProgressCategory.getMatrixName()); - //找到该矩阵下的列表 - lqw = new LambdaQueryWrapper<>(); - lqw.eq(PgsProgressCategory::getMatrixId, pgsProgressCategory.getMatrixId()); - listValues.add(pgsProgressCategoryService.getVoList(pgsProgressCategoryService.list(lqw))); - } - } - } - - try { - ExcelUtil.exportMultiSheetExcelEnhanced(listValues, names, PgsProgressCategoryVo.class, null, response); - } catch (IOException e) { - throw new ServiceException("导出失败"); - } + /** + * 根据名称导出进度类别统计 + */ + @SaCheckPermission("progress:progressCategory:export") + @Log(title = "进度类别", businessType = BusinessType.EXPORT) + @PostMapping("/export/total/{projectId}") + public void exportTotalByName(@NotNull(message = "项目主键不能为空") + @PathVariable Long projectId, HttpServletResponse response) { + pgsProgressCategoryService.exportTotalByName(projectId, response); + } + /** + * 根据父级导出进度类别统计 + */ + @SaCheckPermission("progress:progressCategory:export") + @Log(title = "进度类别", businessType = BusinessType.EXPORT) + @PostMapping("/export/total/parent/{parentId}") + public void exportTotalByNameParent(@NotNull(message = "父级主键不能为空") + @PathVariable Long parentId, HttpServletResponse response) { + pgsProgressCategoryService.exportTotalByNameParent(parentId, response); } /*** @@ -220,111 +124,7 @@ public class PgsProgressCategoryController extends BaseController { @Log(title = "进度类别导入", businessType = BusinessType.IMPORT) @PostMapping("/import") public R importData(@RequestParam("file") MultipartFile file) { - - // 检查文件是否为空 - if (file == null || file.isEmpty()) { - return R.fail("上传文件不能为空"); - } - // 检查文件大小 - if (file.getSize() == 0) { - return R.fail("上传文件不能为空文件"); - } - // 检查文件名 - if (file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) { - return R.fail("文件名不能为空"); - } - - try { - // 使用EasyExcel读取所有sheet - List allData = new ArrayList<>(); - - // 创建Excel读取监听器 - DefaultExcelListener listener = new DefaultExcelListener<>(false); - - // 读取Excel文件 - ExcelReader excelReader = EasyExcel.read(file.getInputStream(), PgsProgressCategoryVo.class, listener).build(); - - // 获取所有sheet - List sheetList = excelReader.excelExecutor().sheetList(); - - // 遍历所有sheet - for (ReadSheet readSheet : sheetList) { - // 为每个sheet创建新的监听器实例 - DefaultExcelListener sheetListener = new DefaultExcelListener<>(false); - - // 读取当前sheet数据 - EasyExcel.read(file.getInputStream(), PgsProgressCategoryVo.class, sheetListener) - .sheet(readSheet.getSheetNo()) - .doRead(); - List list = sheetListener.getExcelResult().getList(); - List newList = list.stream().filter(vo -> vo.getId() == null).toList(); - List oldList = list.stream().filter(vo -> vo.getId() != null).toList(); - Set ids = oldList.stream().map(PgsProgressCategoryVo::getId).collect(Collectors.toSet()); - List categoryList = pgsProgressCategoryService.listByIds(ids); - // 筛选出关联设计图的数据 - List oldListVo = oldList.stream().filter(vo -> { - PgsProgressCategory category = categoryList.stream().filter(c -> c.getId().equals(vo.getId())).findFirst().orElse(null); - if (category == null) { - return true; - } - String workType = category.getWorkType(); - return StringUtils.isBlank(workType); - }).toList(); - // 将当前sheet的数据添加到总数据中 - allData.addAll(oldListVo); - if (CollUtil.isNotEmpty(newList) && CollUtil.isNotEmpty(oldList)) { - PgsProgressCategoryVo first = oldList.getFirst(); - PgsProgressCategory category = pgsProgressCategoryService.getById(first.getId()); - newList.forEach(vo -> { - vo.setParentId(category.getParentId()); - vo.setProjectId(category.getProjectId()); - vo.setMatrixId(category.getMatrixId()); - vo.setAncestors(category.getAncestors()); - vo.setRelevancyStructure(category.getRelevancyStructure()); - }); - allData.addAll(newList); - } - } - - // 关闭读取器 - excelReader.finish(); - if (allData.isEmpty()) { - return R.fail("未读取到有效数据"); - } - // 处理导入的数据 - List list = new ArrayList<>(); - for (PgsProgressCategoryVo vo : allData) { - list.add(pgsProgressCategoryService.convertVoToEntity(vo)); - } - // 计算产值 - list.forEach(pgsProgressCategory -> { - BigDecimal ownerPrice = pgsProgressCategory.getOwnerPrice(); - BigDecimal constructionPrice = pgsProgressCategory.getConstructionPrice(); - BigDecimal total = pgsProgressCategory.getTotal(); - if (total != null && total.compareTo(BigDecimal.ZERO) != 0) { - if (ownerPrice != null && ownerPrice.compareTo(BigDecimal.ZERO) != 0) { - pgsProgressCategory.setOwnerOutputValue(ownerPrice.multiply(total).setScale(4, RoundingMode.HALF_UP)); - } - if (constructionPrice != null && constructionPrice.compareTo(BigDecimal.ZERO) != 0) { - pgsProgressCategory.setConstructionOutputValue(constructionPrice.multiply(total).setScale(4, RoundingMode.HALF_UP)); - } - } - // 关联数据不更新数量 - if (pgsProgressCategory.getRemark() != null && pgsProgressCategory.getRemark().equals("关联数据")) { - pgsProgressCategory.setTotal(null); - } - }); - - boolean b = pgsProgressCategoryService.saveOrUpdateBatch(list); - if (!b) { - return R.fail("更新失败"); - } - - return R.ok("导入成功,共更新 " + list.size() + " 条数据"); - } catch (Exception e) { - log.error("导入Excel文件失败", e); - return R.fail("导入失败: " + e.getMessage()); - } + return R.ok(pgsProgressCategoryService.importData(file)); } /** diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/progressplandetail/PgsProgressPlanDetailAINumberReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/progressplandetail/PgsProgressPlanDetailAINumberReq.java index 1d432bd4..749972e2 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/progressplandetail/PgsProgressPlanDetailAINumberReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/progressplandetail/PgsProgressPlanDetailAINumberReq.java @@ -23,12 +23,22 @@ public class PgsProgressPlanDetailAINumberReq implements Serializable { @NotBlank(message = "大图不能为空") private String file; + /** + * 大图url + */ + private String fileUrl; + /** * tif文件 */ @NotBlank(message = "tif文件不能为空") private String tif; + /** + * tif文件url + */ + private String tifUrl; + /** * 项目id */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/enums/PgsProgressCategoryTypeEnum.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/enums/PgsProgressCategoryTypeEnum.java new file mode 100644 index 00000000..83675762 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/enums/PgsProgressCategoryTypeEnum.java @@ -0,0 +1,38 @@ +package org.dromara.progress.domain.enums; + +import lombok.Getter; + +/** + * @author lilemy + * @date 2025-11-12 15:47 + */ +@Getter +public enum PgsProgressCategoryTypeEnum { + + BOOSTER_STATION("升压站"), + COLLECTING_LINE("集电线路"), + SEND_LINE("送出线路"), + PHOTOVOLTAIC_AREA("光伏场区"), + OTHER_PROJECT("其他工程"); + + private final String text; + + PgsProgressCategoryTypeEnum(String text) { + this.text = text; + } + + /** + * 根据text获取枚举 + * + * @param text 文本 + * @return 枚举 + */ + public static PgsProgressCategoryTypeEnum fromText(String text) { + for (PgsProgressCategoryTypeEnum e : values()) { + if (e.getText().equals(text)) { + return e; + } + } + return null; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryByDayVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryByDayVo.java new file mode 100644 index 00000000..2b1bd8ad --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryByDayVo.java @@ -0,0 +1,57 @@ +package org.dromara.progress.domain.vo.progresscategory; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author lilemy + * @date 2025-11-12 15:39 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PgsProgressCategoryByDayVo { + + /** + * 子项目id + */ + private Long projectId; + + /** + * 子项目名称 + */ + private String projectName; + + /** + * 升压站 + */ + private List boosterStation; + + /** + * 集电线路 + */ + private List collectingLine; + + /** + * 送出线路 + */ + private List sendLine; + + /** + * 光伏场区 + */ + private List photovoltaicArea; + + /** + * 其他工程 + */ + private List otherProject; + + /** + * 总数 + */ + private Integer size; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDayTotalVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDayTotalVo.java new file mode 100644 index 00000000..0b350219 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDayTotalVo.java @@ -0,0 +1,27 @@ +package org.dromara.progress.domain.vo.progresscategory; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author lilemy + * @date 2025-11-13 19:22 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PgsProgressCategoryDayTotalVo { + + /** + * 项目 + */ + private PgsProgressCategoryByDayVo project; + + /** + * 子项目 + */ + private List subProjectList; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDetailByDayVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDetailByDayVo.java new file mode 100644 index 00000000..b89bdda8 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryDetailByDayVo.java @@ -0,0 +1,57 @@ +package org.dromara.progress.domain.vo.progresscategory; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @author lilemy + * @date 2025-11-12 18:59 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PgsProgressCategoryDetailByDayVo { + + /** + * 主键 + */ + private Long id; + + /** + * 进度类别名称 + */ + private String name; + + /** + * 总数量 + */ + private BigDecimal total; + + /** + * 已完成数量 + */ + private BigDecimal completed; + + /** + * 已完成数量百分比 + */ + private BigDecimal completedPercentage; + + /** + * 计量单位 + */ + private String unit; + + /** + * 施工计划 + */ + private BigDecimal constructionPlan; + + /** + * 施工完成 + */ + private BigDecimal constructionCompleted; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryExportTotalVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryExportTotalVo.java new file mode 100644 index 00000000..ef55e338 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryExportTotalVo.java @@ -0,0 +1,66 @@ +package org.dromara.progress.domain.vo.progresscategory; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @author lilemy + * @date 2025-11-13 10:47 + */ +@Data +@ExcelIgnoreUnannotated +public class PgsProgressCategoryExportTotalVo implements Serializable { + + @Serial + private static final long serialVersionUID = -5830653037297127006L; + + /** + * 主键 + */ + private Long id; + + /** + * 类别名称 + */ + @ExcelProperty(value = "类别名称") + private String name; + + /** + * 计量方式(0无 1数量 2百分比) + */ + @ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比") + private String unitType; + + /** + * 计量单位 + */ + @ExcelProperty(value = "计量单位") + private String unit; + + /** + * 总数量 + */ + @ExcelProperty(value = "总数量") + private BigDecimal total; + + /** + * 计划总数量 + */ + @ExcelProperty(value = "计划总数量") + private BigDecimal planTotal; + + /** + * 已完成数量 + */ + @ExcelProperty(value = "已完成总数量") + private BigDecimal completed; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java index 1b8ed0f3..3796766f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java @@ -2,13 +2,16 @@ package org.dromara.progress.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; +import jakarta.servlet.http.HttpServletResponse; import org.dromara.facility.domain.FacMatrix; import org.dromara.progress.domain.PgsProgressCategory; import org.dromara.progress.domain.PgsProgressPlan; import org.dromara.progress.domain.dto.progresscategory.*; import org.dromara.progress.domain.vo.progresscategory.*; +import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.Collection; import java.util.List; import java.util.Map; @@ -147,11 +150,15 @@ public interface IPgsProgressCategoryService extends IService queryListByProjectIds(List projectIds); /*** * 获取方阵id及对应数量 + * + * @param projectId 项目id */ List> getMatrixIdAndNumber(Long projectId); @@ -180,6 +187,15 @@ public interface IPgsProgressCategoryService extends IService getLeafNodesByTopId(Long topId, List allCategory); + /** + * 获取最底层的叶子节点(支持多个顶级id) + * + * @param topIdList 顶级节点id集合 + * @param allCategory 所有节点 + * @return 最底层的叶子节点 + */ + List getLeafNodesByTopIds(List topIdList, List allCategory); + /** * 获取最底层的叶子节点(支持多个顶级id) * @@ -268,4 +284,44 @@ public interface IPgsProgressCategoryService extends IService allChildren = this.list( Wrappers.lambdaQuery() - .and(wrapper -> { + .and(wrapper -> wrapper.like(PgsProgressCategory::getAncestors, "," + topId + ",") .or() - .like(PgsProgressCategory::getAncestors, "," + topId); - }) + .like(PgsProgressCategory::getAncestors, "," + topId)) ); if (allChildren.isEmpty()) { @@ -1446,6 +1450,53 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl getLeafNodesByTopIds(List topIdList, List allCategory) { + if (allCategory == null || allCategory.isEmpty() || topIdList == null || topIdList.isEmpty()) { + return Collections.emptyList(); + } + + // 1. 找出所有属于任意一个顶级节点的子孙节点(Ancestors 字段包含其中任意一个 topId) + List allChildren = allCategory.stream() + .filter(item -> { + String ancestors = item.getAncestors(); + if (ancestors == null) { + return false; + } + // 任意一个 topId 匹配成功即保留 + return topIdList.stream().anyMatch(topId -> + ancestors.contains("," + topId + ",") || + ancestors.endsWith("," + topId) || + ancestors.startsWith(topId + ",") || + ancestors.equals(String.valueOf(topId)) + ); + }) + .toList(); + + if (allChildren.isEmpty()) { + return Collections.emptyList(); + } + + // 2. 找出所有有孩子的节点 ID(即 parentId 出现的节点) + Set parentIds = allChildren.stream() + .map(PgsProgressCategory::getParentId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 3. 过滤出没有作为别人 parentId 出现的节点 → 叶子节点 + return allChildren.stream() + .filter(item -> !parentIds.contains(item.getId())) + .toList(); + } + + /** * 获取最底层的叶子节点(支持多个顶级id) * @@ -2212,6 +2263,379 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl projects = projectService.lambdaQuery() + .eq(BusProject::getPId, projectId) + .list(); + projects.add(project); + List allProjectIds = projects.stream().map(BusProject::getId).toList(); + // 获取当前项目的所有进度类别 + List allList = this.lambdaQuery() + .in(PgsProgressCategory::getProjectId, allProjectIds) + .list(); + // 获取最顶层的进度类别 + List topList = allList.stream() + .filter(category -> category.getParentId().equals(PgsProgressCategoryConstant.TOP_PARENT_ID)) + .toList(); + // 获取指定日期的计划详情 + List detailList = progressPlanDetailService.lambdaQuery() + .in(PgsProgressPlanDetail::getProjectId, allProjectIds) + .eq(PgsProgressPlanDetail::getDate, date) + .list(); + // 根据项目id进行分类 + Map projectMap = projects.stream() + .collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName)); + // 根据项目进行分类 + Map> topMap = topList.stream() + .collect(Collectors.groupingBy(PgsProgressCategory::getProjectId)); + PgsProgressCategoryDayTotalVo totalVo = new PgsProgressCategoryDayTotalVo(); + List voList = new ArrayList<>(); + for (Map.Entry> entry : topMap.entrySet()) { + // 获取当前父类下的最底层子类 + List value = entry.getValue(); + // 根据名称进行分类 + Map> topNameMap = value.stream() + .collect(Collectors.groupingBy(PgsProgressCategory::getName)); + PgsProgressCategoryByDayVo vo = new PgsProgressCategoryByDayVo(); + for (Map.Entry> nameEntry : topNameMap.entrySet()) { + vo.setProjectId(entry.getKey()); + vo.setProjectName(projectMap.get(entry.getKey())); + String nameKey = nameEntry.getKey(); + List nameValue = nameEntry.getValue(); + List topIds = nameValue.stream().map(PgsProgressCategory::getId).toList(); + List children = this.getLeafNodesByTopIds(topIds, allList); + if (CollUtil.isEmpty(children)) { + continue; + } + // 提取所有 children 的 id + Set childIds = children.stream() + .map(PgsProgressCategory::getId) + .collect(Collectors.toSet()); + List planDetailList = detailList.stream() + .filter(detail -> childIds.contains(detail.getProgressCategoryId())) + .toList(); + // 将子类根据名称进行分类 + List detail = this.getChildrenDetailByName(children, planDetailList); + vo.setSize(detail.size()); + switch (PgsProgressCategoryTypeEnum.fromText(nameKey)) { + case BOOSTER_STATION: + vo.setBoosterStation(detail); + break; + case COLLECTING_LINE: + vo.setCollectingLine(detail); + break; + case SEND_LINE: + vo.setSendLine(detail); + break; + case PHOTOVOLTAIC_AREA: + vo.setPhotovoltaicArea(detail); + break; + case OTHER_PROJECT: + vo.setOtherProject(detail); + break; + case null, default: + break; + } + } + if (entry.getKey().equals(projectId)) { + totalVo.setProject(vo); + } else { + voList.add(vo); + } + } + totalVo.setSubProjectList(voList); + return totalVo; + } + + /** + * 导出项目进度类别列表 + * + * @param req 查询条件 + * @param response 响应 + */ + @Override + public void export(PgsProgressCategoryQueryReq req, HttpServletResponse response) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + //要导出的整个sheet所需要的names + List names = new ArrayList<>(); + //要导出的list + List> listValues = new ArrayList<>(); + Long parentId = req.getParentId(); + String relevancyStructure = req.getRelevancyStructure(); + if (relevancyStructure.equals("2")) { + // 父类id不为空,导出父类对应的子类 + PgsProgressCategory category = this.getById(parentId); + if (category == null) { + throw new ServiceException("父进度类别不存在", HttpStatus.NOT_FOUND); + } + names.add(category.getName()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("FIND_IN_SET({0}, ancestors)", parentId); + List voList = this.getVoList(this.list(queryWrapper)); + listValues.add(voList); + } else { + BusProject project = projectService.getById(req.getProjectId()); + if (project == null) { + throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); + } + List projects; + if (project.getPId().equals(0L)) { + projects = projectService.lambdaQuery() + .eq(BusProject::getPId, req.getProjectId()) + .list(); + projects.add(project); + List ids = projects.stream().map(BusProject::getId).toList(); + lqw.in(CollUtil.isNotEmpty(ids), PgsProgressCategory::getProjectId, ids); + } else { + projects = List.of(project); + lqw.eq(req.getProjectId() != null, PgsProgressCategory::getProjectId, req.getProjectId()); + } + lqw.eq(req.getMatrixId() != null, PgsProgressCategory::getMatrixId, req.getMatrixId()); + // 查询数据 + lqw.eq(PgsProgressCategory::getParentId, 0L); + List list = this.list(lqw); + Map projectNameMap = projects.stream() + .collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName)); + // 获取非方阵类别name 非方阵类别有多级 暂定只有2级 也有可能没有父子关系 + List unMatrixList = list.stream().filter(category -> + !category.getRelevancyStructure().equals(PgsRelevancyStructureEnum.MATRIX.getValue())).toList(); + if (!unMatrixList.isEmpty()) { + for (PgsProgressCategory unMatrix : unMatrixList) { + //所有非方阵顶类名 + names.add(unMatrix.getName() + "-" + projectNameMap.get(unMatrix.getProjectId())); + //寻找子类 + lqw = new LambdaQueryWrapper<>(); + lqw.eq(PgsProgressCategory::getParentId, unMatrix.getId()); + List children = this.getVoList(this.list(lqw)); + if (!children.isEmpty()) { + //寻找孙类 然后添加 + List grandson = new ArrayList<>(); + for (PgsProgressCategoryVo childrenCategory : children) { + lqw = new LambdaQueryWrapper<>(); + lqw.eq(PgsProgressCategory::getParentId, childrenCategory.getId()); + List grandsonCategory = this.getVoList(this.list(lqw)); + if (!grandsonCategory.isEmpty()) { + grandson.addAll(grandsonCategory); + } else { + grandson = children; + } + } + listValues.add(grandson); + } + } + } + //获取矩阵类别name + List matrixList = list.stream().filter(category -> + category.getRelevancyStructure().equals(PgsRelevancyStructureEnum.MATRIX.getValue())).toList(); + if (!matrixList.isEmpty()) { + for (PgsProgressCategory pgsProgressCategory : matrixList) { + //增加矩阵名 + names.add(pgsProgressCategory.getName() + "-" + pgsProgressCategory.getMatrixName()); + //找到该矩阵下的列表 + lqw = new LambdaQueryWrapper<>(); + lqw.eq(PgsProgressCategory::getMatrixId, pgsProgressCategory.getMatrixId()); + listValues.add(this.getVoList(this.list(lqw))); + } + } + } + try { + ExcelUtil.exportMultiSheetExcelEnhanced(listValues, names, PgsProgressCategoryVo.class, null, response); + } catch (IOException e) { + throw new ServiceException("导出失败"); + } + } + + /** + * 导出项目进度类别列表,根据名称分类 + * + * @param projectId 项目id + * @param response 响应 + */ + @Override + public void exportTotalByName(Long projectId, HttpServletResponse response) { + BusProject project = projectService.getById(projectId); + if (project == null) { + throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); + } + // 获取当前项目的子项目 + List projects = projectService.lambdaQuery() + .eq(BusProject::getPId, projectId) + .list(); + List allProjectIds = new ArrayList<>(projects.stream().map(BusProject::getId).toList()); + allProjectIds.add(projectId); + // 获取当前项目的所有进度类别 + List allList = this.lambdaQuery() + .in(PgsProgressCategory::getProjectId, allProjectIds) + .list(); + // 获取最顶层的进度类别 + List topList = allList.stream() + .filter(category -> category.getParentId().equals(PgsProgressCategoryConstant.TOP_PARENT_ID)) + .toList(); + // 根据名字进行分类 + List names = new ArrayList<>(); + List> listValues = new ArrayList<>(); + Map> topMap = topList.stream() + .collect(Collectors.groupingBy(PgsProgressCategory::getName)); + for (Map.Entry> entry : topMap.entrySet()) { + names.add(entry.getKey()); + // 获取当前父类下的最底层子类 + List value = entry.getValue(); + List topIds = value.stream().map(PgsProgressCategory::getId).toList(); + List children = this.getLeafNodesByTopIds(topIds, allList); + if (CollUtil.isEmpty(children)) { + continue; + } + // 将子类根据名称进行分类 + List result = getChildrenTotalByName(children); + listValues.add(result); + } + try { + ExcelUtil.exportMultiSheetExcelEnhanced(listValues, names, PgsProgressCategoryExportTotalVo.class, null, response); + } catch (IOException e) { + throw new ServiceException("导出失败"); + } + } + + /** + * 导出项目进度类别列表,根据名称分类 + * + * @param parentId 父级id + * @param response 响应 + */ + @Override + public void exportTotalByNameParent(Long parentId, HttpServletResponse response) { + PgsProgressCategory parent = this.getById(parentId); + if (parent == null) { + throw new ServiceException("父级不存在", HttpStatus.NOT_FOUND); + } + // 获取当前父级的所有进度类别 + List children = this.getLeafNodesByTopId(parentId); + if (CollUtil.isEmpty(children)) { + throw new ServiceException("没有数据"); + } + // 根据名称进行分类,并统计数据 + List total = this.getChildrenTotalByName(children); + ExcelUtil.exportExcel(total, parent.getName(), PgsProgressCategoryExportTotalVo.class, response); + } + + /** + * 导入项目进度类别列表 + * + * @param file 文件 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public String importData(MultipartFile file) { + // 检查文件是否为空 + if (file == null || file.isEmpty()) { + throw new ServiceException("上传文件不能为空"); + } + // 检查文件大小 + if (file.getSize() == 0) { + throw new ServiceException("上传文件不能为空文件"); + } + // 检查文件名 + if (file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) { + throw new ServiceException("文件名不能为空"); + } + try { + // 使用EasyExcel读取所有sheet + List allData = new ArrayList<>(); + // 创建Excel读取监听器 + DefaultExcelListener listener = new DefaultExcelListener<>(false); + // 读取Excel文件 + ExcelReader excelReader = EasyExcel.read(file.getInputStream(), PgsProgressCategoryVo.class, listener).build(); + // 获取所有sheet + List sheetList = excelReader.excelExecutor().sheetList(); + // 遍历所有sheet + for (ReadSheet readSheet : sheetList) { + // 为每个sheet创建新的监听器实例 + DefaultExcelListener sheetListener = new DefaultExcelListener<>(false); + // 读取当前sheet数据 + EasyExcel.read(file.getInputStream(), PgsProgressCategoryVo.class, sheetListener) + .sheet(readSheet.getSheetNo()) + .doRead(); + List list = sheetListener.getExcelResult().getList(); + List newList = list.stream().filter(vo -> vo.getId() == null).toList(); + List oldList = list.stream().filter(vo -> vo.getId() != null).toList(); + Set ids = oldList.stream().map(PgsProgressCategoryVo::getId).collect(Collectors.toSet()); + List categoryList = this.listByIds(ids); + // 筛选出关联设计图的数据 + List oldListVo = oldList.stream().filter(vo -> { + PgsProgressCategory category = categoryList.stream().filter(c -> c.getId().equals(vo.getId())).findFirst().orElse(null); + if (category == null) { + return true; + } + String workType = category.getWorkType(); + return StringUtils.isBlank(workType); + }).toList(); + // 将当前sheet的数据添加到总数据中 + allData.addAll(oldListVo); + if (CollUtil.isNotEmpty(newList) && CollUtil.isNotEmpty(oldList)) { + PgsProgressCategoryVo first = oldList.getFirst(); + PgsProgressCategory category = this.getById(first.getId()); + newList.forEach(vo -> { + vo.setParentId(category.getParentId()); + vo.setProjectId(category.getProjectId()); + vo.setMatrixId(category.getMatrixId()); + vo.setAncestors(category.getAncestors()); + vo.setRelevancyStructure(category.getRelevancyStructure()); + }); + allData.addAll(newList); + } + } + // 关闭读取器 + excelReader.finish(); + if (allData.isEmpty()) { + throw new ServiceException("未读取到有效数据"); + } + // 处理导入的数据 + List list = new ArrayList<>(); + for (PgsProgressCategoryVo vo : allData) { + list.add(this.convertVoToEntity(vo)); + } + // 计算产值 + list.forEach(pgsProgressCategory -> { + BigDecimal ownerPrice = pgsProgressCategory.getOwnerPrice(); + BigDecimal constructionPrice = pgsProgressCategory.getConstructionPrice(); + BigDecimal total = pgsProgressCategory.getTotal(); + if (total != null && total.compareTo(BigDecimal.ZERO) != 0) { + if (ownerPrice != null && ownerPrice.compareTo(BigDecimal.ZERO) != 0) { + pgsProgressCategory.setOwnerOutputValue(ownerPrice.multiply(total).setScale(4, RoundingMode.HALF_UP)); + } + if (constructionPrice != null && constructionPrice.compareTo(BigDecimal.ZERO) != 0) { + pgsProgressCategory.setConstructionOutputValue(constructionPrice.multiply(total).setScale(4, RoundingMode.HALF_UP)); + } + } + // 关联数据不更新数量 + if (pgsProgressCategory.getRemark() != null && pgsProgressCategory.getRemark().equals("关联数据")) { + pgsProgressCategory.setTotal(null); + } + }); + boolean b = this.saveOrUpdateBatch(list); + if (!b) { + throw new ServiceException("更新失败"); + } + return "导入成功,共更新 " + list.size() + " 条数据"; + } catch (Exception e) { + log.error("导入Excel文件失败", e); + throw new ServiceException("导入Excel文件失败" + e.getMessage()); + } + } + /** * 计算进度类别(含子类别)的开始和结束时间。 *

@@ -2231,51 +2655,42 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl allChildren, List allPlanList) { PgsProgressCategoryGanttVo ganttVo = new PgsProgressCategoryGanttVo(); - // 获取该类别下的所有叶子节点(无子节点的类别) List children = this.getLeafNodesByTopId(progressCategoryId, allChildren); - if (CollUtil.isEmpty(children)) { // --- 叶子节点:直接根据计划计算 --- List planList = allPlanList.stream() .filter(p -> p.getProgressCategoryId().equals(progressCategoryId)) .toList(); - if (CollUtil.isNotEmpty(planList)) { LocalDate startDate = planList.stream() .map(PgsProgressPlan::getStartDate) .filter(Objects::nonNull) .min(LocalDate::compareTo) .orElse(null); - LocalDate endDate = planList.stream() .map(PgsProgressPlan::getEndDate) .filter(Objects::nonNull) .max(LocalDate::compareTo) .orElse(null); - ganttVo.setStartDate(startDate); ganttVo.setEndDate(endDate); } - } else { // --- 非叶子节点:递归计算子节点 --- List childVoList = children.stream() .map(child -> getCategoryStartDateAndEndDate(child.getId(), allChildren, allPlanList)) .toList(); - LocalDate minStart = childVoList.stream() .map(PgsProgressCategoryGanttVo::getStartDate) .filter(Objects::nonNull) .min(LocalDate::compareTo) .orElse(null); - LocalDate maxEnd = childVoList.stream() .map(PgsProgressCategoryGanttVo::getEndDate) .filter(Objects::nonNull) .max(LocalDate::compareTo) .orElse(null); - ganttVo.setStartDate(minStart); ganttVo.setEndDate(maxEnd); } @@ -2370,4 +2785,133 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl getChildrenTotalByName(List children) { + // 将子类根据名称进行分类 + Map> childrenMap = children.stream() + .collect(Collectors.groupingBy(PgsProgressCategory::getName)); + return childrenMap.entrySet().stream() + .map(c -> { + String name = c.getKey(); + List list = c.getValue(); + // 汇总 + BigDecimal total = list.stream() + .map(PgsProgressCategory::getTotal) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal planTotal = list.stream() + .map(PgsProgressCategory::getPlanTotal) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal completed = list.stream() + .map(PgsProgressCategory::getCompleted) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + // 假设同名类别下的 unit / unitType 一致,取第一个即可 + String unit = list.stream() + .map(PgsProgressCategory::getUnit) + .filter(Objects::nonNull) + .findFirst().orElse(null); + String unitType = list.stream() + .map(PgsProgressCategory::getUnitType) + .filter(Objects::nonNull) + .findFirst().orElse(null); + // 封装结果 + PgsProgressCategoryExportTotalVo vo = new PgsProgressCategoryExportTotalVo(); + vo.setId(list.getFirst().getId()); + vo.setName(name); + vo.setUnit(unit); + vo.setUnitType(unitType); + vo.setTotal(total); + vo.setPlanTotal(planTotal); + vo.setCompleted(completed); + return vo; + }).sorted(Comparator.comparing(PgsProgressCategoryExportTotalVo::getId)).toList(); + } + + /** + * 根据子级名称分类并统计数据 + * + * @param children 子级 + * @param planList 计划 + * @return 分类后的数据 + */ + private List getChildrenDetailByName(List children, + List planList) { + // 将子类根据名称进行分类 + Map> childrenMap = children.stream() + .collect(Collectors.groupingBy(PgsProgressCategory::getName)); + Map> detailMap = new HashMap<>(); + if (CollUtil.isNotEmpty(planList)) { + detailMap = planList.stream() + .collect(Collectors.groupingBy(PgsProgressPlanDetail::getProgressCategoryId)); + } + Map> finalDetailMap = detailMap; + return childrenMap.entrySet().stream() + .map(c -> { + String name = c.getKey(); + List list = c.getValue(); + if (CollUtil.isEmpty(list)) { + return null; + } + // 汇总 + BigDecimal total = list.stream() + .map(PgsProgressCategory::getTotal) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal completed = list.stream() + .map(PgsProgressCategory::getCompleted) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + // 假设同名类别下的 unit / unitType 一致,取第一个即可 + String unit = list.stream() + .map(PgsProgressCategory::getUnit) + .filter(Objects::nonNull) + .findFirst().orElse(null); + // 获取施工计划数量 + BigDecimal constructionPlan = BigDecimal.ZERO; + if (CollUtil.isNotEmpty(finalDetailMap)) { + constructionPlan = list.stream() + .map(PgsProgressCategory::getId) + .filter(Objects::nonNull) + .map(finalDetailMap::get) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .map(PgsProgressPlanDetail::getPlanNumber) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + // 获取施工完成数量 + BigDecimal constructionCompleted = BigDecimal.ZERO; + if (CollUtil.isNotEmpty(finalDetailMap)) { + constructionPlan = list.stream() + .map(PgsProgressCategory::getId) + .filter(Objects::nonNull) + .map(finalDetailMap::get) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .map(PgsProgressPlanDetail::getFinishedNumber) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + // 封装结果 + PgsProgressCategoryDetailByDayVo vo = new PgsProgressCategoryDetailByDayVo(); + vo.setConstructionPlan(constructionPlan); + vo.setConstructionCompleted(constructionCompleted); + vo.setId(list.getFirst().getId()); + vo.setName(name); + vo.setUnit(unit); + vo.setTotal(total); + vo.setCompleted(completed); + vo.setCompletedPercentage(BigDecimalUtil.toPercentage(completed, total)); + return vo; + }).filter(Objects::nonNull) + .sorted(Comparator.comparing(PgsProgressCategoryDetailByDayVo::getId)).toList(); + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java index 3eee704e..b5b70347 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java @@ -16,12 +16,10 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.enums.AppUserTypeEnum; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.utils.AsyncUtil; import org.dromara.common.utils.IdCardEncryptorUtil; import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.contractor.service.ISubConstructionUserService; -import org.dromara.dataTransmission.clarityPm.method.ClarityPmAsyncMethod; import org.dromara.project.domain.BusConstructionUserExit; import org.dromara.project.domain.BusProjectTeam; import org.dromara.project.domain.BusProjectTeamMember; @@ -185,14 +183,14 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class) .eq(SubConstructionUser::getId, constructionUser.getId()) .set(SubConstructionUser::getProjectId, req.getProjectId()) - .set(req.getContractorId()!=null,SubConstructionUser::getContractorId, req.getContractorId()) + .set(req.getContractorId() != null, SubConstructionUser::getContractorId, req.getContractorId()) .set(SubConstructionUser::getTeamId, projectTeamMember.getTeamId()) .set(SubConstructionUser::getTeamName, projectTeam.getTeamName()) .set(SubConstructionUser::getEntryDate, new Date()) .set(SubConstructionUser::getLeaveDate, null) .set(SubConstructionUser::getExitStatus, "0") .set(SubConstructionUser::getUserRole, "0") - .set(StrUtil.isNotBlank(req.getTypeOfWork()),SubConstructionUser::getTypeOfWork,req.getTypeOfWork()) + .set(StrUtil.isNotBlank(req.getTypeOfWork()), SubConstructionUser::getTypeOfWork, req.getTypeOfWork()) .set(constructionUser.getFirstDate() == null, SubConstructionUser::getFirstDate, LocalDate.now()); constructionUserService.update(constructionUserLuw); @@ -223,8 +221,8 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpllambdaQuery() .eq(SysUserRole::getUserId, constructionUser.getSysUserId()) @@ -333,8 +331,9 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class) .eq(SubConstructionUser::getId, constructionUser.getId()) - .set(SubConstructionUser::getExitStatus, "2") + .set(SubConstructionUser::getExitStatus, exitStatus) .set(SubConstructionUser::getTeamId, null) .set(SubConstructionUser::getLeaveDate, new Date()); constructionUserService.update(constructionUserLuw); @@ -394,9 +393,9 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpllambdaQuery() .eq(BusProjectTeamMember::getMemberId, userId) .eq(BusProjectTeamMember::getProjectId, projectId) .last("limit 1") ); - if(busProjectTeamMember == null){ + if (busProjectTeamMember == null) { return null; } return busProjectTeamMember.getPostId(); From 3f4b127cdfda3258fe0f560277c9a6bbbd313ea8 Mon Sep 17 00:00:00 2001 From: lg Date: Thu, 13 Nov 2025 19:55:52 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9C=BA=E6=A2=B0=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E6=8D=AE=E6=97=A5=E6=9C=9F=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/bo/XzdMachineryContractAlterationBo.java | 5 +++++ .../impl/XzdMachineryContractAlterationServiceImpl.java | 5 ++++- .../jixiehetongxinxi/domain/bo/XzdContractMachineryBo.java | 5 +++++ .../service/impl/XzdContractMachineryServiceImpl.java | 2 ++ .../domain/bo/XzdMachineryContractSuspendBo.java | 4 ++++ .../service/impl/XzdMachineryContractSuspendServiceImpl.java | 3 +++ 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/domain/bo/XzdMachineryContractAlterationBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/domain/bo/XzdMachineryContractAlterationBo.java index dd0afc59..a4ab027a 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/domain/bo/XzdMachineryContractAlterationBo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/domain/bo/XzdMachineryContractAlterationBo.java @@ -232,6 +232,11 @@ public class XzdMachineryContractAlterationBo extends BaseEntity { */ private String contractText; + + private LocalDate startTime; + + private LocalDate endTime; + /** * 组织id */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/service/impl/XzdMachineryContractAlterationServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/service/impl/XzdMachineryContractAlterationServiceImpl.java index 50a92c19..33a6879f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/service/impl/XzdMachineryContractAlterationServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongbiang/service/impl/XzdMachineryContractAlterationServiceImpl.java @@ -15,6 +15,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.dromara.common.utils.BatchNumberGenerator; import org.dromara.system.service.impl.SysOssServiceImpl; +import org.dromara.xzd.biddingManagement.biaoqianlixiang.domain.XzdProjectRiskAssessment; import org.dromara.xzd.contractManagement.caigouhetongbiangeng.domain.XzdPurchaseContractAlteration; import org.dromara.xzd.contractManagement.caigouhetongbiangeng.domain.vo.XzdPurchaseContractAlterationVo; import org.dromara.xzd.contractManagement.jixiehetongxinxi.domain.XzdEquipmentLeasing; @@ -219,6 +220,8 @@ public class XzdMachineryContractAlterationServiceImpl extends ServiceImpl 0; if (flag) { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/domain/bo/XzdContractMachineryBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/domain/bo/XzdContractMachineryBo.java index 65c661f1..659fd536 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/domain/bo/XzdContractMachineryBo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/domain/bo/XzdContractMachineryBo.java @@ -259,6 +259,11 @@ public class XzdContractMachineryBo extends BaseEntity { private Long deptId; + private LocalDate startTime; + + private LocalDate endTime; + + /** * 印章信息 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/service/impl/XzdContractMachineryServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/service/impl/XzdContractMachineryServiceImpl.java index fa51ee42..8f362b02 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/service/impl/XzdContractMachineryServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/jixiehetongxinxi/service/impl/XzdContractMachineryServiceImpl.java @@ -234,6 +234,8 @@ public class XzdContractMachineryServiceImpl extends ServiceImpl