From 5f64f3aef455922868fb7c59a58503f863633be5 Mon Sep 17 00:00:00 2001 From: zt Date: Mon, 17 Nov 2025 16:38:59 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=97=A5=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PgsReportExportController.java | 2026 +++++++++++++++++ .../domain/dto/export/ReportExportDto.java | 16 + .../domain/vo/export/EquipmentEntryData.java | 32 + .../domain/vo/export/MaterialEntryData.java | 31 + .../vo/export/MaterialInspectionData.java | 32 + .../progress/domain/vo/export/ParamData.java | 58 + .../domain/vo/export/ParticipantData.java | 30 + .../domain/vo/export/ProgressData.java | 34 + .../domain/vo/export/ProjectData.java | 23 + .../safety/domain/HseViolationRecord.java | 21 + 10 files changed, 2303 insertions(+) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsReportExportController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/export/ReportExportDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/EquipmentEntryData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialEntryData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialInspectionData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParamData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParticipantData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProgressData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProjectData.java diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsReportExportController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsReportExportController.java new file mode 100644 index 00000000..3a83276f --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/controller/PgsReportExportController.java @@ -0,0 +1,2026 @@ +package org.dromara.progress.controller; + +import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +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 org.apache.commons.io.IOUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.RegionUtil; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.dromara.common.core.enums.FormatsType; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.DateUtils; +import org.dromara.common.web.core.BaseController; +import org.dromara.manager.weathermanager.WeatherConstant; +import org.dromara.manager.weathermanager.WeatherManager; +import org.dromara.manager.weathermanager.vo.WeatherVo; +import org.dromara.progress.domain.dto.export.ReportExportDto; +import org.dromara.progress.domain.vo.export.*; +import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryByDayVo; +import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryDayTotalVo; +import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryDetailByDayVo; +import org.dromara.progress.service.IPgsProgressCategoryService; +import org.dromara.progress.service.IPgsProgressPlanService; +import org.dromara.project.domain.BusProject; +import org.dromara.project.service.IBusProjectService; +import org.dromara.quality.domain.QltQualityInspection; +import org.dromara.quality.service.IQltQualityInspectionService; +import org.dromara.safety.domain.HseSafetyInspection; +import org.dromara.safety.service.IHseSafetyInspectionService; +import org.dromara.system.domain.vo.SysOssVo; +import org.dromara.system.service.ISysOssService; +import org.springframework.scheduling.annotation.Async; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Validated +@RestController +@RequestMapping("/progress/export") +public class PgsReportExportController extends BaseController { + + + @Resource + private IPgsProgressCategoryService pgsProgressCategoryService; + @Resource + private IBusProjectService projectService; + @Resource + private IQltQualityInspectionService qltQualityInspectionService; + @Resource + private IHseSafetyInspectionService safetyInspectionService; + @Resource + private ISysOssService ossService; + + @Resource + private WeatherManager weatherManager; + + + public static final List IMAGE_SUFFIX = Arrays.asList(".png",".jpg",".jpeg"); + + @SaIgnore + @GetMapping("/dayReport") + public void getStreamData(ReportExportDto dto, HttpServletResponse response) { + try { + // 设置响应头,指定文件类型和下载文件名 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setHeader("Content-Disposition", "attachment; filename=project-report.xlsx"); + + // 获取数据并导出Excel + PgsProgressCategoryDayTotalVo progressCategoryByDay = pgsProgressCategoryService.getProgressCategoryByDay(dto.getProjectId(), DateUtils.parseLocalDateTime(FormatsType.YYYY_MM_DD, dto.getDate())); + + // 修改数据组装方式,返回 List> + List> projectDataList = getProjectDataListAsRows(progressCategoryByDay); + + ParamData paramData = getParamData(dto); + // 导出Excel到响应输出流 + exportProjectExcel(response.getOutputStream(), projectDataList, paramData); + + response.getOutputStream().flush(); + } catch (IOException e) { + throw new RuntimeException("导出Excel失败", e); + } + } + + + +// public static void main(String[] args) { +// // 导出路径 +// String exportPath = "C:\\Users\\YuanJie\\Desktop\\test.xlsx"; +// PgsProgressCategoryDayTotalVo progressCategoryDayTotalVo = getProgressCategoryDayTotalVo(); +// List projectDataList = getProjectDataList(progressCategoryDayTotalVo); +// +// try (FileOutputStream fos = new FileOutputStream(exportPath)) { +// exportProjectExcel(fos, projectDataList); +// System.out.println("Excel导出成功!文件路径:" + exportPath); +// } catch (IOException e) { +// System.err.println("导出失败:" + e.getMessage()); +// } +// } + + + + public static void exportProjectExcel(OutputStream outputStream, List> projectDataList, ParamData paramData) throws IOException { + try (Workbook workbook = new XSSFWorkbook()) { + Sheet sheet = workbook.createSheet("项目日志"); + + // 样式定义 + CellStyle wrapTitleStyle = createWrapTitleStyle(workbook); + CellStyle titleStyle = createTitleStyle(workbook); + CellStyle contentStyle = createContentStyle(workbook); + CellStyle headerStyle = createHeaderStyle(workbook); + CellStyle leftHeaderStyle = createLeftHeaderStyle(workbook); // 左对齐表头样式 + + // 行偏移量,用于跟踪当前写入的行位置 + int currentRowOffset = 0; + + // 遍历每一行数据 + for (int rowIndex = 0; rowIndex < projectDataList.size(); rowIndex++) { + List rowData = projectDataList.get(rowIndex); + + // 计算该行数据需要的最大行数 + int maxRowsInThisLine = 0; + + // 为该行中的每个项目生成数据(按列排列) + for (int projectIndex = 0; projectIndex < rowData.size(); projectIndex++) { + int columnOffset = projectIndex * 14; // 每个项目13列,间隔1列 + ProjectData projectData = rowData.get(projectIndex); + + // 导出单个项目数据 + int projectRows = exportSingleProject(sheet, workbook, projectData, currentRowOffset, columnOffset, + wrapTitleStyle, titleStyle, contentStyle, headerStyle, leftHeaderStyle, paramData); + + maxRowsInThisLine = Math.max(maxRowsInThisLine, projectRows); + } + + // 更新行偏移量,为下一行数据预留空间 + currentRowOffset += maxRowsInThisLine + 1; // 加1行间隔 + } + + // 设置列宽 + int maxColumns = 0; + for (List rowData : projectDataList) { + maxColumns = Math.max(maxColumns, rowData.size() * 14); + } + + int columnWidth = (int) (9.85 * 256); + for (int i = 0; i < maxColumns; i++) { + sheet.setColumnWidth(i, columnWidth); + } + + workbook.write(outputStream); + } + } + + // 为单个项目导出数据的方法 + // 为单个项目导出数据的方法 + private static int exportSingleProject(Sheet sheet, Workbook workbook, ProjectData projectData, + int rowOffset, // 改为行偏移 + int columnOffset, // 保留列偏移 + CellStyle wrapTitleStyle, CellStyle titleStyle, + CellStyle contentStyle, CellStyle headerStyle, + CellStyle leftHeaderStyle, ParamData paramData) { + List progressList = projectData.getProgressList(); + List participantList = projectData.getParticipantList(); + List equipmentEntryList = projectData.getEquipmentEntryList(); + List materialList = projectData.getMaterialList(); + List inspectionList = projectData.getInspectionList(); + String projectName = projectData.getProjectName(); + String projectDate = projectData.getProjectDate(); + + // ============================================== + // 1. 第一行:A1-M1合并(加上行偏移量和列偏移量) + // ============================================== + CellRangeAddress titleRegion = new CellRangeAddress(0 + rowOffset, 0 + rowOffset, 0 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, titleRegion, + projectName + "\n日期: " + paramData.getDate(), + wrapTitleStyle); + drawBorderForRegion(sheet, titleRegion, workbook); + Row titleRow = sheet.getRow(0 + rowOffset); + if (titleRow == null) { + titleRow = sheet.createRow(0 + rowOffset); + } + titleRow.setHeightInPoints(45); + + // ============================================== + // 2. 部门区域:A2-B3合并(加上行偏移量和列偏移量) + // ============================================== + CellRangeAddress deptRegion = new CellRangeAddress(1 + rowOffset, 2 + rowOffset, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, deptRegion, "部门", titleStyle); + drawBorderForRegion(sheet, deptRegion, workbook); + + // ============================================== + // 3. 部门名称:C2-F3合并 + // ============================================== + CellRangeAddress deptNameRegion = new CellRangeAddress(1 + rowOffset, 2 + rowOffset, 2 + columnOffset, 5 + columnOffset); + mergeAndFill(sheet, deptNameRegion, "田东公司项目建设管理部", contentStyle); + drawBorderForRegion(sheet, deptNameRegion, workbook); + + // ============================================== + // 4. 记录人:G2-I2合并 + // ============================================== + CellRangeAddress recorderRegion = new CellRangeAddress(1 + rowOffset, 1 + rowOffset, 6 + columnOffset, 8 + columnOffset); + mergeAndFill(sheet, recorderRegion, "记录人", titleStyle); + drawBorderForRegion(sheet, recorderRegion, workbook); + + // ============================================== + // 5. 记录人名称:J2-M2合并 + // ============================================== + CellRangeAddress recorderNameRegion = new CellRangeAddress(1 + rowOffset, 1 + rowOffset, 9 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, recorderNameRegion, paramData.getRecorder(), contentStyle); + drawBorderForRegion(sheet, recorderNameRegion, workbook); + + // ============================================== + // 6. 气温:G3-I3合并 + // ============================================== + CellRangeAddress tempRegion = new CellRangeAddress(2 + rowOffset, 2 + rowOffset, 6 + columnOffset, 8 + columnOffset); + mergeAndFill(sheet, tempRegion, "气温", titleStyle); + drawBorderForRegion(sheet, tempRegion, workbook); + + // ============================================== + // 7. 气温值:J3-M3合并 + // ============================================== + CellRangeAddress tempValueRegion = new CellRangeAddress(2 + rowOffset, 2 + rowOffset, 9 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, tempValueRegion, paramData.getTemp(), contentStyle); + drawBorderForRegion(sheet, tempValueRegion, workbook); + + // ============================================== + // 8. 天气:A4-B4合并 + // ============================================== + CellRangeAddress weatherRegion = new CellRangeAddress(3 + rowOffset, 3 + rowOffset, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, weatherRegion, "天气", titleStyle); + drawBorderForRegion(sheet, weatherRegion, workbook); + + // ============================================== + // 9. 白天:C4-D4合并 + // ============================================== + CellRangeAddress dayRegion = new CellRangeAddress(3 + rowOffset, 3 + rowOffset, 2 + columnOffset, 3 + columnOffset); + mergeAndFill(sheet, dayRegion, "白天", titleStyle); + drawBorderForRegion(sheet, dayRegion, workbook); + + // ============================================== + // 10. 白天天气:E4-F4合并 + // ============================================== + CellRangeAddress dayWeatherRegion = new CellRangeAddress(3 + rowOffset, 3 + rowOffset, 4 + columnOffset, 5 + columnOffset); + mergeAndFill(sheet, dayWeatherRegion, paramData.getDayWeather(), contentStyle); + drawBorderForRegion(sheet, dayWeatherRegion, workbook); + + // ============================================== + // 11. 夜晚:G4-I4合并 + // ============================================== + CellRangeAddress nightRegion = new CellRangeAddress(3 + rowOffset, 3 + rowOffset, 6 + columnOffset, 8 + columnOffset); + mergeAndFill(sheet, nightRegion, "夜晚", titleStyle); + drawBorderForRegion(sheet, nightRegion, workbook); + + // ============================================== + // 12. 夜晚天气:J4-M4合并 + // ============================================== + CellRangeAddress nightWeatherRegion = new CellRangeAddress(3 + rowOffset, 3 + rowOffset, 9 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, nightWeatherRegion, paramData.getNightWeather(), contentStyle); + drawBorderForRegion(sheet, nightWeatherRegion, workbook); + + // ============================================== + // 13. 项目简介:A5-B5合并 + // ============================================== + CellRangeAddress introRegion = new CellRangeAddress(4 + rowOffset, 4 + rowOffset, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, introRegion, "项目简介", titleStyle); + drawBorderForRegion(sheet, introRegion, workbook); + + // ============================================== + // 14. 项目简介内容:C5-M5合并 + // ============================================== + CellRangeAddress introContentRegion = new CellRangeAddress(4 + rowOffset, 4 + rowOffset, 2 + columnOffset, 12 + columnOffset); + String introContent = "田东县乡村振兴分布式光伏项目(一期)眉定项目位于百色市田东县那拔镇,项目备案容量为15MW,现计划装机容量为15.06MW,土地使用权面积217.36亩,可实施的交流容量约为15.06MW。"; + mergeAndFill(sheet, introContentRegion, introContent, contentStyle); + drawBorderForRegion(sheet, introContentRegion, workbook); + Row introRow = sheet.getRow(4 + rowOffset); + if (introRow == null) { + introRow = sheet.createRow(4 + rowOffset); + } + introRow.setHeightInPoints(60); + + // ============================================== + // 15. 光伏场区标题行(C6-M6合并) + // ============================================== + CellRangeAddress fieldTitleRegion = new CellRangeAddress(5 + rowOffset, 5 + rowOffset, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, fieldTitleRegion, "光伏场区", headerStyle); + drawBorderForRegion(sheet, fieldTitleRegion, workbook); + Row fieldTitleRow = sheet.getRow(5 + rowOffset); + if (fieldTitleRow == null) { + fieldTitleRow = sheet.createRow(5 + rowOffset); + } + fieldTitleRow.setHeightInPoints(25); + + // ============================================== + // 16. 表头行(第7行,索引6) + // ============================================== + int headerRowNum = 6 + rowOffset; + Row headerRow = sheet.getRow(headerRowNum); + if (headerRow == null) { + headerRow = sheet.createRow(headerRowNum); + } + + // C7:序号 + Cell c7 = headerRow.createCell(2 + columnOffset); + c7.setCellValue("序号"); + c7.setCellStyle(headerStyle); + CellRangeAddress c7Region = new CellRangeAddress(headerRowNum, headerRowNum, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, c7Region, workbook); + + // D7-E7:项目 + CellRangeAddress projectRegion = new CellRangeAddress(headerRowNum, headerRowNum, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, projectRegion, "项目", headerStyle); + drawBorderForRegion(sheet, projectRegion, workbook); + + // F7:设计值 + Cell f7 = headerRow.createCell(5 + columnOffset); + f7.setCellValue("设计值"); + f7.setCellStyle(headerStyle); + CellRangeAddress f7Region = new CellRangeAddress(headerRowNum, headerRowNum, 5 + columnOffset, 5 + columnOffset); + drawBorderForRegion(sheet, f7Region, workbook); + + // G7-H7:今日施工计划 + CellRangeAddress planRegion = new CellRangeAddress(headerRowNum, headerRowNum, 6 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, planRegion, "今日施工计划", headerStyle); + drawBorderForRegion(sheet, planRegion, workbook); + + // I7-J7:今日施工完成情况 + CellRangeAddress completeRegion = new CellRangeAddress(headerRowNum, headerRowNum, 8 + columnOffset, 9 + columnOffset); + mergeAndFill(sheet, completeRegion, "今日施工完成情况", headerStyle); + drawBorderForRegion(sheet, completeRegion, workbook); + + // K7:累计完成工程量 + Cell k7 = headerRow.createCell(10 + columnOffset); + k7.setCellValue("累计完成工程量"); + k7.setCellStyle(headerStyle); + CellRangeAddress k7Region = new CellRangeAddress(headerRowNum, headerRowNum, 10 + columnOffset, 10 + columnOffset); + drawBorderForRegion(sheet, k7Region, workbook); + + // L7-M7:施工形象及进度 + CellRangeAddress processRegion = new CellRangeAddress(headerRowNum, headerRowNum, 11 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, processRegion, "施工形象及进度", headerStyle); + drawBorderForRegion(sheet, processRegion, workbook); + + headerRow.setHeightInPoints(25); + + // ============================================== + // 17. 动态填充进度数据 + // ============================================== + int lastDataRow = headerRowNum; // 记录最后一行数据的行索引 + if (progressList != null && !progressList.isEmpty()) { + int dataStartRow = headerRowNum + 1; // 数据从第8行开始(索引7) + + for (int i = 0; i < progressList.size(); i++) { + ProgressData data = progressList.get(i); + int rowNum = dataStartRow + i; + lastDataRow = rowNum; // 更新最后一行索引 + Row dataRow = sheet.getRow(rowNum); + if (dataRow == null) { + dataRow = sheet.createRow(rowNum); + } + + // C列:序号 + Cell cCell = dataRow.createCell(2 + columnOffset); + cCell.setCellValue(data.getNum()); + cCell.setCellStyle(contentStyle); + drawBorderForCell(sheet, rowNum, 2 + columnOffset, 2 + columnOffset, workbook); + + // D-E列:项目 + CellRangeAddress projectDataRegion = new CellRangeAddress(rowNum, rowNum, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, projectDataRegion, data.getProject(), contentStyle); + drawBorderForRegion(sheet, projectDataRegion, workbook); + + // F列:设计值 + Cell fCell = dataRow.createCell(5 + columnOffset); + fCell.setCellValue(data.getDesign()); + fCell.setCellStyle(contentStyle); + drawBorderForCell(sheet, rowNum, 5 + columnOffset, 5 + columnOffset, workbook); + + // G-H列:今日施工计划 + CellRangeAddress planDataRegion = new CellRangeAddress(rowNum, rowNum, 6 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, planDataRegion, data.getPlan(), contentStyle); + drawBorderForRegion(sheet, planDataRegion, workbook); + + // I-J列:今日施工完成情况 + CellRangeAddress completeDataRegion = new CellRangeAddress(rowNum, rowNum, 8 + columnOffset, 9 + columnOffset); + mergeAndFill(sheet, completeDataRegion, data.getComplete(), contentStyle); + drawBorderForRegion(sheet, completeDataRegion, workbook); + + // K列:累计完成工程量 + Cell kCell = dataRow.createCell(10 + columnOffset); + kCell.setCellValue(data.getTotal()); + kCell.setCellStyle(contentStyle); + drawBorderForCell(sheet, rowNum, 10 + columnOffset, 10 + columnOffset, workbook); + + // L-M列:施工形象及进度 + CellRangeAddress processDataRegion = new CellRangeAddress(rowNum, rowNum, 11 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, processDataRegion, data.getProcess(), contentStyle); + drawBorderForRegion(sheet, processDataRegion, workbook); + + dataRow.setHeightInPoints(20); + } + } + + // ============================================== + // 18. 情况说明行(动态数据下一行) + // ============================================== + int noteRowNum = lastDataRow + 1; + Row noteRow = sheet.getRow(noteRowNum); + if (noteRow == null) { + noteRow = sheet.createRow(noteRowNum); + } + + // C-E列合并:情况说明 + CellRangeAddress noteTitleRegion = new CellRangeAddress(noteRowNum, noteRowNum, 2 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, noteTitleRegion, "情况说明", headerStyle); + drawBorderForRegion(sheet, noteTitleRegion, workbook); + + // F-M列合并:无 + CellRangeAddress noteContentRegion = new CellRangeAddress(noteRowNum, noteRowNum, 5 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, noteContentRegion, "无", contentStyle); + drawBorderForRegion(sheet, noteContentRegion, workbook); + + noteRow.setHeightInPoints(25); + + // ============================================== + // 19. A6到情况说明行的B列纵向合并(含内容) + // ============================================== + int startMergeRow = 5 + rowOffset; // A6对应行索引5 + int endMergeRow = noteRowNum; // 情况说明行的行索引 + CellRangeAddress aColumnRegion = new CellRangeAddress(startMergeRow, endMergeRow, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, aColumnRegion, "施工部位\n施工内容\n施工形象\n及进度", titleStyle); + drawBorderForRegion(sheet, aColumnRegion, workbook); + + // 调整A-B列合并区域行高(适配4行文本) + int totalHeight = 0; + for (int i = startMergeRow; i <= endMergeRow; i++) { + Row row = sheet.getRow(i); + if (row != null) { + totalHeight += row.getHeightInPoints(); + } + } + int rowCount = endMergeRow - startMergeRow + 1; + int baseHeight = 20; + int extraHeight = (int) (totalHeight - rowCount * baseHeight); // 额外高度分配给首行 + Row firstRow = sheet.getRow(startMergeRow); + if (firstRow != null) { + firstRow.setHeightInPoints(baseHeight + extraHeight); + } + for (int i = startMergeRow + 1; i <= endMergeRow; i++) { + Row row = sheet.getRow(i); + if (row != null) { + row.setHeightInPoints(baseHeight); + } + } + + // ============================================== + // 20. 现场质量行(情况说明行下一行) + // ============================================== + int qualityRowNum = noteRowNum + 1; + Row qualityRow = sheet.getRow(qualityRowNum); + if (qualityRow == null) { + qualityRow = sheet.createRow(qualityRowNum); + } + + // A-B列合并:现场质量 + CellRangeAddress qualityTitleRegion = new CellRangeAddress(qualityRowNum, qualityRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, qualityTitleRegion, "现场质量", titleStyle); + drawBorderForRegion(sheet, qualityTitleRegion, workbook); + + // C-M列合并:质量正常.可控。 + CellRangeAddress qualityContentRegion = new CellRangeAddress(qualityRowNum, qualityRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, qualityContentRegion, paramData.getQuality(), contentStyle); + drawBorderForRegion(sheet, qualityContentRegion, workbook); + + qualityRow.setHeightInPoints(25); + + // ============================================== + // 21. 现场安全行(现场质量行下一行) + // ============================================== + int safetyRowNum = qualityRowNum + 1; + Row safetyRow = sheet.getRow(safetyRowNum); + if (safetyRow == null) { + safetyRow = sheet.createRow(safetyRowNum); + } + + // A-B列合并:现场安全\n安全巡检 + CellRangeAddress safetyTitleRegion = new CellRangeAddress(safetyRowNum, safetyRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, safetyTitleRegion, "现场安全\n安全巡检", titleStyle); + drawBorderForRegion(sheet, safetyTitleRegion, workbook); + + // C-M列合并:安全正常.可控。 + CellRangeAddress safetyContentRegion = new CellRangeAddress(safetyRowNum, safetyRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, safetyContentRegion, paramData.getSafety(), contentStyle); + drawBorderForRegion(sheet, safetyContentRegion, workbook); + + safetyRow.setHeightInPoints(30); // 适配两行文本 + + // ============================================== + // 22. 施工现场情况说明行(现场安全行下一行) + // ============================================== + int siteRowNum = safetyRowNum + 1; + Row siteRow = sheet.getRow(siteRowNum); + if (siteRow == null) { + siteRow = sheet.createRow(siteRowNum); + } + + // A-B列合并:施工现场 + CellRangeAddress siteTitleRegion = new CellRangeAddress(siteRowNum, siteRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, siteTitleRegion, "施工现场", titleStyle); + drawBorderForRegion(sheet, siteTitleRegion, workbook); + + // C-E列合并:情况说明 + CellRangeAddress siteSubTitleRegion = new CellRangeAddress(siteRowNum, siteRowNum, 2 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, siteSubTitleRegion, "情况说明", headerStyle); + drawBorderForRegion(sheet, siteSubTitleRegion, workbook); + + // F-M列合并:详细内容 + String siteContent = "一.光伏区施工情况\n" + + "1.1#、3#、5#方阵支架、组件安装;\n" + + "2.2#方阵直流电缆敷设。\n\n" + + "二.验收情况\n" + + "今日无验收。"; + CellRangeAddress siteContentRegion = new CellRangeAddress(siteRowNum, siteRowNum, 5 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, siteContentRegion, siteContent, contentStyle); + drawBorderForRegion(sheet, siteContentRegion, workbook); + + siteRow.setHeightInPoints(100); // 适配多行文本 + + // ============================================== + // 23. 施工问题及处理情况行(施工现场行下一行) + // ============================================== + int problemRowNum = siteRowNum + 1; + Row problemRow = sheet.getRow(problemRowNum); + if (problemRow == null) { + problemRow = sheet.createRow(problemRowNum); + } + + // A-B列合并:施工问题及处理情况 + CellRangeAddress problemTitleRegion = new CellRangeAddress(problemRowNum, problemRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, problemTitleRegion, "施工问题及处理情况", titleStyle); + drawBorderForRegion(sheet, problemTitleRegion, workbook); + + // C-M列合并:坡度较大,合理安排人员采取有效防护措施。 + CellRangeAddress problemContentRegion = new CellRangeAddress(problemRowNum, problemRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, problemContentRegion, "坡度较大,合理安排人员采取有效防护措施。", contentStyle); + drawBorderForRegion(sheet, problemContentRegion, workbook); + + problemRow.setHeightInPoints(30); // 适配可能的换行 + + // ============================================== + // 24. 设计供图或技术核定行(施工问题行下一行) + // ============================================== + int designRowNum = problemRowNum + 1; + Row designRow = sheet.getRow(designRowNum); + if (designRow == null) { + designRow = sheet.createRow(designRowNum); + } + + // A-B列合并:设计供图或技术核定 + CellRangeAddress designTitleRegion = new CellRangeAddress(designRowNum, designRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, designTitleRegion, "设计供图或技术核定", titleStyle); + drawBorderForRegion(sheet, designTitleRegion, workbook); + + // C-M列合并:施工图满足现场施工 + CellRangeAddress designContentRegion = new CellRangeAddress(designRowNum, designRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, designContentRegion, "施工图满足现场施工", contentStyle); + drawBorderForRegion(sheet, designContentRegion, workbook); + + designRow.setHeightInPoints(25); + + // ============================================== + // 25. 参建单位人员标题行(设计核定行下一行) + // ============================================== + int participantTitleRow = designRowNum + 1; + Row titleRow2 = sheet.getRow(participantTitleRow); + if (titleRow2 == null) { + titleRow2 = sheet.createRow(participantTitleRow); + } + + // C-D列合并:参建单位 + CellRangeAddress unitRegion = new CellRangeAddress(participantTitleRow, participantTitleRow, 2 + columnOffset, 3 + columnOffset); + mergeAndFill(sheet, unitRegion, "参建单位", headerStyle); + drawBorderForRegion(sheet, unitRegion, workbook); + + // E列:经理班子人员(不合并) + Cell leaderCell = titleRow2.createCell(4 + columnOffset); + leaderCell.setCellValue("经理班子人员"); + leaderCell.setCellStyle(headerStyle); + CellRangeAddress leaderRegion = new CellRangeAddress(participantTitleRow, participantTitleRow, 4 + columnOffset, 4 + columnOffset); + drawBorderForRegion(sheet, leaderRegion, workbook); + + // F-G列合并:主要管理技术人员 + CellRangeAddress managerRegion = new CellRangeAddress(participantTitleRow, participantTitleRow, 5 + columnOffset, 6 + columnOffset); + mergeAndFill(sheet, managerRegion, "主要管理技术人员", headerStyle); + drawBorderForRegion(sheet, managerRegion, workbook); + + // H列:其他人员(不合并) + Cell otherCell = titleRow2.createCell(7 + columnOffset); + otherCell.setCellValue("其他人员"); + otherCell.setCellStyle(headerStyle); + CellRangeAddress otherRegion = new CellRangeAddress(participantTitleRow, participantTitleRow, 7 + columnOffset, 7 + columnOffset); + drawBorderForRegion(sheet, otherRegion, workbook); + + // I-M列合并:备注 + CellRangeAddress remarkRegion1 = new CellRangeAddress(participantTitleRow, participantTitleRow, 8 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, remarkRegion1, "备注", headerStyle); + drawBorderForRegion(sheet, remarkRegion1, workbook); + + titleRow2.setHeightInPoints(25); + + // ============================================== + // 26. 动态填充参建单位人员数据 + // ============================================== + int lastParticipantRow = participantTitleRow; // 记录参建单位数据最后一行 + if (participantList != null && !participantList.isEmpty()) { + int dataStartRow = participantTitleRow + 1; + + for (int i = 0; i < participantList.size(); i++) { + ParticipantData data = participantList.get(i); + int rowNum = dataStartRow + i; + lastParticipantRow = rowNum; + Row dataRow = sheet.getRow(rowNum); + if (dataRow == null) { + dataRow = sheet.createRow(rowNum); + } + + // C-D列:参建单位 + CellRangeAddress unitDataRegion = new CellRangeAddress(rowNum, rowNum, 2 + columnOffset, 3 + columnOffset); + mergeAndFill(sheet, unitDataRegion, data.getUnit(), contentStyle); + drawBorderForRegion(sheet, unitDataRegion, workbook); + + // E列:经理班子人员 + Cell leaderDataCell = dataRow.createCell(4 + columnOffset); + leaderDataCell.setCellValue(data.getLeader()); + leaderDataCell.setCellStyle(contentStyle); + CellRangeAddress leaderDataRegion = new CellRangeAddress(rowNum, rowNum, 4 + columnOffset, 4 + columnOffset); + drawBorderForRegion(sheet, leaderDataRegion, workbook); + + // F-G列:主要管理技术人员 + CellRangeAddress managerDataRegion = new CellRangeAddress(rowNum, rowNum, 5 + columnOffset, 6 + columnOffset); + mergeAndFill(sheet, managerDataRegion, data.getManager(), contentStyle); + drawBorderForRegion(sheet, managerDataRegion, workbook); + + // H列:其他人员 + Cell otherDataCell = dataRow.createCell(7 + columnOffset); + otherDataCell.setCellValue(data.getOther()); + otherDataCell.setCellStyle(contentStyle); + CellRangeAddress otherDataRegion = new CellRangeAddress(rowNum, rowNum, 7 + columnOffset, 7 + columnOffset); + drawBorderForRegion(sheet, otherDataRegion, workbook); + + // I-M列:备注 + CellRangeAddress remarkDataRegion1 = new CellRangeAddress(rowNum, rowNum, 8 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, remarkDataRegion1, data.getRemark(), contentStyle); + drawBorderForRegion(sheet, remarkDataRegion1, workbook); + + dataRow.setHeightInPoints(22); + } + } + + // ============================================== + // 27. AB列纵向合并(参建单位标题行到数据结束行) + // ============================================== + CellRangeAddress participantABRegion = new CellRangeAddress( + participantTitleRow, // 开始行:参建单位标题行 + lastParticipantRow, // 结束行:参建单位数据最后一行 + 0 + columnOffset, 1 + columnOffset // A-B列 + ); + mergeAndFill(sheet, participantABRegion, + "参建单位主要管理.技术人员及劳务人员到位情况", + titleStyle); + drawBorderForRegion(sheet, participantABRegion, workbook); + + // 调整AB列合并区域行高(适配文本) + int participantRowCount = lastParticipantRow - participantTitleRow + 1; + int participantTotalHeight = 0; + for (int i = participantTitleRow; i <= lastParticipantRow; i++) { + Row row = sheet.getRow(i); + if (row != null) { + participantTotalHeight += row.getHeightInPoints(); + } + } + int participantBaseHeight = 25; + int participantExtraHeight = (int) (participantTotalHeight - participantRowCount * participantBaseHeight); + Row participantTitleRowObj = sheet.getRow(participantTitleRow); + if (participantTitleRowObj != null) { + participantTitleRowObj.setHeightInPoints(participantBaseHeight + participantExtraHeight); + } + for (int i = participantTitleRow + 1; i <= lastParticipantRow; i++) { + Row row = sheet.getRow(i); + if (row != null) { + row.setHeightInPoints(participantBaseHeight); + } + } + + // ============================================== + // 28. 施工机械标题行(参建单位数据行下一行) + // 第一行:C-M合并输入"光伏场区工程:"(左对齐) + // ============================================== + int machineTitleRow = lastParticipantRow + 1; + Row machineTitle = sheet.getRow(machineTitleRow); + if (machineTitle == null) { + machineTitle = sheet.createRow(machineTitleRow); + } + + // C-M列合并:光伏场区工程:(左对齐) + CellRangeAddress machineHeaderRegion = new CellRangeAddress(machineTitleRow, machineTitleRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, machineHeaderRegion, "光伏场区工程:", leftHeaderStyle); + drawBorderForRegion(sheet, machineHeaderRegion, workbook); + + machineTitle.setHeightInPoints(25); + + // ============================================== + // 29. 施工机械数据行(标题行下一行) + // C-D合并:机械/设备数量;E-M合并:设备清单(逗号分隔) + // ============================================== + int machineDataRow = machineTitleRow + 1; + Row machineData = sheet.getRow(machineDataRow); + if (machineData == null) { + machineData = sheet.createRow(machineDataRow); + } + + // C-D列合并:机械/设备数量 + CellRangeAddress machineCountRegion = new CellRangeAddress(machineDataRow, machineDataRow, 2 + columnOffset, 3 + columnOffset); + mergeAndFill(sheet, machineCountRegion, "机械/设备数量", headerStyle); + drawBorderForRegion(sheet, machineCountRegion, workbook); + + // E-M列合并:设备清单(逗号分隔) + String equipmentListStr = "RTK-0、清孔工具-0、电动扳手-20、小蜜蜂-0"; + CellRangeAddress equipmentRegion = new CellRangeAddress(machineDataRow, machineDataRow, 4 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, equipmentRegion, equipmentListStr, contentStyle); + drawBorderForRegion(sheet, equipmentRegion, workbook); + + machineData.setHeightInPoints(25); // 单行显示无需过高行高 + + // ============================================== + // 30. AB列纵向合并(施工机械标题行到数据行) + // 输入:施工机械及设备投入情况 + // ============================================== + CellRangeAddress machineABRegion = new CellRangeAddress( + machineTitleRow, // 开始行:机械标题行 + machineDataRow, // 结束行:机械数据行 + 0 + columnOffset, 1 + columnOffset // A-B列 + ); + mergeAndFill(sheet, machineABRegion, "施工机械及设备投入情况", titleStyle); + drawBorderForRegion(sheet, machineABRegion, workbook); + + // 调整AB列合并区域行高 + Row machineTitleRowObj = sheet.getRow(machineTitleRow); + Row machineDataRowObj = sheet.getRow(machineDataRow); + float machineTotalHeight = 0; + if (machineTitleRowObj != null) { + machineTotalHeight += machineTitleRowObj.getHeightInPoints(); + } + if (machineDataRowObj != null) { + machineTotalHeight += machineDataRowObj.getHeightInPoints(); + } + // 分配高度确保文本垂直居中 + if (machineTitleRowObj != null) { + machineTitleRowObj.setHeightInPoints(25); + } + if (machineDataRowObj != null) { + machineDataRowObj.setHeightInPoints(machineTotalHeight - 25); + } + + // ============================================== + // 31. 设备进场情况标题行(机械数据行下一行) + // 记录此行为AB列合并的起始行 + // ============================================== + int equipmentTitleRow = machineDataRow + 1; // AB列合并起始行 + Row equipmentTitle = sheet.getRow(equipmentTitleRow); + if (equipmentTitle == null) { + equipmentTitle = sheet.createRow(equipmentTitleRow); + } + + // C-M列合并:主要设备进场情况:(左对齐) + CellRangeAddress equipmentHeaderRegion = new CellRangeAddress(equipmentTitleRow, equipmentTitleRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, equipmentHeaderRegion, "主要设备进场情况:", leftHeaderStyle); + drawBorderForRegion(sheet, equipmentHeaderRegion, workbook); + + equipmentTitle.setHeightInPoints(20); + + // ============================================== + // 32. 设备进场情况表头行(标题行下一行) + // ============================================== + int equipmentHeaderRow = equipmentTitleRow + 1; + Row eqHeaderRow = sheet.getRow(equipmentHeaderRow); + if (eqHeaderRow == null) { + eqHeaderRow = sheet.createRow(equipmentHeaderRow); + } + + // C列:序号 + Cell eqC = eqHeaderRow.createCell(2 + columnOffset); + eqC.setCellValue("序号"); + eqC.setCellStyle(headerStyle); + CellRangeAddress eqCRegion = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, eqCRegion, workbook); + + // D-E列:项目 + CellRangeAddress eqProjectRegion = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, eqProjectRegion, "项目", headerStyle); + drawBorderForRegion(sheet, eqProjectRegion, workbook); + + // F列:数量 + Cell eqF = eqHeaderRow.createCell(5 + columnOffset); + eqF.setCellValue("数量"); + eqF.setCellStyle(headerStyle); + CellRangeAddress eqFRegion = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 5 + columnOffset, 5 + columnOffset); + drawBorderForRegion(sheet, eqFRegion, workbook); + + // G-H列:生产情况 + CellRangeAddress eqProductionRegion = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 6 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, eqProductionRegion, "生产情况", headerStyle); + drawBorderForRegion(sheet, eqProductionRegion, workbook); + + // I-J列:今日进场情况 + CellRangeAddress eqEntryRegion = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 8 + columnOffset, 9 + columnOffset); + mergeAndFill(sheet, eqEntryRegion, "今日进场情况", headerStyle); + drawBorderForRegion(sheet, eqEntryRegion, workbook); + + // K列:累计进场情况 + Cell eqK = eqHeaderRow.createCell(10 + columnOffset); + eqK.setCellValue("累计进场情况"); + eqK.setCellStyle(headerStyle); + CellRangeAddress eqKRegion = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 10 + columnOffset, 10 + columnOffset); + drawBorderForRegion(sheet, eqKRegion, workbook); + + // L-M列:备注 + CellRangeAddress remarkRegion2 = new CellRangeAddress(equipmentHeaderRow, equipmentHeaderRow, 11 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, remarkRegion2, "备注", headerStyle); + drawBorderForRegion(sheet, remarkRegion2, workbook); + + eqHeaderRow.setHeightInPoints(20); + + // ============================================== + // 33. 动态填充设备进场数据 + // ============================================== + int lastEquipmentRow = equipmentHeaderRow; // 记录设备数据最后一行 + if (equipmentEntryList != null && !equipmentEntryList.isEmpty()) { + int dataStartRow = equipmentHeaderRow + 1; + + for (int i = 0; i < equipmentEntryList.size(); i++) { + EquipmentEntryData data = equipmentEntryList.get(i); + int rowNum = dataStartRow + i; + lastEquipmentRow = rowNum; + Row dataRow = sheet.getRow(rowNum); + if (dataRow == null) { + dataRow = sheet.createRow(rowNum); + } + + // C列:序号 + Cell noCell = dataRow.createCell(2 + columnOffset); + noCell.setCellValue(data.getNo()); + noCell.setCellStyle(contentStyle); + CellRangeAddress noRegion = new CellRangeAddress(rowNum, rowNum, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, noRegion, workbook); + + // D-E列:项目 + CellRangeAddress eqProjectDataRegion = new CellRangeAddress(rowNum, rowNum, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, eqProjectDataRegion, data.getProject(), contentStyle); + drawBorderForRegion(sheet, eqProjectDataRegion, workbook); + + // F列:数量 + Cell numCell = dataRow.createCell(5 + columnOffset); + numCell.setCellValue(data.getNum()); + numCell.setCellStyle(contentStyle); + CellRangeAddress numRegion = new CellRangeAddress(rowNum, rowNum, 5 + columnOffset, 5 + columnOffset); + drawBorderForRegion(sheet, numRegion, workbook); + + // G-H列:生产情况 + CellRangeAddress productionRegion = new CellRangeAddress(rowNum, rowNum, 6 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, productionRegion, data.getProduction(), contentStyle); + drawBorderForRegion(sheet, productionRegion, workbook); + + // I-J列:今日进场情况 + CellRangeAddress entryRegion = new CellRangeAddress(rowNum, rowNum, 8 + columnOffset, 9 + columnOffset); + mergeAndFill(sheet, entryRegion, data.getEntry(), contentStyle); + drawBorderForRegion(sheet, entryRegion, workbook); + + // K列:累计进场情况 + Cell totalEntryCell = dataRow.createCell(10 + columnOffset); + totalEntryCell.setCellValue(data.getTotalEntry()); + totalEntryCell.setCellStyle(contentStyle); + CellRangeAddress totalEntryRegion = new CellRangeAddress(rowNum, rowNum, 10 + columnOffset, 10 + columnOffset); + drawBorderForRegion(sheet, totalEntryRegion, workbook); + + // L-M列:备注 + CellRangeAddress remarkDataRegion2 = new CellRangeAddress(rowNum, rowNum, 11 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, remarkDataRegion2, data.getRemark(), contentStyle); + drawBorderForRegion(sheet, remarkDataRegion2, workbook); + + dataRow.setHeightInPoints(20); + } + } + + // ============================================== + // 34. 设备情况说明行(设备进场数据行下一行) + // ============================================== + int equipmentNoteRow = lastEquipmentRow + 1; + Row eqNoteRow = sheet.getRow(equipmentNoteRow); + if (eqNoteRow == null) { + eqNoteRow = sheet.createRow(equipmentNoteRow); + } + + // C-E列合并:情况说明 + CellRangeAddress eqNoteTitleRegion = new CellRangeAddress(equipmentNoteRow, equipmentNoteRow, 2 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, eqNoteTitleRegion, "情况说明", headerStyle); + drawBorderForRegion(sheet, eqNoteTitleRegion, workbook); + + // F-M列合并:待生产 + CellRangeAddress eqNoteContentRegion = new CellRangeAddress(equipmentNoteRow, equipmentNoteRow, 5 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, eqNoteContentRegion, "待生产", contentStyle); + drawBorderForRegion(sheet, eqNoteContentRegion, workbook); + + eqNoteRow.setHeightInPoints(20); + + // ============================================== + // 35. 主要材料进场情况标题行(情况说明行下一行) + // ============================================== + int materialTitleRow = equipmentNoteRow + 1; + Row materialTitle = sheet.getRow(materialTitleRow); + if (materialTitle == null) { + materialTitle = sheet.createRow(materialTitleRow); + } + + CellRangeAddress materialHeaderRegion = new CellRangeAddress(materialTitleRow, materialTitleRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, materialHeaderRegion, "主要材料进场情况:", leftHeaderStyle); + drawBorderForRegion(sheet, materialHeaderRegion, workbook); + + materialTitle.setHeightInPoints(20); + + // ============================================== + // 36. 光伏场区工程标题行(主要材料标题行下一行) + // ============================================== + int materialSubTitleRow = materialTitleRow + 1; + Row materialSubTitle = sheet.getRow(materialSubTitleRow); + if (materialSubTitle == null) { + materialSubTitle = sheet.createRow(materialSubTitleRow); + } + + CellRangeAddress materialSubHeaderRegion = new CellRangeAddress(materialSubTitleRow, materialSubTitleRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, materialSubHeaderRegion, "1.光伏场区工程:", leftHeaderStyle); + drawBorderForRegion(sheet, materialSubHeaderRegion, workbook); + + materialSubTitle.setHeightInPoints(20); + + // ============================================== + // 37. 材料进场情况表头行(光伏场区工程标题行下一行) + // ============================================== + int materialHeaderRow = materialSubTitleRow + 1; + Row materialHeader = sheet.getRow(materialHeaderRow); + if (materialHeader == null) { + materialHeader = sheet.createRow(materialHeaderRow); + } + + // C列:序号 + Cell materialC = materialHeader.createCell(2 + columnOffset); + materialC.setCellValue("序号"); + materialC.setCellStyle(headerStyle); + CellRangeAddress materialCRegion = new CellRangeAddress(materialHeaderRow, materialHeaderRow, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, materialCRegion, workbook); + + // D-E列:材料名称 + CellRangeAddress materialNameRegion = new CellRangeAddress(materialHeaderRow, materialHeaderRow, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, materialNameRegion, "材料名称", headerStyle); + drawBorderForRegion(sheet, materialNameRegion, workbook); + + // F列:设计值 + Cell materialF = materialHeader.createCell(5 + columnOffset); + materialF.setCellValue("设计值"); + materialF.setCellStyle(headerStyle); + CellRangeAddress materialFRegion = new CellRangeAddress(materialHeaderRow, materialHeaderRow, 5 + columnOffset, 5 + columnOffset); + drawBorderForRegion(sheet, materialFRegion, workbook); + + // G-L列:进场情况 + CellRangeAddress materialEntryRegion = new CellRangeAddress(materialHeaderRow, materialHeaderRow, 6 + columnOffset, 11 + columnOffset); + mergeAndFill(sheet, materialEntryRegion, "进场情况", headerStyle); + drawBorderForRegion(sheet, materialEntryRegion, workbook); + + // M列:送检记录 + Cell materialM = materialHeader.createCell(12 + columnOffset); + materialM.setCellValue("送检记录"); + materialM.setCellStyle(headerStyle); + CellRangeAddress materialMRegion = new CellRangeAddress(materialHeaderRow, materialHeaderRow, 12 + columnOffset, 12 + columnOffset); + drawBorderForRegion(sheet, materialMRegion, workbook); + + materialHeader.setHeightInPoints(20); + + // ============================================== + // 38. 动态填充材料进场数据 + // ============================================== + int lastMaterialRow = materialHeaderRow; // 记录材料数据最后一行 + if (materialList != null && !materialList.isEmpty()) { + int dataStartRow = materialHeaderRow + 1; + + for (int i = 0; i < materialList.size(); i++) { + MaterialEntryData data = materialList.get(i); + int rowNum = dataStartRow + i; + lastMaterialRow = rowNum; + Row dataRow = sheet.getRow(rowNum); + if (dataRow == null) { + dataRow = sheet.createRow(rowNum); + } + + // C列:序号 + Cell noCell = dataRow.createCell(2 + columnOffset); + noCell.setCellValue(data.getNo()); + noCell.setCellStyle(contentStyle); + CellRangeAddress noRegion = new CellRangeAddress(rowNum, rowNum, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, noRegion, workbook); + + // D-E列:材料名称 + CellRangeAddress nameRegion = new CellRangeAddress(rowNum, rowNum, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, nameRegion, data.getMaterialName(), contentStyle); + drawBorderForRegion(sheet, nameRegion, workbook); + + // F列:设计值 + Cell designCell = dataRow.createCell(5 + columnOffset); + designCell.setCellValue(data.getDesignValue()); + designCell.setCellStyle(contentStyle); + CellRangeAddress designRegion = new CellRangeAddress(rowNum, rowNum, 5 + columnOffset, 5 + columnOffset); + drawBorderForRegion(sheet, designRegion, workbook); + + // G-L列:进场情况 + CellRangeAddress entryRegion = new CellRangeAddress(rowNum, rowNum, 6 + columnOffset, 11 + columnOffset); + mergeAndFill(sheet, entryRegion, data.getEntryStatus(), contentStyle); + drawBorderForRegion(sheet, entryRegion, workbook); + + // M列:送检记录 + Cell inspectionCell = dataRow.createCell(12 + columnOffset); + inspectionCell.setCellValue(data.getInspection()); + inspectionCell.setCellStyle(contentStyle); + CellRangeAddress inspectionRegion = new CellRangeAddress(rowNum, rowNum, 12 + columnOffset, 12 + columnOffset); + drawBorderForRegion(sheet, inspectionRegion, workbook); + + dataRow.setHeightInPoints(20); + } + } + + // ============================================== + // 39. 主要材料送检情况标题行(材料进场数据行下一行) + // ============================================== + int inspectionTitleRow = lastMaterialRow + 1; + Row inspectionTitle = sheet.getRow(inspectionTitleRow); + if (inspectionTitle == null) { + inspectionTitle = sheet.createRow(inspectionTitleRow); + } + + CellRangeAddress inspectionHeaderRegion = new CellRangeAddress(inspectionTitleRow, inspectionTitleRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, inspectionHeaderRegion, "主要材料送检情况:", leftHeaderStyle); + drawBorderForRegion(sheet, inspectionHeaderRegion, workbook); + + inspectionTitle.setHeightInPoints(20); + + // ============================================== + // 40. 材料送检情况表头行(标题行下一行) + // 列布局:C=序号, D-E=材料名称, F-G=用材部位, + // H-J=送检机构, K-M=送检记录 + // ============================================== + int inspectionHeaderRow = inspectionTitleRow + 1; + Row inspectionHeader = sheet.getRow(inspectionHeaderRow); + if (inspectionHeader == null) { + inspectionHeader = sheet.createRow(inspectionHeaderRow); + } + + // C列:序号 + Cell inspC = inspectionHeader.createCell(2 + columnOffset); + inspC.setCellValue("序号"); + inspC.setCellStyle(headerStyle); + CellRangeAddress inspCRegion = new CellRangeAddress(inspectionHeaderRow, inspectionHeaderRow, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, inspCRegion, workbook); + + // D-E列:材料名称 + CellRangeAddress inspNameRegion = new CellRangeAddress(inspectionHeaderRow, inspectionHeaderRow, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, inspNameRegion, "材料名称", headerStyle); + drawBorderForRegion(sheet, inspNameRegion, workbook); + + // F-G列:用材部位 + CellRangeAddress inspPartRegion = new CellRangeAddress(inspectionHeaderRow, inspectionHeaderRow, 5 + columnOffset, 6 + columnOffset); + mergeAndFill(sheet, inspPartRegion, "用材部位", headerStyle); + drawBorderForRegion(sheet, inspPartRegion, workbook); + + // H-J列:送检机构 + CellRangeAddress inspOrgRegion = new CellRangeAddress(inspectionHeaderRow, inspectionHeaderRow, 7 + columnOffset, 9 + columnOffset); + mergeAndFill(sheet, inspOrgRegion, "送检机构", headerStyle); + drawBorderForRegion(sheet, inspOrgRegion, workbook); + + // K-M列:送检记录 + CellRangeAddress inspRecordRegion = new CellRangeAddress(inspectionHeaderRow, inspectionHeaderRow, 10 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, inspRecordRegion, "送检记录", headerStyle); + drawBorderForRegion(sheet, inspRecordRegion, workbook); + + inspectionHeader.setHeightInPoints(20); + + // ============================================== + // 41. 动态填充材料送检数据 + // ============================================== + int lastInspectionRow = inspectionHeaderRow; // 记录送检数据最后一行 + if (inspectionList != null && !inspectionList.isEmpty()) { + int dataStartRow = inspectionHeaderRow + 1; + + for (int i = 0; i < inspectionList.size(); i++) { + MaterialInspectionData data = inspectionList.get(i); + int rowNum = dataStartRow + i; + lastInspectionRow = rowNum; + Row dataRow = sheet.getRow(rowNum); + if (dataRow == null) { + dataRow = sheet.createRow(rowNum); + } + + // C列:序号 + Cell noCell = dataRow.createCell(2 + columnOffset); + noCell.setCellValue(data.getNo()); + noCell.setCellStyle(contentStyle); + CellRangeAddress noRegion = new CellRangeAddress(rowNum, rowNum, 2 + columnOffset, 2 + columnOffset); + drawBorderForRegion(sheet, noRegion, workbook); + + // D-E列:材料名称 + CellRangeAddress nameRegion = new CellRangeAddress(rowNum, rowNum, 3 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, nameRegion, data.getMaterialName(), contentStyle); + drawBorderForRegion(sheet, nameRegion, workbook); + + // F-G列:用材部位 + CellRangeAddress partRegion = new CellRangeAddress(rowNum, rowNum, 5 + columnOffset, 6 + columnOffset); + mergeAndFill(sheet, partRegion, data.getUsePart(), contentStyle); + drawBorderForRegion(sheet, partRegion, workbook); + + // H-J列:送检机构 + CellRangeAddress orgRegion = new CellRangeAddress(rowNum, rowNum, 7 + columnOffset, 9 + columnOffset); + mergeAndFill(sheet, orgRegion, data.getInspectionOrg(), contentStyle); + drawBorderForRegion(sheet, orgRegion, workbook); + + // K-M列:送检记录 + CellRangeAddress recordRegion = new CellRangeAddress(rowNum, rowNum, 10 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, recordRegion, data.getInspectionRecord(), contentStyle); + drawBorderForRegion(sheet, recordRegion, workbook); + + dataRow.setHeightInPoints(20); + } + } + + // ============================================== + // 42. 材料送检情况说明行(送检数据行下一行) + // ============================================== + int inspectionNoteRow = lastInspectionRow + 1; // 最终的情况说明行 + Row inspNoteRow = sheet.getRow(inspectionNoteRow); + if (inspNoteRow == null) { + inspNoteRow = sheet.createRow(inspectionNoteRow); + } + + // C-E列合并:情况说明 + CellRangeAddress inspNoteTitleRegion = new CellRangeAddress(inspectionNoteRow, inspectionNoteRow, 2 + columnOffset, 4 + columnOffset); + mergeAndFill(sheet, inspNoteTitleRegion, "情况说明", headerStyle); + drawBorderForRegion(sheet, inspNoteTitleRegion, workbook); + + // F-M列合并:无 + CellRangeAddress inspNoteContentRegion = new CellRangeAddress(inspectionNoteRow, inspectionNoteRow, 5 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, inspNoteContentRegion, "无", contentStyle); + drawBorderForRegion(sheet, inspNoteContentRegion, workbook); + + inspNoteRow.setHeightInPoints(20); + + // ============================================== + // 关键调整:AB列从设备进场标题行到最终情况说明行合并 + // 开始行:设备进场情况标题行(equipmentTitleRow) + // 结束行:材料送检情况说明行(inspectionNoteRow) + // 合并后标题:主要材料.设备进场情况及送检记录 + // ============================================== + CellRangeAddress finalABRegion = new CellRangeAddress( + equipmentTitleRow, // 开始行:主要设备进场情况标题行 + inspectionNoteRow, // 结束行:最终情况说明行 + 0 + columnOffset, 1 + columnOffset // A-B列 + ); + mergeAndFill(sheet, finalABRegion, "主要材料.设备进场情况及送检记录", titleStyle); + drawBorderForRegion(sheet, finalABRegion, workbook); + + // 调整合并区域行高 + int totalRowCount = inspectionNoteRow - equipmentTitleRow + 1; + float totalRegionHeight = 0; + for (int i = equipmentTitleRow; i <= inspectionNoteRow; i++) { + Row row = sheet.getRow(i); + if (row != null) { + totalRegionHeight += row.getHeightInPoints(); + } + } + float baseHeight1 = 20; + float extraHeight1 = totalRegionHeight - totalRowCount * baseHeight1; + Row equipmentTitleRowObj = sheet.getRow(equipmentTitleRow); + if (equipmentTitleRowObj != null) { + equipmentTitleRowObj.setHeightInPoints(baseHeight1 + (int) extraHeight1); + } + for (int i = equipmentTitleRow + 1; i <= inspectionNoteRow; i++) { + Row row = sheet.getRow(i); + if (row != null) { + row.setHeightInPoints(baseHeight1); + } + } + + // ============================================== + // 43. 并网手续办理情况行 + // ============================================== + int sxNoteRow = inspectionNoteRow + 1; + Row sxRow = sheet.getRow(sxNoteRow); + if (sxRow == null) { + sxRow = sheet.createRow(sxNoteRow); + } + + // A-B列合并:并网手续办理情况 + CellRangeAddress sxTitleRegion = new CellRangeAddress(sxNoteRow, sxNoteRow, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, sxTitleRegion, "并网手续办理情况", titleStyle); + drawBorderForRegion(sheet, sxTitleRegion, workbook); + + // C-M列合并:今日无 + CellRangeAddress sxContentRegion = new CellRangeAddress(sxNoteRow, sxNoteRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, sxContentRegion, "今日无", contentStyle); + drawBorderForRegion(sheet, sxContentRegion, workbook); + + sxRow.setHeightInPoints(30); // 适配可能的换行 + + // ============================================== + // 44. 现场是否存在危险源(并说明,如:物理危害.人为因素.自然因素.环境因素等现场问题)行 + // ============================================== + int wxNoteRow = sxNoteRow + 1; + Row wxRow = sheet.getRow(wxNoteRow); + if (wxRow == null) { + wxRow = sheet.createRow(wxNoteRow); + } + + // A-B列合并:现场是否存在危险源(并说明,如:物理危害.人为因素.自然因素.环境因素等现场问题) + CellRangeAddress wxTitleRegion = new CellRangeAddress(wxNoteRow, wxNoteRow, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, wxTitleRegion, "现场是否存在危险源(并说明,如:物理危害.人为因素.自然因素.环境因素等现场问题)", titleStyle); + drawBorderForRegion(sheet, wxTitleRegion, workbook); + + // C-M列合并:部分区域坡度较大。 + CellRangeAddress wxContentRegion = new CellRangeAddress(wxNoteRow, wxNoteRow, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, wxContentRegion, "部分区域坡度较大。", contentStyle); + drawBorderForRegion(sheet, wxContentRegion, workbook); + + wxRow.setHeightInPoints(30); // 适配可能的换行 + + // ============================================== + // 45. 现场施工照片行 + // ============================================== + + int photoRowNum = wxNoteRow + 1; + Row photoRow = sheet.getRow(photoRowNum); + if (photoRow == null) { + photoRow = sheet.createRow(photoRowNum); + } + + // C-H列合并:现场施工照片标题 + CellRangeAddress photoTitleRegion = new CellRangeAddress(photoRowNum, photoRowNum, 2 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, photoTitleRegion, "", titleStyle); + drawBorderForRegion(sheet, photoTitleRegion, workbook); + + // I-M列合并:图片展示区域 + CellRangeAddress photoImageRegion = new CellRangeAddress(photoRowNum, photoRowNum, 8 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, photoImageRegion, "", contentStyle); + drawBorderForRegion(sheet, photoImageRegion, workbook); + + photoRow.setHeightInPoints(200); // 设置较高行高以适应图片 + + // 插入图片到C-H区域 + if(paramData.getImgUrls1() != null && !paramData.getImgUrls1().isEmpty()){ + insertImageFromUrl(sheet, workbook, + paramData.getImgUrls1().getFirst(), + photoRowNum, photoRowNum + 1, 2 + columnOffset, 8 + columnOffset); + + } + + if(paramData.getImgUrls1() != null && paramData.getImgUrls1().size()>1){ + insertImageFromUrl(sheet, workbook, + paramData.getImgUrls1().getLast(), + photoRowNum, photoRowNum + 1, 8 + columnOffset, 13 + columnOffset); + + } + + // ============================================== + // 46. 照片名字行 + // ============================================== + int photoNameRowNum = photoRowNum + 1; + Row photoNameRow = sheet.getRow(photoNameRowNum); + if (photoNameRow == null) { + photoNameRow = sheet.createRow(photoNameRowNum); + } + + // A-B列合并:与上一行的A-B列合并(现场施工照片区域) + CellRangeAddress photoNameABRegion = new CellRangeAddress(photoRowNum, photoNameRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, photoNameABRegion, "现场施工照片", titleStyle); + drawBorderForRegion(sheet, photoNameABRegion, workbook); + + // C-H列合并:输入1#方阵组件安装 + CellRangeAddress photoName1Region = new CellRangeAddress(photoNameRowNum, photoNameRowNum, 2 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, photoName1Region, "1#", contentStyle); + drawBorderForRegion(sheet, photoName1Region, workbook); + + // I-M列合并:输入5#方阵支架安装 + CellRangeAddress photoName2Region = new CellRangeAddress(photoNameRowNum, photoNameRowNum, 8 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, photoName2Region, "2#", contentStyle); + drawBorderForRegion(sheet, photoName2Region, workbook); + + photoNameRow.setHeightInPoints(25); // 设置行高 + + // ============================================== + // 47. 现场施工照片行(第二组) + // ============================================== + int photoRowNum2 = photoNameRowNum + 1; + Row photoRow2 = sheet.getRow(photoRowNum2); + if (photoRow2 == null) { + photoRow2 = sheet.createRow(photoRowNum2); + } + + // C-H列合并:现场施工照片标题 + CellRangeAddress photoTitleRegion2 = new CellRangeAddress(photoRowNum2, photoRowNum2, 2 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, photoTitleRegion2, "", titleStyle); + drawBorderForRegion(sheet, photoTitleRegion2, workbook); + + // I-M列合并:图片展示区域 + CellRangeAddress photoImageRegion2 = new CellRangeAddress(photoRowNum2, photoRowNum2, 8 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, photoImageRegion2, "", contentStyle); + drawBorderForRegion(sheet, photoImageRegion2, workbook); + + photoRow2.setHeightInPoints(200); // 设置较高行高以适应图片 + + // 插入图片到C-H区域 + if(paramData.getImgUrls2() != null && !paramData.getImgUrls2().isEmpty()){ + insertImageFromUrl(sheet, workbook, + paramData.getImgUrls2().getFirst(), + photoRowNum, photoRowNum2 + 1, 2 + columnOffset, 8 + columnOffset); + + } + + if(paramData.getImgUrls2() != null && paramData.getImgUrls2().size()>1){ + insertImageFromUrl(sheet, workbook, + paramData.getImgUrls2().getLast(), + photoRowNum, photoRowNum2 + 1, 8 + columnOffset, 13 + columnOffset); + + } + +// // 插入图片到C-H区域 +// insertImageFromUrl(sheet, workbook, +// "http://xny.yj-3d.com:9000/xinnengyuan/2025/11/13/7cbef6181831427a8472ac1e9daafea4.png", +// photoRowNum2, photoRowNum2 + 1, 2 + columnOffset, 8 + columnOffset); +// +// // 可以添加第二个图片到I-M区域 +// insertImageFromUrl(sheet, workbook, +// "http://xny.yj-3d.com:9000/xinnengyuan/2025/11/13/7cbef6181831427a8472ac1e9daafea4.png", +// photoRowNum2, photoRowNum2 + 1, 8 + columnOffset, 13 + columnOffset); + + // ============================================== + // 48. 照片名字行(第二组) + // ============================================== + int photoNameRowNum2 = photoRowNum2 + 1; + Row photoNameRow2 = sheet.getRow(photoNameRowNum2); + if (photoNameRow2 == null) { + photoNameRow2 = sheet.createRow(photoNameRowNum2); + } + + // A-B列合并:与上一行的A-B列合并(现场施工照片区域) + CellRangeAddress photoNameABRegion2 = new CellRangeAddress(photoRowNum2, photoNameRowNum2, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, photoNameABRegion2, "现场施工照片", titleStyle); + drawBorderForRegion(sheet, photoNameABRegion2, workbook); + + // C-H列合并:输入2#方阵组件安装 + CellRangeAddress photoName3Region = new CellRangeAddress(photoNameRowNum2, photoNameRowNum2, 2 + columnOffset, 7 + columnOffset); + mergeAndFill(sheet, photoName3Region, "3#", contentStyle); + drawBorderForRegion(sheet, photoName3Region, workbook); + + // I-M列合并:输入3#方阵支架安装 + CellRangeAddress photoName4Region = new CellRangeAddress(photoNameRowNum2, photoNameRowNum2, 8 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, photoName4Region, "4#", contentStyle); + drawBorderForRegion(sheet, photoName4Region, workbook); + + photoNameRow2.setHeightInPoints(25); // 设置行高 + + + + // ============================================== + // 49. 明天工作计划 + // ============================================== + int tomorrowPlanRowNum = photoNameRowNum2 + 1; + Row tomorrowPlanRow = sheet.getRow(tomorrowPlanRowNum); + if (tomorrowPlanRow == null) { + tomorrowPlanRow = sheet.createRow(tomorrowPlanRowNum); + } + + // A-B列合并 + CellRangeAddress tomorrowABRegion = new CellRangeAddress(tomorrowPlanRowNum, tomorrowPlanRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, tomorrowABRegion, "明天工作计划", titleStyle); + drawBorderForRegion(sheet, tomorrowABRegion, workbook); + + // C-M列合并:输入工作计划内容 + String tomorrowPlanContent = "支架、组件安装37人,计划完成支架8组,组件7组;\n直流电缆敷设15人,计划完成3500米。"; + CellRangeAddress tomorrowContentRegion = new CellRangeAddress(tomorrowPlanRowNum, tomorrowPlanRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, tomorrowContentRegion, tomorrowPlanContent, contentStyle); + drawBorderForRegion(sheet, tomorrowContentRegion, workbook); + + tomorrowPlanRow.setHeightInPoints(40); // 设置行高以适应多行文本 + + // ============================================== + // 50. 其他事项 + // ============================================== + int otherMattersRowNum = tomorrowPlanRowNum + 1; + Row otherMattersRow = sheet.getRow(otherMattersRowNum); + if (otherMattersRow == null) { + otherMattersRow = sheet.createRow(otherMattersRowNum); + } + + // A-B列合并 + CellRangeAddress otherABRegion = new CellRangeAddress(otherMattersRowNum, otherMattersRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, otherABRegion, "其他事项", titleStyle); + drawBorderForRegion(sheet, otherABRegion, workbook); + + // C-M列合并 + CellRangeAddress otherContentRegion = new CellRangeAddress(otherMattersRowNum, otherMattersRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, otherContentRegion, "无", contentStyle); + drawBorderForRegion(sheet, otherContentRegion, workbook); + + otherMattersRow.setHeightInPoints(25); // 设置行高 + + // ============================================== + // 51. 现场人员 + // ============================================== + int sitePersonnelRowNum = otherMattersRowNum + 1; + Row sitePersonnelRow = sheet.getRow(sitePersonnelRowNum); + if (sitePersonnelRow == null) { + sitePersonnelRow = sheet.createRow(sitePersonnelRowNum); + } + + // A-B列合并 + CellRangeAddress personnelABRegion = new CellRangeAddress(sitePersonnelRowNum, sitePersonnelRowNum, 0 + columnOffset, 1 + columnOffset); + mergeAndFill(sheet, personnelABRegion, "现场人员", titleStyle); + drawBorderForRegion(sheet, personnelABRegion, workbook); + + // C-M列合并 + CellRangeAddress personnelContentRegion = new CellRangeAddress(sitePersonnelRowNum, sitePersonnelRowNum, 2 + columnOffset, 12 + columnOffset); + mergeAndFill(sheet, personnelContentRegion, "1.管理人员2人;\n" + + "2.支架、组件安装36人;\n" + + "3.直流电缆敷设15人;\n" + + "4.无人机飞手2人;\n" + + "5.合计55人。", contentStyle); + drawBorderForRegion(sheet, personnelContentRegion, workbook); + + sitePersonnelRow.setHeightInPoints(25); // 设置行高 + + // 调整内容行高 + for (int i = 1 + rowOffset; i <= 3 + rowOffset; i++) { + Row row = sheet.getRow(i); + if (row != null) { + row.setHeightInPoints(25); + } + } + + return sitePersonnelRowNum - rowOffset + 1; // 返回该项目使用的行数(相对于起始行) + } + + // 样式创建工具方法 + private static CellStyle createWrapTitleStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + font.setFontHeightInPoints((short) 14); + style.setFont(font); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setWrapText(true); + return style; + } + + private static CellStyle createTitleStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + style.setFont(font); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setWrapText(true); + return style; + } + + private static CellStyle createContentStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setWrapText(true); + return style; + } + + private static CellStyle createHeaderStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + style.setFont(font); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setWrapText(true); + return style; + } + + private static CellStyle createLeftHeaderStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setBold(true); + style.setFont(font); + style.setAlignment(HorizontalAlignment.LEFT); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setWrapText(true); + return style; + } + + // 合并单元格并填充内容 + private static void mergeAndFill(Sheet sheet, CellRangeAddress region, String value, CellStyle style) { + int rowNum = region.getFirstRow(); + int colNum = region.getFirstColumn(); + Row row = sheet.getRow(rowNum); + if (row == null) { + row = sheet.createRow(rowNum); + } + Cell cell = row.createCell(colNum); + cell.setCellValue(value); + cell.setCellStyle(style); + sheet.addMergedRegion(region); + } + + // 为合并区域绘制边框 + private static void drawBorderForRegion(Sheet sheet, CellRangeAddress region, Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + style.setBorderTop(BorderStyle.THIN); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + + RegionUtil.setBorderTop(BorderStyle.THIN, region, sheet); + RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet); + RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet); + RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet); + } + + // 为单个单元格绘制边框 + private static void drawBorderForCell(Sheet sheet, int rowNum, int firstCol, int lastCol, Workbook workbook) { + CellRangeAddress region = new CellRangeAddress(rowNum, rowNum, firstCol, lastCol); + drawBorderForRegion(sheet, region, workbook); + } + + /** + * 从URL下载图片并插入到指定区域 + */ + private static void insertImageFromUrl(Sheet sheet, Workbook workbook, String imageUrl, + int firstRow, int lastRow, int firstCol, int lastCol) { + try { + // 下载图片数据 + URL url = new URL(imageUrl); + try (InputStream inputStream = url.openStream()) { + byte[] imageBytes = IOUtils.toByteArray(inputStream); + + // 确定图片类型 + int pictureType = Workbook.PICTURE_TYPE_PNG; + if (imageUrl.toLowerCase().endsWith(".jpg") || imageUrl.toLowerCase().endsWith(".jpeg")) { + pictureType = Workbook.PICTURE_TYPE_JPEG; + } + + // 将图片添加到工作簿 + int pictureIdx = workbook.addPicture(imageBytes, pictureType); + + // 创建绘图对象 + Drawing drawing = sheet.createDrawingPatriarch(); + + // 创建锚点 + CreationHelper helper = workbook.getCreationHelper(); + ClientAnchor anchor = helper.createClientAnchor(); + anchor.setCol1(firstCol); + anchor.setCol2(lastCol); + anchor.setRow1(firstRow); + anchor.setRow2(lastRow); + + // 插入图片 + drawing.createPicture(anchor, pictureIdx); + + System.out.println("成功插入图片: " + imageUrl); + } + } catch (Exception e) { + System.err.println("插入图片失败: " + e.getMessage()); + // 如果插入失败,在单元格中显示错误信息 + Row row = sheet.getRow(firstRow); + if (row == null) row = sheet.createRow(firstRow); + Cell cell = row.createCell(firstCol); + cell.setCellValue("图片加载失败"); + } + } + + + + + //数据组装 + public static List getProjectDataList(PgsProgressCategoryDayTotalVo totalVo) { + + List projectDataList = new ArrayList<>(); + List subProjectList = totalVo.getSubProjectList(); + int maxPhotovoltaicAreaLength = getMaxPhotovoltaicAreaLength(subProjectList); + for (PgsProgressCategoryByDayVo vo : subProjectList) { + ProjectData projectData = new ProjectData(); + projectData.setProjectName(vo.getProjectName()); + List progressList = new ArrayList<>(); + + List photovoltaicArea = vo.getPhotovoltaicArea(); + int num = 1; + for (PgsProgressCategoryDetailByDayVo vo1 : photovoltaicArea) { + ProgressData progressData = new ProgressData(); + progressData.setNum(num); + progressData.setProject(vo1.getName()+"("+vo1.getUnit()+")"); + progressData.setDesign(vo1.getTotal().toString()); + progressData.setPlan(vo1.getConstructionPlan().toString()); + progressData.setComplete(vo1.getConstructionCompleted().toString()); + progressData.setTotal(vo1.getCompleted().toString()); + progressData.setProcess(vo1.getCompletedPercentage().toString()); + progressList.add(progressData); + num++; + } + if(photovoltaicArea.size() < maxPhotovoltaicAreaLength){ + for (int i = 0; i < maxPhotovoltaicAreaLength - photovoltaicArea.size(); i++) { + ProgressData progressData = new ProgressData(); + progressData.setNum(num); + progressData.setProject(""); + progressData.setDesign(""); + progressData.setPlan(""); + progressData.setComplete(""); + progressData.setTotal(""); + progressData.setProcess(""); + progressList.add(progressData); + } + } + projectData.setProgressList(progressList); + + List participantList= new ArrayList<>(); + List equipmentEntryList= new ArrayList<>(); + List materialList= new ArrayList<>(); + List inspectionList= new ArrayList<>(); + participantList.add(new ParticipantData("", "","", "","")); + equipmentEntryList.add(new EquipmentEntryData("","","","","","","")); + materialList.add(new MaterialEntryData("","","","","")); + inspectionList.add(new MaterialInspectionData("","","","","")); + + projectData.setParticipantList(participantList); + projectData.setEquipmentEntryList(equipmentEntryList); + projectData.setMaterialList(materialList); + projectData.setInspectionList(inspectionList); + + System.out.println(projectData); + + projectDataList.add(projectData); + } + + return projectDataList; + } + + public static int getMaxPhotovoltaicAreaLength(List subProjectList) { + // 初始化最大值为0(若所有项目的photovoltaicArea都为null,结果为0) + int maxLength = 0; + + if (subProjectList == null) { + return maxLength; // 集合为null时返回0 + } + + for (PgsProgressCategoryByDayVo project : subProjectList) { + // 获取当前项目的photovoltaicArea + List pvArea = project.getPhotovoltaicArea(); + + // 计算当前photovoltaicArea的长度(为null时按0处理) + int currentLength = (pvArea == null) ? 0 : pvArea.size(); + + // 更新最大值 + if (currentLength > maxLength) { + maxLength = currentLength; + } + } + + return maxLength; + } + + + + public ParamData getParamData(ReportExportDto dto){ + ParamData paramData = new ParamData(); + String originalDate = dto.getDate(); + // 解析原始字符串为Date对象,再格式化为目标字符串 + LocalDate localDate = DateUtils.parseLocalDateTime(FormatsType.YYYY_MM_DD, originalDate); + String format = LocalDateTimeUtil.format(localDate, "yyyy年-MM月-dd日"); + + + BusProject project = projectService.getById(dto.getProjectId()); + + List list = qltQualityInspectionService.lambdaQuery() + .eq(QltQualityInspection::getProjectId, project.getId()) + .between(QltQualityInspection::getCreateTime, localDate.atStartOfDay(), localDate.atTime(23, 59, 59)) + .orderByDesc(QltQualityInspection::getCreateTime) + .list(); + + List list1 = safetyInspectionService.lambdaQuery() + .eq(HseSafetyInspection::getProjectId, project.getId()) + .between(HseSafetyInspection::getCheckTime, localDate.atStartOfDay(), localDate.atTime(23, 59, 59)) + .orderByDesc(HseSafetyInspection::getCreateTime) + .list(); + + //查找图片 + List qltImgList = new ArrayList<>(); + List list2 = list.stream().map(QltQualityInspection::getInspectionImgFile).toList(); + for (String s : list2) { + if (s != null && !s.isEmpty()) { + String[] split = s.split(","); + //转成Long + List longs = Arrays.stream(split).map(Long::valueOf).toList(); + qltImgList.addAll(longs); + } + } + + List hseImgList = new ArrayList<>(); + List list3 = list1.stream().map(HseSafetyInspection::getCheckFile).toList(); + for (String s : list3) { + if (s != null && !s.isEmpty()) { + String[] split = s.split(","); + //转成Long + List longs = Arrays.stream(split).map(Long::valueOf).toList(); + hseImgList.addAll(longs); + } + } + List imgUrls1 = new ArrayList<>(); + if(CollectionUtil.isNotEmpty(qltImgList)){ + List sysOssVos = ossService.listByIds(qltImgList); + for (SysOssVo sysOssVo : sysOssVos){ + if(!IMAGE_SUFFIX.contains(sysOssVo.getFileSuffix())){ + continue; + } + imgUrls1.add(sysOssVo.getUrl()); + } + paramData.setImgUrls1(imgUrls1); + } + + List imgUrls2 = new ArrayList<>(); + if(CollectionUtil.isNotEmpty(hseImgList)){ + List sysOssVos = ossService.listByIds(hseImgList); + for (SysOssVo sysOssVo : sysOssVos){ + if(!IMAGE_SUFFIX.contains(sysOssVo.getFileSuffix())){ + continue; + } + imgUrls2.add(sysOssVo.getUrl()); + } + paramData.setImgUrls2(imgUrls2); + } + List weatherList = weatherManager.getWeatherListVo(project.getLng(), project.getLat(), WeatherConstant.THREE_DAYS_WEATHER_PATH); + WeatherVo first = weatherList.getFirst(); + + paramData.setDate(format); + paramData.setRecorder(dto.getPerson()); + if(first != null){ + paramData.setTemp(first.getTempMin()+ "℃~"+ first.getTempMax() + "℃"); + paramData.setDayWeather(first.getDayStatus()); + paramData.setNightWeather(first.getNightStatus()); + } + if(CollectionUtil.isNotEmpty(list)){ + String collect = list.stream().map(QltQualityInspection::getInspectionResult).collect(Collectors.joining(",")); + paramData.setQuality(collect); + } + if(CollectionUtil.isNotEmpty(list1)){ + String collect = list1.stream().map(HseSafetyInspection::getInspectionResult).collect(Collectors.joining(",")); + paramData.setSafety(collect); + } + + return paramData; + } + + + + // 新的数据组装方法,将数据按行组织 + public static List> getProjectDataListAsRows(PgsProgressCategoryDayTotalVo totalVo) { + List> result = new ArrayList<>(); + + if (totalVo != null && totalVo.getSubProjectList() != null) { + List rowProjects = new ArrayList<>(); + + // 将所有项目放在同一行中 + List subProjectList = totalVo.getSubProjectList(); + int maxPhotovoltaicAreaLength = getMaxPhotovoltaicAreaLength(subProjectList); + + for (PgsProgressCategoryByDayVo vo : subProjectList) { + ProjectData projectData = new ProjectData(); + projectData.setProjectName(vo.getProjectName()); + List progressList = new ArrayList<>(); + + List photovoltaicArea = vo.getPhotovoltaicArea(); + int num = 1; + for (PgsProgressCategoryDetailByDayVo vo1 : photovoltaicArea) { + ProgressData progressData = new ProgressData(); + progressData.setNum(num); + progressData.setProject(vo1.getName()+"("+vo1.getUnit()+")"); + progressData.setDesign(vo1.getTotal().toString()); + progressData.setPlan(vo1.getConstructionPlan().toString()); + progressData.setComplete(vo1.getConstructionCompleted().toString()); + progressData.setTotal(vo1.getCompleted().toString()); + progressData.setProcess(vo1.getCompletedPercentage().toString()); + progressList.add(progressData); + num++; + } + + if(photovoltaicArea.size() < maxPhotovoltaicAreaLength){ + for (int i = 0; i < maxPhotovoltaicAreaLength - photovoltaicArea.size(); i++) { + ProgressData progressData = new ProgressData(); + progressData.setNum(num); + progressData.setProject(""); + progressData.setDesign(""); + progressData.setPlan(""); + progressData.setComplete(""); + progressData.setTotal(""); + progressData.setProcess(""); + progressList.add(progressData); + } + } + projectData.setProgressList(progressList); + + List participantList= new ArrayList<>(); + List equipmentEntryList= new ArrayList<>(); + List materialList= new ArrayList<>(); + List inspectionList= new ArrayList<>(); + participantList.add(new ParticipantData("", "","", "","")); + equipmentEntryList.add(new EquipmentEntryData("","","","","","","")); + materialList.add(new MaterialEntryData("","","","","")); + inspectionList.add(new MaterialInspectionData("","","","","")); + + projectData.setParticipantList(participantList); + projectData.setEquipmentEntryList(equipmentEntryList); + projectData.setMaterialList(materialList); + projectData.setInspectionList(inspectionList); + + rowProjects.add(projectData); + } + + // 将所有项目作为一行添加到结果中 + result.add(rowProjects); + } + if (totalVo != null && totalVo.getProject() != null) { + + PgsProgressCategoryByDayVo project = totalVo.getProject(); + + //升压站 + List sy = new ArrayList<>(); + ProjectData projectData = new ProjectData(); + projectData.setProjectName("升压站"); + List progressList = new ArrayList<>(); + + List boosterStation = project.getBoosterStation(); + int num = 1; + for (PgsProgressCategoryDetailByDayVo vo1 : boosterStation) { + ProgressData progressData = new ProgressData(); + progressData.setNum(num); + progressData.setProject(vo1.getName()+"("+vo1.getUnit()+")"); + progressData.setDesign(vo1.getTotal().toString()); + progressData.setPlan(vo1.getConstructionPlan().toString()); + progressData.setComplete(vo1.getConstructionCompleted().toString()); + progressData.setTotal(vo1.getCompleted().toString()); + progressData.setProcess(vo1.getCompletedPercentage().toString()); + progressList.add(progressData); + num++; + } + projectData.setProgressList(progressList); + + List participantList= new ArrayList<>(); + List equipmentEntryList= new ArrayList<>(); + List materialList= new ArrayList<>(); + List inspectionList= new ArrayList<>(); + participantList.add(new ParticipantData("", "","", "","")); + equipmentEntryList.add(new EquipmentEntryData("","","","","","","")); + materialList.add(new MaterialEntryData("","","","","")); + inspectionList.add(new MaterialInspectionData("","","","","")); + + projectData.setParticipantList(participantList); + projectData.setEquipmentEntryList(equipmentEntryList); + projectData.setMaterialList(materialList); + projectData.setInspectionList(inspectionList); + + sy.add(projectData); + result.add(sy); + + //集电线路 + List jd = new ArrayList<>(); + ProjectData jdProjectData = new ProjectData(); + jdProjectData.setProjectName("集电线路"); + List jdProgressList = new ArrayList<>(); + + List collectingLine = project.getCollectingLine(); + int jdNum = 1; + for (PgsProgressCategoryDetailByDayVo vo1 : collectingLine) { + ProgressData progressData = new ProgressData(); + progressData.setNum(jdNum); + progressData.setProject(vo1.getName()+"("+vo1.getUnit()+")"); + progressData.setDesign(vo1.getTotal().toString()); + progressData.setPlan(vo1.getConstructionPlan().toString()); + progressData.setComplete(vo1.getConstructionCompleted().toString()); + progressData.setTotal(vo1.getCompleted().toString()); + progressData.setProcess(vo1.getCompletedPercentage().toString()); + jdProgressList.add(progressData); + jdNum++; + } + projectData.setProgressList(jdProgressList); + + List jdParticipantList= new ArrayList<>(); + List jdEquipmentEntryList= new ArrayList<>(); + List jdMaterialList= new ArrayList<>(); + List jdInspectionList= new ArrayList<>(); + jdParticipantList.add(new ParticipantData("", "","", "","")); + jdEquipmentEntryList.add(new EquipmentEntryData("","","","","","","")); + jdMaterialList.add(new MaterialEntryData("","","","","")); + jdInspectionList.add(new MaterialInspectionData("","","","","")); + + projectData.setParticipantList(jdParticipantList); + projectData.setEquipmentEntryList(jdEquipmentEntryList); + projectData.setMaterialList(jdMaterialList); + projectData.setInspectionList(jdInspectionList); + + jd.add(jdProjectData); + result.add(jd); + + //送出线路 + List sc = new ArrayList<>(); + ProjectData scProjectData = new ProjectData(); + scProjectData.setProjectName("送出线路"); + List scProgressList = new ArrayList<>(); + + List sendLine = project.getSendLine(); + int scNum = 1; + for (PgsProgressCategoryDetailByDayVo vo1 : sendLine) { + ProgressData progressData = new ProgressData(); + progressData.setNum(scNum); + progressData.setProject(vo1.getName()+"("+vo1.getUnit()+")"); + progressData.setDesign(vo1.getTotal().toString()); + progressData.setPlan(vo1.getConstructionPlan().toString()); + progressData.setComplete(vo1.getConstructionCompleted().toString()); + progressData.setTotal(vo1.getCompleted().toString()); + progressData.setProcess(vo1.getCompletedPercentage().toString()); + scProgressList.add(progressData); + scNum++; + } + projectData.setProgressList(scProgressList); + + List scParticipantList= new ArrayList<>(); + List scEquipmentEntryList= new ArrayList<>(); + List scMaterialList= new ArrayList<>(); + List scInspectionList= new ArrayList<>(); + scParticipantList.add(new ParticipantData("", "","", "","")); + scEquipmentEntryList.add(new EquipmentEntryData("","","","","","","")); + scMaterialList.add(new MaterialEntryData("","","","","")); + scInspectionList.add(new MaterialInspectionData("","","","","")); + + projectData.setParticipantList(scParticipantList); + projectData.setEquipmentEntryList(scEquipmentEntryList); + projectData.setMaterialList(scMaterialList); + projectData.setInspectionList(scInspectionList); + + sc.add(scProjectData); + result.add(sc); + + //其他工程 + List qt = new ArrayList<>(); + ProjectData qtProjectData = new ProjectData(); + qtProjectData.setProjectName("其他工程"); + List qtProgressList = new ArrayList<>(); + + List otherProject = project.getOtherProject(); + int qtNum = 1; + for (PgsProgressCategoryDetailByDayVo vo1 : otherProject) { + ProgressData progressData = new ProgressData(); + progressData.setNum(qtNum); + progressData.setProject(vo1.getName()+"("+vo1.getUnit()+")"); + progressData.setDesign(vo1.getTotal().toString()); + progressData.setPlan(vo1.getConstructionPlan().toString()); + progressData.setComplete(vo1.getConstructionCompleted().toString()); + progressData.setTotal(vo1.getCompleted().toString()); + progressData.setProcess(vo1.getCompletedPercentage().toString()); + qtProgressList.add(progressData); + qtNum++; + } + projectData.setProgressList(qtProgressList); + + List qtParticipantList= new ArrayList<>(); + List qtEquipmentEntryList= new ArrayList<>(); + List qtMaterialList= new ArrayList<>(); + List qtInspectionList= new ArrayList<>(); + qtParticipantList.add(new ParticipantData("", "","", "","")); + qtEquipmentEntryList.add(new EquipmentEntryData("","","","","","","")); + qtMaterialList.add(new MaterialEntryData("","","","","")); + qtInspectionList.add(new MaterialInspectionData("","","","","")); + + projectData.setParticipantList(qtParticipantList); + projectData.setEquipmentEntryList(qtEquipmentEntryList); + projectData.setMaterialList(qtMaterialList); + projectData.setInspectionList(qtInspectionList); + + qt.add(qtProjectData); + result.add(qt); + + + } + + return result; + } + + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/export/ReportExportDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/export/ReportExportDto.java new file mode 100644 index 00000000..1e1a6092 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/dto/export/ReportExportDto.java @@ -0,0 +1,16 @@ +package org.dromara.progress.domain.dto.export; + + +import lombok.Data; + +@Data +public class ReportExportDto { + private Long projectId; + + /** + * 日期 yyyy-mm-dd + */ + private String date; + + private String person; +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/EquipmentEntryData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/EquipmentEntryData.java new file mode 100644 index 00000000..3228664e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/EquipmentEntryData.java @@ -0,0 +1,32 @@ +package org.dromara.progress.domain.vo.export; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EquipmentEntryData { + private String no; // 序号 + private String project; // 项目 + private String num; // 数量 + private String production; // 生产情况 + private String entry; // 今日进场情况 + private String totalEntry; // 累计进场情况 + private String remark; // 备注 + + + // 生成模拟数据 + public static List generateMockData() { + List dataList = new ArrayList<>(); + dataList.add(new EquipmentEntryData("1", "光伏支架", "3200组", "正常生产", "50组", "1200组", "符合质量标准")); + dataList.add(new EquipmentEntryData("2", "光伏组件", "56000块", "正常生产", "750块", "22000块", "符合质量标准")); + dataList.add(new EquipmentEntryData("3", "逆变器", "30台", "生产中", "0台", "10台", "预计下周进场")); + return dataList; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialEntryData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialEntryData.java new file mode 100644 index 00000000..85a1efd0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialEntryData.java @@ -0,0 +1,31 @@ +package org.dromara.progress.domain.vo.export; + + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MaterialEntryData { + private String no; // 序号 + private String materialName;// 材料名称 + private String designValue; // 设计值 + private String entryStatus; // 进场情况 + private String inspection; // 送检记录 + + // 生成模拟数据 + public static List generateMockData() { + List dataList = new ArrayList<>(); + dataList.add(new MaterialEntryData("1", "光伏电缆", "5000米", "今日进场1000米,累计3000米", "已送检,合格")); + dataList.add(new MaterialEntryData("2", "水泥", "200吨", "今日进场50吨,累计150吨", "已送检,合格")); + dataList.add(new MaterialEntryData("3", "钢筋", "100吨", "未进场,预计明日到货", "待送检")); + dataList.add(new MaterialEntryData("4", "预埋件", "2000个", "今日进场500个,累计1500个", "已送检,合格")); + return dataList; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialInspectionData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialInspectionData.java new file mode 100644 index 00000000..45d09b97 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/MaterialInspectionData.java @@ -0,0 +1,32 @@ +package org.dromara.progress.domain.vo.export; + + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MaterialInspectionData { + private String no; // 序号 + private String materialName;// 材料名称 + private String usePart; // 用材部位 + private String inspectionOrg; // 送检机构 + private String inspectionRecord; // 送检记录 + + + // 生成模拟数据 + public static List generateMockData() { + List dataList = new ArrayList<>(); + dataList.add(new MaterialInspectionData("1", "光伏电缆", "方阵连接", "广西质检中心", "2025-11-05送检,2025-11-06合格")); + dataList.add(new MaterialInspectionData("2", "水泥", "基础浇筑", "百色市质检所", "2025-11-04送检,2025-11-05合格")); + dataList.add(new MaterialInspectionData("3", "钢筋", "支架固定", "广西质检中心", "待送检,预计2025-11-08送检")); + dataList.add(new MaterialInspectionData("4", "预埋件", "基础连接", "百色市质检所", "2025-11-03送检,2025-11-04合格")); + return dataList; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParamData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParamData.java new file mode 100644 index 00000000..aefe4a72 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParamData.java @@ -0,0 +1,58 @@ +package org.dromara.progress.domain.vo.export; + +import lombok.Data; + +import java.util.List; + +@Data +public class ParamData { + + /** + * 项目简介 + */ + private String projectIntro; + + /** + * 记录人 + */ + private String date; + + /** + * 记录人 + */ + private String recorder; + + /** + * 气温 + */ + private String temp; + /** + * 白天天气 + */ + private String dayWeather; + /** + * 夜晚天气 + */ + private String nightWeather; + /** + * 现场质量 + */ + private String quality = "质量正常.可控。"; + /** + * 现场安全 + */ + private String safety = "安全正常.可控。"; + + /** + * 图片地址 + */ + private List imgUrls1; + + /** + * 图片地址 + */ + private List imgUrls2; + + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParticipantData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParticipantData.java new file mode 100644 index 00000000..21593beb --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ParticipantData.java @@ -0,0 +1,30 @@ +package org.dromara.progress.domain.vo.export; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ParticipantData { + private String unit; // 参建单位 + private String leader; // 经理班子人员 + private String manager; // 主要管理技术人员 + private String other; // 其他人员 + private String remark; // 备注 + + + // 生成模拟数据 + public static List generateMockData() { + List dataList = new ArrayList<>(); + dataList.add(new ParticipantData("田东公司项目建设管理部", "3人", "8人", "12人", "正常")); + dataList.add(new ParticipantData("XX施工单位", "2人", "5人", "30人", "部分人员轮休")); + dataList.add(new ParticipantData("XX监理单位", "1人", "2人", "0人", "正常")); + return dataList; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProgressData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProgressData.java new file mode 100644 index 00000000..65b6691e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProgressData.java @@ -0,0 +1,34 @@ +package org.dromara.progress.domain.vo.export; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ProgressData { + private int num; // 序号 + private String project; // 项目 + private String design; // 设计值 + private String plan; // 今日施工计划 + private String complete; // 今日施工完成情况 + private String total; // 累计完成工程量 + private String process; // 施工形象及进度 + + + + public static List generateMockData() { + List dataList = new ArrayList<>(); + dataList.add(new ProgressData(1, "土地流转(亩)", "217.36", "50", "45", "180", "已完成82.8%")); + dataList.add(new ProgressData(2, "清表(亩)", "217.36", "40", "38", "150", "已完成69%")); + dataList.add(new ProgressData(3, "支架安装(组)", "3200", "50", "45", "1200", "已完成37.5%")); + dataList.add(new ProgressData(4, "组件安装(块)", "56000", "800", "750", "22000", "已完成39.3%")); + return dataList; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProjectData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProjectData.java new file mode 100644 index 00000000..6a2562e0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/export/ProjectData.java @@ -0,0 +1,23 @@ +// ProjectData.java +package org.dromara.progress.domain.vo.export; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ProjectData { + private List progressList; + private List participantList; + private List equipmentEntryList; + private List materialList; + private List inspectionList; + private String projectName; // 项目名称 + private String projectDate; // 项目日期 + +} + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseViolationRecord.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseViolationRecord.java index 0af19df4..52fd80eb 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseViolationRecord.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseViolationRecord.java @@ -125,4 +125,25 @@ public class HseViolationRecord extends BaseEntity { */ private String remark; + + /** + * 任务批号 + */ + private String jobKey; + + /** + * 任务批号 + */ + private Integer version; + + /** + * 验证人id + */ + private Long validatorId; + + /** + * 验证人名字 + */ + private String validatorName; + } From 073f704c0e17c05a6d15cc7c2b4d047fb36aa51f Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 17 Nov 2025 16:39:15 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E8=AF=A6=E6=83=85=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../XzdBidDepositRecoveryController.java | 28 ++++++++ .../XzdSubcontractChangeController.java | 13 ++++ .../controller/XzdSubcontractController.java | 57 +++++++++++++++ .../XzdSubcontractTerminationController.java | 15 ++++ ...PurchaseContractInformationController.java | 56 +++++++++++++++ .../XzdContractDetailsController.java | 4 ++ .../xzd/controller/XzdCorrespondentList.java | 9 +++ .../dromara/xzd/domain/vo/XzdProjectVo.java | 4 ++ .../xzd/publicUrl/XzdPublicUrlConreoller.java | 64 +++++++++++++---- .../xzd/service/IXzdProjectService.java | 9 +++ .../service/impl/XzdProjectServiceImpl.java | 8 +++ ...entOfSubcontractingContractController.java | 13 ++++ ...tOfSubcontractingCompletionController.java | 13 ++++ ...tOfSubcontractingAdjustmentController.java | 12 ++++ ...ancialRevenuePlanAlterationController.java | 70 +++++++++++++++++++ ...ncialRevenueExpenditurePlanController.java | 56 +++++++++++++++ 16 files changed, 417 insertions(+), 14 deletions(-) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/biddingManagement/earnestMoneyWithdraw/controller/XzdBidDepositRecoveryController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/biddingManagement/earnestMoneyWithdraw/controller/XzdBidDepositRecoveryController.java index 4cb9e8b5..4fd65b3d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/biddingManagement/earnestMoneyWithdraw/controller/XzdBidDepositRecoveryController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/biddingManagement/earnestMoneyWithdraw/controller/XzdBidDepositRecoveryController.java @@ -10,6 +10,10 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import org.dromara.xzd.biddingManagement.biaoqianlixiang.domain.dto.QuerBiddingManagementDto; import org.dromara.xzd.biddingManagement.biaoqianlixiang.domain.vo.QueryListXzdVo; import org.dromara.xzd.biddingManagement.biaoqianlixiang.service.IXzdBidPreProjectService; +import org.dromara.xzd.biddingManagement.earnestMoney.domain.bo.XzdBidDepositPaymentBo; +import org.dromara.xzd.biddingManagement.earnestMoney.domain.vo.XzdBidDepositPaymentByBqlx; +import org.dromara.xzd.biddingManagement.earnestMoney.domain.vo.XzdBidDepositPaymentVo; +import org.dromara.xzd.biddingManagement.earnestMoney.service.IXzdBidDepositPaymentService; import org.dromara.xzd.biddingManagement.earnestMoneyWithdraw.domain.bo.XzdBidDepositRecoveryBo; import org.dromara.xzd.biddingManagement.earnestMoneyWithdraw.domain.vo.XzdBidDepositRecoveryVo; import org.dromara.xzd.biddingManagement.earnestMoneyWithdraw.domain.vo.XzdBidDepositRecoveryXqVo; @@ -43,6 +47,8 @@ public class XzdBidDepositRecoveryController extends BaseController { private final IXzdBidDepositRecoveryService xzdBidDepositRecoveryService; private final IXzdBidPreProjectService xzdBidPreProjectService; + private final IXzdBidDepositPaymentService xzdBidDepositPaymentService; + /** * 查询投标保证金收回列表 @@ -119,4 +125,26 @@ public class XzdBidDepositRecoveryController extends BaseController { public QueryListXzdVo list(QuerBiddingManagementDto bo, PageQuery pageQuery) { return xzdBidPreProjectService.queryPageList(bo, pageQuery); } + + /** + * 查询投标保证金缴纳列表 + */ + @SaCheckPermission(value = {"biddingManagement:bidDepositRecovery:list","biddingManagement:bidDepositRecovery:add","biddingManagement:bidDepositRecovery:edit"},mode = SaMode.OR) + @GetMapping("/getxzdBidDepositPayment") + public TableDataInfo list(XzdBidDepositPaymentBo bo, PageQuery pageQuery) { + return xzdBidDepositPaymentService.queryPageList(bo, pageQuery); + } + + /** + * 获取投标保证金缴纳详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"biddingManagement:bidDepositRecovery:list","biddingManagement:bidDepositRecovery:add","biddingManagement:bidDepositRecovery:edit"},mode = SaMode.OR) + @GetMapping("/get/{id}") + public R getInfoxzdBidDeposit(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdBidDepositPaymentService.queryById(id)); + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongbiangg/controller/XzdSubcontractChangeController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongbiangg/controller/XzdSubcontractChangeController.java index a19f39e8..cf379d0e 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongbiangg/controller/XzdSubcontractChangeController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongbiangg/controller/XzdSubcontractChangeController.java @@ -138,6 +138,19 @@ public class XzdSubcontractChangeController extends BaseController { } + /** + * 获取分包合同信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value={"fenbaohetongbiangg:subcontractChange:list","fenbaohetongbiangg:subcontractChange:add","fenbaohetongbiangg:subcontractChange:edit"}, mode = SaMode.OR) + @GetMapping("/xx/{id}") + public R getInfoxx(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSubcontractService.queryById(id)); + } + + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongxinxi/controller/XzdSubcontractController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongxinxi/controller/XzdSubcontractController.java index 1b850419..311e47cc 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongxinxi/controller/XzdSubcontractController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongxinxi/controller/XzdSubcontractController.java @@ -7,10 +7,17 @@ import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.xzd.contractManagement.fenbaohetongbiangg.domain.bo.XzdSubcontractChangeBo; +import org.dromara.xzd.contractManagement.fenbaohetongbiangg.domain.vo.XzdSubcontractChangeVo; +import org.dromara.xzd.contractManagement.fenbaohetongbiangg.service.IXzdSubcontractChangeService; import org.dromara.xzd.contractManagement.fenbaohetongxinxi.domain.vo.XzdJdztVo; +import org.dromara.xzd.contractManagement.fenbaohetongzhongzhi.domain.bo.XzdSubcontractTerminationBo; +import org.dromara.xzd.contractManagement.fenbaohetongzhongzhi.domain.vo.XzdSubcontractTerminationVo; +import org.dromara.xzd.contractManagement.fenbaohetongzhongzhi.service.IXzdSubcontractTerminationService; import org.dromara.xzd.domain.bo.XzdBusinessSealBo; import org.dromara.xzd.domain.vo.XzdBusinessSealVo; import org.dromara.xzd.service.IXzdBusinessSealService; +import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -43,6 +50,56 @@ public class XzdSubcontractController extends BaseController { private final IXzdBusinessSealService xzdBusinessSealService; + @Lazy + private final IXzdSubcontractChangeService xzdSubcontractChangeService; + + @Lazy + private final IXzdSubcontractTerminationService xzdSubcontractTerminationService; + + + /** + * 查询分包合同终止列表 + */ + @SaCheckPermission(value={"fenbaohetongxinxi:subcontract:list","fenbaohetongxinxi:subcontract:add","fenbaohetongxinxi:subcontract:edit"}, mode = SaMode.OR) + @GetMapping("/listzz") + public TableDataInfo list(XzdSubcontractTerminationBo bo, PageQuery pageQuery) { + return xzdSubcontractTerminationService.queryPageList(bo, pageQuery); + } + + /** + * 查询分包合同变更列表 + */ + @SaCheckPermission(value={"fenbaohetongxinxi:subcontract:list","fenbaohetongxinxi:subcontract:add","fenbaohetongxinxi:subcontract:edit"}, mode = SaMode.OR) + @GetMapping("/listbg") + public TableDataInfo list(XzdSubcontractChangeBo bo, PageQuery pageQuery) { + return xzdSubcontractChangeService.queryPageList(bo, pageQuery); + } + + + /** + * 获取分包合同变更详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value={"fenbaohetongxinxi:subcontract:list","fenbaohetongxinxi:subcontract:add","fenbaohetongxinxi:subcontract:edit"}, mode = SaMode.OR) + @GetMapping("/bg/{id}") + public R getInfobg(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSubcontractChangeService.queryById(id)); + } + + /** + * 获取分包合同终止详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value={"fenbaohetongxinxi:subcontract:list","fenbaohetongxinxi:subcontract:add","fenbaohetongxinxi:subcontract:edit"}, mode = SaMode.OR) + @GetMapping("/zz/{id}") + public R getInfozz(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSubcontractTerminationService.queryById(id)); + } + /** * 查询印章帮助列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongzhongzhi/controller/XzdSubcontractTerminationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongzhongzhi/controller/XzdSubcontractTerminationController.java index f9c8249d..b1345d43 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongzhongzhi/controller/XzdSubcontractTerminationController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/fenbaohetongzhongzhi/controller/XzdSubcontractTerminationController.java @@ -134,4 +134,19 @@ public class XzdSubcontractTerminationController extends BaseController { public TableDataInfo list(XzdSubcontractBo bo, PageQuery pageQuery) { return xzdSubcontractService.queryPageList(bo, pageQuery); } + + /** + * 获取分包合同信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value={"fenbaohetongzhongzhi:subcontractTermination:list","fenbaohetongzhongzhi:subcontractTermination:add","fenbaohetongzhongzhi:subcontractTermination:edit"}, mode = SaMode.OR) + @GetMapping("/xx/{id}") + public R getInfoxx(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSubcontractService.queryById(id)); + } + + + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/purchaseManagement/controller/XzdPurchaseContractInformationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/purchaseManagement/controller/XzdPurchaseContractInformationController.java index 91df40e9..8c301bd5 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/purchaseManagement/controller/XzdPurchaseContractInformationController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/contractManagement/purchaseManagement/controller/XzdPurchaseContractInformationController.java @@ -7,6 +7,12 @@ import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.xzd.contractManagement.caigoucontractTermination.domain.bo.XzdPurchaseContractSuspendBo; +import org.dromara.xzd.contractManagement.caigoucontractTermination.domain.vo.XzdPurchaseContractSuspendVo; +import org.dromara.xzd.contractManagement.caigoucontractTermination.service.IXzdPurchaseContractSuspendService; +import org.dromara.xzd.contractManagement.caigouhetongbiangeng.domain.bo.XzdPurchaseContractAlterationBo; +import org.dromara.xzd.contractManagement.caigouhetongbiangeng.domain.vo.XzdPurchaseContractAlterationVo; +import org.dromara.xzd.contractManagement.caigouhetongbiangeng.service.IXzdPurchaseContractAlterationService; import org.dromara.xzd.contractManagement.fenbaohetongxinxi.domain.vo.XzdJdztVo; import org.dromara.xzd.contractManagement.purchaseManagement.domain.bo.XzdPurchaseContractInformationBo; import org.dromara.xzd.contractManagement.purchaseManagement.domain.vo.XzdJdztCghtVo; @@ -15,6 +21,7 @@ import org.dromara.xzd.contractManagement.purchaseManagement.service.IXzdPurchas import org.dromara.xzd.domain.bo.XzdBusinessSealBo; import org.dromara.xzd.domain.vo.XzdBusinessSealVo; import org.dromara.xzd.service.IXzdBusinessSealService; +import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -45,6 +52,55 @@ public class XzdPurchaseContractInformationController extends BaseController { private final IXzdBusinessSealService xzdBusinessSealService; + @Lazy + private final IXzdPurchaseContractAlterationService xzdPurchaseContractAlterationService; + + + @Lazy + private final IXzdPurchaseContractSuspendService xzdPurchaseContractSuspendService; + + + /** + * 获取采购合同终止详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value={"contractManagement:purchaseContractInformation:list","contractManagement:purchaseContractInformation:add","contractManagement:purchaseContractInformation:edit"}, mode = SaMode.OR) + @GetMapping("/zz/{id}") + public R getInfozz(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdPurchaseContractSuspendService.queryById(id)); + } + + /** + * 查询采购合同终止列表 + */ + @SaCheckPermission(value={"contractManagement:purchaseContractInformation:list","contractManagement:purchaseContractInformation:add","contractManagement:purchaseContractInformation:edit"}, mode = SaMode.OR) + @GetMapping("/listzz") + public TableDataInfo list(XzdPurchaseContractSuspendBo bo, PageQuery pageQuery) { + return xzdPurchaseContractSuspendService.queryPageList(bo, pageQuery); + } + + /** + * 查询采购合同变更列表 + */ + @SaCheckPermission(value={"contractManagement:purchaseContractInformation:list","contractManagement:purchaseContractInformation:add","contractManagement:purchaseContractInformation:edit"}, mode = SaMode.OR) + @GetMapping("/listbg") + public TableDataInfo list(XzdPurchaseContractAlterationBo bo, PageQuery pageQuery) { + return xzdPurchaseContractAlterationService.queryPageList(bo, pageQuery); + } + /** + * 获取采购合同变更详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value={"contractManagement:purchaseContractInformation:list","contractManagement:purchaseContractInformation:add","contractManagement:purchaseContractInformation:edit"}, mode = SaMode.OR) + @GetMapping("/xx/{id}") + public R getInfoxx(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdPurchaseContractAlterationService.queryById(id)); + } + /** * 查询印章帮助列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdContractDetailsController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdContractDetailsController.java index 024bd997..5450fce7 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdContractDetailsController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdContractDetailsController.java @@ -43,6 +43,10 @@ public class XzdContractDetailsController extends BaseController { private final IXzdContractChangeService xzdContractChangeService; private final IXzdContractTerminationService xzdContractTerminationService; + + + + /** * 查询承包合同信息列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdCorrespondentList.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdCorrespondentList.java index e6b34d31..ca788050 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdCorrespondentList.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/controller/XzdCorrespondentList.java @@ -11,8 +11,11 @@ import org.dromara.xzd.domain.dto.XzdClienteleListDto; import org.dromara.xzd.domain.vo.XzdClienteleListSumVo; import org.dromara.xzd.domain.vo.XzdCustomertypeVo; import org.dromara.xzd.domain.vo.XzdPoiAreaVo; +import org.dromara.xzd.domain.vo.XzdProjectVo; import org.dromara.xzd.service.IXzdCorrespondentList; import org.dromara.xzd.service.IXzdCustomertypeService; +import org.dromara.xzd.service.IXzdProjectService; +import org.springframework.context.annotation.Lazy; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -32,6 +35,9 @@ public class XzdCorrespondentList { private final IXzdCustomertypeService iXzdCustomertypeService; + + + /** * 查询区域列表 */ @@ -51,6 +57,9 @@ public class XzdCorrespondentList { } + + + /** * 客户信息修改 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/domain/vo/XzdProjectVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/domain/vo/XzdProjectVo.java index 04241540..265ba3bd 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/domain/vo/XzdProjectVo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/domain/vo/XzdProjectVo.java @@ -5,6 +5,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import org.dromara.common.translation.annotation.Translation; +import org.dromara.common.translation.annotation.TranslationType; import org.dromara.common.translation.constant.TransConstant; import org.dromara.xzd.domain.XzdProject; @@ -125,6 +126,7 @@ public class XzdProjectVo implements Serializable { /** * 管理组织名 */ + @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "managementOrganization") private String managementOrganizationName; /** @@ -158,6 +160,8 @@ public class XzdProjectVo implements Serializable { @ExcelProperty(value = "项目责任人") private Long managerResponsible; + + @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "managerResponsible") private String managerResponsibleName; /** diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java index 0a2f6ce4..e07e11b0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java @@ -2,6 +2,8 @@ package org.dromara.xzd.publicUrl; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaMode; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.mybatis.core.page.PageQuery; @@ -14,20 +16,17 @@ import org.dromara.system.service.ISysUserService; import org.dromara.xzd.biddingManagement.biaoqianlixiang.domain.dto.QuerBiddingManagementDto; import org.dromara.xzd.biddingManagement.biaoqianlixiang.domain.vo.QueryListXzdVo; import org.dromara.xzd.biddingManagement.biaoqianlixiang.service.IXzdBidPreProjectService; +import org.dromara.xzd.domain.bo.XzdBusinessSealBo; import org.dromara.xzd.domain.bo.XzdProjectBo; import org.dromara.xzd.domain.bo.XzdSupplierInfoBo; import org.dromara.xzd.domain.bo.XzdSupplierOpenBankBo; import org.dromara.xzd.domain.dto.XzdClienteleListDto; -import org.dromara.xzd.domain.vo.XzdClienteleListSumVo; -import org.dromara.xzd.domain.vo.XzdProjectVo; -import org.dromara.xzd.domain.vo.XzdSupplierInfoVo; -import org.dromara.xzd.domain.vo.XzdSupplierOpenBankVo; -import org.dromara.xzd.service.IXzdCorrespondentList; -import org.dromara.xzd.service.IXzdProjectService; -import org.dromara.xzd.service.IXzdSupplierInfoService; -import org.dromara.xzd.service.IXzdSupplierOpenBankService; +import org.dromara.xzd.domain.vo.*; +import org.dromara.xzd.service.*; +import org.springframework.context.annotation.Lazy; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -60,6 +59,11 @@ public class XzdPublicUrlConreoller { private final ISysDeptService iSysDeptService; + private final IXzdBusinessSealService xzdBusinessSealService; + + + + /** * 查询项目信息列表 @@ -107,22 +111,54 @@ public class XzdPublicUrlConreoller { } - // /** -// * 获取用户列表 -// */ + /** + * 获取用户列表 + */ @GetMapping("/userList") public TableDataInfo list(SysUserBo user, PageQuery pageQuery) { return userService.selectPageUserList(user, pageQuery); } -// /** -// * 查询部门 -// */ + /** + * 查询部门 + */ @GetMapping("/listDept") public R> list() { List list = iSysDeptService.querListDept(); return R.ok(list); } + /** + * 获取供应商信息详细信息 + * + * @param id 主键 + */ + @GetMapping("/xzdSupplier/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSupplierInfoService.queryById(id)); + } + + + /** + * 查询印章帮助列表 + */ + @GetMapping("/listBusinss") + public TableDataInfo list(XzdBusinessSealBo bo, PageQuery pageQuery) { + return xzdBusinessSealService.queryPageList(bo, pageQuery); + } + + + /** + * 项目信息查询 + */ + @GetMapping("/xmxx/{id}") + public R> getXmxx( @PathVariable Long id) { + return R.ok(xzdProjectService.getXmxx(id)); + } + + + + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/IXzdProjectService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/IXzdProjectService.java index 95f8f5f9..d6a04e65 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/IXzdProjectService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/IXzdProjectService.java @@ -1,5 +1,6 @@ package org.dromara.xzd.service; +import org.dromara.common.core.domain.R; import org.dromara.xzd.domain.vo.XzdProjectVo; import org.dromara.xzd.domain.bo.XzdProjectBo; import org.dromara.xzd.domain.XzdProject; @@ -69,4 +70,12 @@ public interface IXzdProjectService extends IService{ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); String queryNameById(Long projectId); + + /** + * 查询项目信息 + * + * @param id 主键 + * @return 项目信息 + */ + List getXmxx(Long id); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdProjectServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdProjectServiceImpl.java index 12f578f6..e4d6fe9e 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdProjectServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdProjectServiceImpl.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.event.ProcessDeleteEvent; import org.dromara.common.core.domain.event.ProcessEvent; import org.dromara.common.core.domain.event.ProcessTaskEvent; @@ -513,6 +514,13 @@ public class XzdProjectServiceImpl extends ServiceImpl getXmxx(Long id) { + List xzdProjectVos = this.getBaseMapper().selectVoList(new LambdaQueryWrapper<>(new XzdProject()).eq(XzdProject::getConstructionUnit, id)); + + return xzdProjectVos; + } + public void setValue(XzdProjectVo entity){ if (entity != null) { //项目概况 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjingdu/controller/SettlementOfSubcontractingContractController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjingdu/controller/SettlementOfSubcontractingContractController.java index 46ac9ddb..dc68670f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjingdu/controller/SettlementOfSubcontractingContractController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjingdu/controller/SettlementOfSubcontractingContractController.java @@ -65,6 +65,19 @@ public class SettlementOfSubcontractingContractController extends BaseController return xzdSubcontractService.queryPageList(bo, pageQuery); } + + /** + * 获取分包合同信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"fenbaohetongjingdu:ofSubcontractingContract:list","fenbaohetongjingdu:ofSubcontractingContract:add","fenbaohetongjingdu:ofSubcontractingContract:edit"},mode = SaMode.OR) + @GetMapping("/xx/{id}") + public R getInfoxx(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSubcontractService.queryById(id)); + } + /** * 查询分包合同进度结算列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjungong/controller/SettlementOfSubcontractingCompletionController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjungong/controller/SettlementOfSubcontractingCompletionController.java index c4a20ad3..15f438c1 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjungong/controller/SettlementOfSubcontractingCompletionController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongjungong/controller/SettlementOfSubcontractingCompletionController.java @@ -65,6 +65,19 @@ public class SettlementOfSubcontractingCompletionController extends BaseControll return settlementOfSubcontractingCompletionService.queryPageList(bo, pageQuery); } + + /** + * 获取分包合同信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"fenbaohetongjungong:ofSubcontractingCompletion:list","fenbaohetongjungong:ofSubcontractingCompletion:add","fenbaohetongjungong:ofSubcontractingCompletion:edit"},mode = SaMode.OR) + @GetMapping("/xx/{id}") + public R getInfoxx(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdSubcontractService.queryById(id)); + } + /** * 导出分包合同竣工结算列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongtiaozheng/controller/SettlementOfSubcontractingAdjustmentController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongtiaozheng/controller/SettlementOfSubcontractingAdjustmentController.java index f4f61818..da7d1984 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongtiaozheng/controller/SettlementOfSubcontractingAdjustmentController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/settlement/fenbaohetongtiaozheng/controller/SettlementOfSubcontractingAdjustmentController.java @@ -57,6 +57,18 @@ public class SettlementOfSubcontractingAdjustmentController extends BaseControll // return xzdSubcontractService.queryPageList(bo, pageQuery); // } + /** + * 获取分包合同竣工结算详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"fenbaohetongtiaozheng:ofSubcontractingAdjustment:list","fenbaohetongtiaozheng:ofSubcontractingAdjustment:add","fenbaohetongtiaozheng:ofSubcontractingAdjustment:edit"},mode = SaMode.OR) + @GetMapping("/jg/{id}") + public R getInfojg(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(settlementOfSubcontractingCompletionService.queryById(id)); + } + /** * 查询分包合同竣工结算列表 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinbiangeng/controller/FinancialRevenuePlanAlterationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinbiangeng/controller/FinancialRevenuePlanAlterationController.java index ae90ece4..443d6244 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinbiangeng/controller/FinancialRevenuePlanAlterationController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinbiangeng/controller/FinancialRevenuePlanAlterationController.java @@ -3,10 +3,20 @@ package org.dromara.xzd.zijinjihua.yueduzijinbiangeng.controller; import java.util.List; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaMode; import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; +import org.dromara.xzd.domain.bo.XzdContractDetailsBo; +import org.dromara.xzd.domain.vo.XzdContractDetailsVo; +import org.dromara.xzd.domain.vo.XzdProjectVo; +import org.dromara.xzd.service.IXzdContractDetailsService; +import org.dromara.xzd.service.IXzdProjectService; +import org.dromara.xzd.zijinjihua.yueduzijinjihua.domain.bo.FinancialRevenueExpenditurePlanBo; +import org.dromara.xzd.zijinjihua.yueduzijinjihua.domain.vo.FinancialRevenueExpenditurePlanVo; +import org.dromara.xzd.zijinjihua.yueduzijinjihua.service.IFinancialRevenueExpenditurePlanService; +import org.hibernate.validator.internal.util.stereotypes.Lazy; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -37,6 +47,66 @@ public class FinancialRevenuePlanAlterationController extends BaseController { private final IFinancialRevenuePlanAlterationService financialRevenuePlanAlterationService; + private final IFinancialRevenueExpenditurePlanService financialRevenueExpenditurePlanService; + + + private final IXzdContractDetailsService xzdContractDetailsService; + + + + + @Lazy + private final IXzdProjectService xzdProjectService; + + + + /** + * 获取项目信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"yueduzijinbiangeng:revenuePlanAlteration:list","yueduzijinbiangeng:revenuePlanAlteration:add","yueduzijinbiangeng:revenuePlanAlteration:edit"}, mode = SaMode.OR) + @GetMapping("/getProject/{id}") + public R getProjectInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdProjectService.queryById(id)); + } + + + + + + /** + * 查询月度资金计划列表 + */ + @SaCheckPermission(value = {"yueduzijinbiangeng:revenuePlanAlteration:list","yueduzijinbiangeng:revenuePlanAlteration:add","yueduzijinbiangeng:revenuePlanAlteration:edit"}, mode = SaMode.OR) + @GetMapping("/getlist") + public TableDataInfo list(FinancialRevenueExpenditurePlanBo bo, PageQuery pageQuery) { + return financialRevenueExpenditurePlanService.queryPageList(bo, pageQuery); + } + + /** + * 获取承包合同信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"yueduzijinbiangeng:revenuePlanAlteration:list","yueduzijinbiangeng:revenuePlanAlteration:add","yueduzijinbiangeng:revenuePlanAlteration:edit"}, mode = SaMode.OR) + @GetMapping("/cb/{id}") + public R getInfocb(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdContractDetailsService.queryById(id)); + } + + + /** + * 查询承包合同信息列表 + */ + @SaCheckPermission(value = {"yueduzijinbiangeng:revenuePlanAlteration:list","yueduzijinbiangeng:revenuePlanAlteration:add","yueduzijinbiangeng:revenuePlanAlteration:edit"}, mode = SaMode.OR) + @GetMapping("/listcb") + public TableDataInfo list(XzdContractDetailsBo bo, PageQuery pageQuery) { + return xzdContractDetailsService.queryPageList(bo, pageQuery); + } + /** * 查询月度资金计划变更列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinjihua/controller/FinancialRevenueExpenditurePlanController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinjihua/controller/FinancialRevenueExpenditurePlanController.java index d4c258c4..7be8459e 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinjihua/controller/FinancialRevenueExpenditurePlanController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/zijinjihua/yueduzijinjihua/controller/FinancialRevenueExpenditurePlanController.java @@ -2,12 +2,19 @@ package org.dromara.xzd.zijinjihua.yueduzijinjihua.controller; import java.util.List; +import cn.dev33.satoken.annotation.SaMode; import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.xzd.domain.bo.XzdContractDetailsBo; +import org.dromara.xzd.domain.vo.XzdContractDetailsVo; +import org.dromara.xzd.domain.vo.XzdProjectVo; +import org.dromara.xzd.service.IXzdContractDetailsService; +import org.dromara.xzd.service.IXzdProjectService; import org.dromara.xzd.zijinjihua.yueduzijinjihua.service.IDetailOfEarningsService; import org.dromara.xzd.zijinjihua.yueduzijinjihua.service.IStatementOfExpendituresService; +import org.hibernate.validator.internal.util.stereotypes.Lazy; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -39,6 +46,55 @@ public class FinancialRevenueExpenditurePlanController extends BaseController { private final IFinancialRevenueExpenditurePlanService financialRevenueExpenditurePlanService; + private final IXzdContractDetailsService xzdContractDetailsService; + + + + + @Lazy + private final IXzdProjectService xzdProjectService; + + + + /** + * 获取项目信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"yueduzijinjihua:revenueExpenditurePlan:list","yueduzijinjihua:revenueExpenditurePlan:add","yueduzijinjihua:revenueExpenditurePlan:edit"}, mode = SaMode.OR) + @GetMapping("/getProject/{id}") + public R getProjectInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdProjectService.queryById(id)); + } + + + + /** + * 获取承包合同信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"yueduzijinjihua:revenueExpenditurePlan:list","yueduzijinjihua:revenueExpenditurePlan:add","yueduzijinjihua:revenueExpenditurePlan:edit"}, mode = SaMode.OR) + @GetMapping("/cb/{id}") + public R getInfocb(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdContractDetailsService.queryById(id)); + } + + + /** + * 查询承包合同信息列表 + */ + @SaCheckPermission(value = {"yueduzijinjihua:revenueExpenditurePlan:list","yueduzijinjihua:revenueExpenditurePlan:add","yueduzijinjihua:revenueExpenditurePlan:edit"}, mode = SaMode.OR) + @GetMapping("/listcb") + public TableDataInfo list(XzdContractDetailsBo bo, PageQuery pageQuery) { + return xzdContractDetailsService.queryPageList(bo, pageQuery); + } + + + + /** * 查询月度资金计划列表 */ From 0c3b14e0107d7de0079b5e29461c6d10ef02095d Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 17 Nov 2025 18:39:45 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E5=AE=A2=E6=88=B7=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/mapper/xzd/XzdCustomerinformationMapper.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdCustomerinformationMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdCustomerinformationMapper.xml index d1093d0f..89563e28 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdCustomerinformationMapper.xml +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdCustomerinformationMapper.xml @@ -57,6 +57,9 @@ AND a1.unified_social_credit_code = #{dto.unifiedSocialCreditCode} + + AND a1.audit_status = #{dto.auditStatus} + AND a1.poi_area_id = #{dto.poiAreaId} From 73988b88280aab6c96605662244aa8cf41d46c6d Mon Sep 17 00:00:00 2001 From: dfdg <2710245601@qq.com> Date: Mon, 17 Nov 2025 18:45:06 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BD=A6=E8=BE=86?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E8=BD=A8=E8=BF=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 1 + .../controller/GpsEquipmentController.java | 5 + .../gps/service/IGpsEquipmentSonService.java | 1 + .../service/impl/GpsEquipmentServiceImpl.java | 33 ++- .../impl/GpsEquipmentSonServiceImpl.java | 8 + .../controller/VehVehicleInfoController.java | 12 + .../service/IVehVehicleInfoService.java | 5 + .../service/IVehVehicleTripService.java | 7 + .../impl/VehVehicleInfoServiceImpl.java | 25 ++ .../impl/VehVehicleTripServiceImpl.java | 8 + .../websocket/domain/vo/VehicleVo.java | 27 +++ .../service/VehicleWebSocketServer.java | 227 ++++++++++++++++++ .../XzdCsContractInformationController.java | 19 ++ 13 files changed, 374 insertions(+), 4 deletions(-) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/domain/vo/VehicleVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/VehicleWebSocketServer.java diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml index 6938f01b..2f2a5f62 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml @@ -137,6 +137,7 @@ security: - /facility/matrix/** - /hat/device/data - /websocket/ue + - /websocket/vehicle # 多租户配置 tenant: diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/GpsEquipmentController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/GpsEquipmentController.java index bc96bea6..3447d4b0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/GpsEquipmentController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/controller/GpsEquipmentController.java @@ -92,6 +92,11 @@ public class GpsEquipmentController extends BaseController { return gpsEquipmentService.queryPageList(bo, pageQuery); } + /** + * 查询GPS设备详细列表给车辆 + * @param bo + * @return + */ @GetMapping("/getListToVehicle") public R> getListToVehicle(GpsEquipmentBo bo) { return R.ok(gpsEquipmentService.getListToVehicle(bo)); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsEquipmentSonService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsEquipmentSonService.java index ce672613..f7dc357c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsEquipmentSonService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsEquipmentSonService.java @@ -87,4 +87,5 @@ public interface IGpsEquipmentSonService extends IService{ List getUeUserListByProjectId(LocalDateTime startOfDay, LocalDateTime now); List getVehicleList(GpsEquipmentSonBo bo); + List getNewVehicleList(GpsEquipmentSonBo bo); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java index 3db89308..d4e6ce78 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java @@ -35,6 +35,7 @@ import org.dromara.project.domain.vo.project.BusProjectVo; import org.dromara.project.service.IBusProjectService; import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.service.ISysUserService; +import org.dromara.websocket.websocket.service.VehicleWebSocketServer; import org.redisson.api.DeletedObjectListener; import org.redisson.api.ExpiredObjectListener; import org.redisson.api.listener.SetObjectListener; @@ -263,7 +264,6 @@ public class GpsEquipmentServiceImpl extends ServiceImpl 0){ - if (equipment != null && StringUtils.isNotEmpty(equipment.getModelId())) { + if (equipment != null && StringUtils.isNotEmpty(equipment.getModelId())) { + int onlineCount = InitOnStartWebSocketServer.getOnlineCount(); + if (onlineCount > 0){ String ued = ueStructureJsonMessage(gpsEquipmentSon, equipment.getModelId()); InitOnStartWebSocketServer.sendToAll(ued); } } + //判断车辆轨迹是否有连接 + if (equipment != null && equipment.getClientType() == 1 && equipment.getUserId() != null) { + int onlineCount1 = VehicleWebSocketServer.getOnlineCount(); + if (onlineCount1 > 0) { + String vehicled = vehicleStructureJsonMessage(gpsEquipmentSon); + VehicleWebSocketServer.sendToSubscription(gpsEquipmentSon.getUserId()+"-"+gpsEquipmentSon.getTripId(), vehicled); + } + } + + + Set sessionsAll = WebSocketSessionHolder.getSessionsAll(); + if (!sessionsAll.isEmpty()) { String pushContent = buildPushMessage(gpsEquipmentSon); @@ -348,6 +360,19 @@ public class GpsEquipmentServiceImpl extends ServiceImpl getNewVehicleList(GpsEquipmentSonBo bo) { + return baseMapper.selectVoList(new LambdaQueryWrapper() + .eq(GpsEquipmentSon::getUserId,bo.getUserId()) + .eq(GpsEquipmentSon::getTripId,bo.getTripId()) + .orderByDesc(GpsEquipmentSon::getCreateTime)); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/controller/VehVehicleInfoController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/controller/VehVehicleInfoController.java index 8b2d1fb0..f03d82d5 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/controller/VehVehicleInfoController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/controller/VehVehicleInfoController.java @@ -17,6 +17,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.web.core.BaseController; import org.dromara.vehicle.domain.bo.VehVehicleInfoBo; import org.dromara.vehicle.domain.vo.VehVehicleInfoVo; +import org.dromara.vehicle.domain.vo.VehVehicleTripVo; import org.dromara.vehicle.service.IVehVehicleInfoService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -45,6 +46,17 @@ public class VehVehicleInfoController extends BaseController { public TableDataInfo list(VehVehicleInfoBo bo, PageQuery pageQuery) { return vehVehicleInfoService.queryPageList(bo, pageQuery); } + /** + * 获取车辆行程信息 + * + * @param id 主键 + */ +// @SaCheckPermission("vehicle:vehicleInfo:query") + @GetMapping("/getTrip/{id}") + public R getTripInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(vehVehicleInfoService.getTripInfo(id)); + } /** * 查询车辆信息列表 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleInfoService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleInfoService.java index 08045e43..af987eff 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleInfoService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleInfoService.java @@ -1,5 +1,6 @@ package org.dromara.vehicle.service; +import jakarta.validation.constraints.NotNull; import org.dromara.vehicle.domain.vo.VehVehicleInfoVo; import org.dromara.vehicle.domain.bo.VehVehicleInfoBo; import org.dromara.vehicle.domain.VehVehicleInfo; @@ -7,6 +8,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.vehicle.domain.vo.VehVehicleTripVo; + import java.util.Collection; import java.util.List; @@ -81,4 +84,6 @@ public interface IVehVehicleInfoService extends IService{ * @return */ int unBindClient(VehVehicleInfoBo bo); + + VehVehicleTripVo getTripInfo(Long id); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleTripService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleTripService.java index 53981d4b..2323fc10 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleTripService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/IVehVehicleTripService.java @@ -107,4 +107,11 @@ public interface IVehVehicleTripService extends IService { * @return */ Long getTripId(Long id); + + /** + * 根据车辆id获取最新行程信息 + * @param id + * @return + */ + VehVehicleTripVo getTripInfoByVehicleId(Long id); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleInfoServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleInfoServiceImpl.java index bd097ea0..f60604ea 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleInfoServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleInfoServiceImpl.java @@ -18,9 +18,12 @@ import org.dromara.gps.service.IGpsEquipmentService; import org.dromara.gps.service.IGpsManmachineService; import org.dromara.vehicle.domain.VehVehicleInfo; import org.dromara.vehicle.domain.bo.VehVehicleInfoBo; +import org.dromara.vehicle.domain.enums.VehVehicleInfoStatusEnum; import org.dromara.vehicle.domain.vo.VehVehicleInfoVo; +import org.dromara.vehicle.domain.vo.VehVehicleTripVo; import org.dromara.vehicle.mapper.VehVehicleInfoMapper; import org.dromara.vehicle.service.IVehVehicleInfoService; +import org.dromara.vehicle.service.IVehVehicleTripService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -50,6 +53,10 @@ public class VehVehicleInfoServiceImpl extends ServiceImpl().set(VehVehicleInfo::getClientId,null).eq(VehVehicleInfo::getId,bo.getId())); } + + /** + * 通过车辆id获取车辆的当前行程信息 + * @param id + * @return + */ + @Override + public VehVehicleTripVo getTripInfo(Long id) { + VehVehicleInfoVo vehVehicleInfoVo = baseMapper.selectVoById(id); + if (vehVehicleInfoVo == null) { + throw new ServiceException("车辆信息为空"); + } + if (!VehVehicleInfoStatusEnum.IN_USE.getValue().equals(vehVehicleInfoVo.getVehicleStatus())){ + return null; + } + + return vehVehicleTripService.getTripInfoByVehicleId(id); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleTripServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleTripServiceImpl.java index 2bd88e11..40892118 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleTripServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/vehicle/service/impl/VehVehicleTripServiceImpl.java @@ -476,6 +476,14 @@ public class VehVehicleTripServiceImpl extends ServiceImpl() + .eq(VehVehicleTrip::getVehicleId, id) + .orderByDesc(VehVehicleTrip::getCreateTime) + .last("limit 1")); + } + /** * 构建用户行程及其对应申请的展示列表 * diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/domain/vo/VehicleVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/domain/vo/VehicleVo.java new file mode 100644 index 00000000..05ddc3cf --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/domain/vo/VehicleVo.java @@ -0,0 +1,27 @@ +package org.dromara.websocket.websocket.domain.vo; + +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.math.BigDecimal; + +@Data +public class VehicleVo { + + /** + * 纬度(精确到6位小数) + */ + @ExcelProperty(value = "纬度", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "精=确到6位小数") + private BigDecimal locLatitude; + + /** + * 经度(精确到6位小数) + */ + @ExcelProperty(value = "经度", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "精=确到6位小数") + private BigDecimal locLongitude; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/VehicleWebSocketServer.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/VehicleWebSocketServer.java new file mode 100644 index 00000000..e3d00038 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/VehicleWebSocketServer.java @@ -0,0 +1,227 @@ +package org.dromara.websocket.websocket.service; + +import cn.hutool.json.JSONUtil; +import jakarta.websocket.*; +import jakarta.websocket.server.ServerEndpoint; +import lombok.extern.slf4j.Slf4j; +import org.dromara.bigscreen.service.ProjectBigScreenService; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.gps.domain.bo.GpsEquipmentSonBo; +import org.dromara.gps.domain.vo.GpsEquipmentSonVo; +import org.dromara.gps.service.IGpsEquipmentSonService; +import org.dromara.websocket.websocket.domain.vo.VehicleVo; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 车辆轨迹 WebSocket 服务端(支持订阅消息) + * 端点路径:/websocket/vehicle + */ +@Slf4j +@ServerEndpoint("/websocket/vehicle") // 客户端连接时需携带订阅ID参数:ws://xxx/websocket/vehicle?subscriptionId=xxx +@Component +public class VehicleWebSocketServer { + + // 1. 存储所有在线会话(sessionId -> Session) + private static final Map ONLINE_SESSIONS = new ConcurrentHashMap<>(); + + // 2. 核心:订阅ID与会话的映射(subscriptionId -> Session) + private static final Map SUBSCRIPTION_SESSIONS = new ConcurrentHashMap<>(); + + // 3. 反向映射:会话ID与订阅ID的映射(用于断开连接时清理订阅关系) + private static final Map SESSION_TO_SUBSCRIPTION = new ConcurrentHashMap<>(); + + // 当前会话对应的订阅ID(每个连接实例的专属变量) + private String currentSubscriptionId; + + + static { + log.info("✅ 车辆轨迹 WebSocket 服务端已随项目启动初始化!端点路径:/websocket/vehicle"); + } + + /** + * 客户端连接时触发(解析订阅ID并建立映射关系) + */ + @OnOpen + public void onOpen(Session session) { + // 从连接URL的查询参数中获取订阅ID(客户端连接格式:ws://xxx/websocket/vehicle?subscriptionId=123) + Map> params = session.getRequestParameterMap(); + List subscriptionIds = params.get("subscriptionId"); + if (subscriptionIds != null && !subscriptionIds.isEmpty()) { + this.currentSubscriptionId = subscriptionIds.get(0); // 取第一个订阅ID + // 建立映射关系 + SUBSCRIPTION_SESSIONS.put(currentSubscriptionId, session); + SESSION_TO_SUBSCRIPTION.put(session.getId(), currentSubscriptionId); + log.info("📌 客户端订阅成功!订阅ID:{},会话ID:{},当前订阅数:{}", + currentSubscriptionId, session.getId(), SUBSCRIPTION_SESSIONS.size()); + } else { + log.warn("📌 客户端连接未携带订阅ID!会话ID:{}", session.getId()); + } + + // 存储会话到在线列表 + ONLINE_SESSIONS.put(session.getId(), session); + log.info("📌 客户端连接成功!会话ID:{},当前在线数:{}", session.getId(), ONLINE_SESSIONS.size()); + + // 异步推送初始化数据(原有逻辑保留) + CompletableFuture.runAsync(() -> { + try { + String[] split = currentSubscriptionId.split("-"); + IGpsEquipmentSonService service = SpringUtils.getBean(IGpsEquipmentSonService.class); + GpsEquipmentSonBo bo = new GpsEquipmentSonBo(); + bo.setUserId(Long.parseLong(split[0])); + bo.setTripId(Long.parseLong(split[1])); + List list = service.getNewVehicleList(bo); + if (list == null || list.isEmpty()) { + session.getBasicRemote().sendText("初始化数据为空"); + log.warn("会话[{}]未获取到初始化数据", session.getId()); + return; + } + List vehicleVos = new ArrayList<>(); + for (GpsEquipmentSonVo ueClient : list) { + VehicleVo vo = new VehicleVo(); + vo.setLocLatitude(ueClient.getLocLatitude()); + vo.setLocLongitude(ueClient.getLocLongitude()); + vehicleVos.add(vo); + } + session.getBasicRemote().sendText(JSONUtil.toJsonStr(vehicleVos)); + log.info("📤 已向会话[{}]推送初始化数据,长度:{}字节", session.getId(), vehicleVos.size()); + } catch (Exception e) { + log.error("会话[{}]初始化数据处理失败", session.getId(), e); + try { + if (session.isOpen()) { + session.getBasicRemote().sendText("初始化失败:" + e.getMessage()); + } + } catch (IOException ex) { + log.error("会话[{}]推送错误信息失败", session.getId(), ex); + } + } + }); + } + + /** + * 接收客户端消息 + */ + @OnMessage + public void onMessage(String message, Session session) { + log.info("📥 收到会话[{}](订阅ID:{})消息:{}", session.getId(), currentSubscriptionId, message); + // 可选:回复客户端 + try { + session.getBasicRemote().sendText("服务端已收到消息:" + message); + } catch (IOException e) { + log.error("📤 回复会话[{}]失败:{}", session.getId(), e.getMessage()); + } + } + + /** + * 客户端断开连接(清理订阅关系) + */ + @OnClose + public void onClose(Session session, CloseReason reason) { + // 1. 移除在线会话 + ONLINE_SESSIONS.remove(session.getId()); + // 2. 清理订阅关系 + String subscriptionId = SESSION_TO_SUBSCRIPTION.get(session.getId()); + if (subscriptionId != null) { + SUBSCRIPTION_SESSIONS.remove(subscriptionId); + SESSION_TO_SUBSCRIPTION.remove(session.getId()); + log.info("🔌 客户端订阅关系已清除!订阅ID:{},会话ID:{}", subscriptionId, session.getId()); + } + log.info("🔌 客户端断开连接!会话ID:{},原因:{},当前在线数:{},当前订阅数:{}", + session.getId(), reason.getReasonPhrase(), + ONLINE_SESSIONS.size(), SUBSCRIPTION_SESSIONS.size()); + } + + /** + * 连接异常 + */ + @OnError + public void onError(Session session, Throwable error) { + log.error("⚠️ 会话[{}](订阅ID:{})异常:{}", session.getId(), currentSubscriptionId, error.getMessage(), error); + } + + + // ------------------------------ 订阅消息发送工具方法(供外部调用) ------------------------------ + + /** + * 向指定订阅ID的客户端发送消息 + * @param subscriptionId 订阅ID + * @param message 消息内容 + * @return 是否发送成功 + */ + public static boolean sendToSubscription(String subscriptionId, String message) { + if (subscriptionId == null || message == null) { + log.warn("⚠️ 订阅ID或消息为空,发送失败"); + return false; + } + // 从订阅映射中获取目标会话 + Session session = SUBSCRIPTION_SESSIONS.get(subscriptionId); + if (session == null || !session.isOpen()) { + log.warn("⚠️ 订阅ID[{}]对应的客户端未连接或已断开", subscriptionId); + return false; + } + // 发送消息 + try { + session.getBasicRemote().sendText(message); + log.info("📤 已向订阅ID[{}]发送消息:{}", subscriptionId, message); + return true; + } catch (IOException e) { + log.error("📤 向订阅ID[{}]发送消息失败", subscriptionId, e); + return false; + } + } + + /** + * 向所有订阅客户端广播消息 + * @param message 消息内容 + */ + public static void broadcastToAllSubscriptions(String message) { + if (SUBSCRIPTION_SESSIONS.isEmpty()) { + log.warn("⚠️ 无订阅客户端,无需广播消息"); + return; + } + SUBSCRIPTION_SESSIONS.forEach((subscriptionId, session) -> { + if (session.isOpen()) { + try { + session.getBasicRemote().sendText(message); + log.info("📤 已向订阅ID[{}]广播消息", subscriptionId); + } catch (IOException e) { + log.error("📤 向订阅ID[{}]广播消息失败", subscriptionId, e); + } + } + }); + } + + /** + * 获取当前订阅数 + */ + public static int getSubscriptionCount() { + return SUBSCRIPTION_SESSIONS.size(); + } + + // 原有工具方法保留 + public static void sendToAll(String message) { + if (ONLINE_SESSIONS.isEmpty()) { + log.warn("⚠️ 无在线客户端,无需发送消息"); + return; + } + ONLINE_SESSIONS.values().forEach(session -> { + if (session.isOpen()) { + try { + session.getBasicRemote().sendText(message); + } catch (IOException e) { + log.error("📤 向会话[{}]发送消息失败:{}", session.getId(), e.getMessage()); + } + } + }); + } + + public static int getOnlineCount() { + return ONLINE_SESSIONS.size(); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/comprehensive/controller/XzdCsContractInformationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/comprehensive/controller/XzdCsContractInformationController.java index 32fb51b2..104d792d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/comprehensive/controller/XzdCsContractInformationController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/comprehensive/controller/XzdCsContractInformationController.java @@ -15,7 +15,9 @@ import org.dromara.xzd.comprehensive.service.IXzdCsContractChangeService; import org.dromara.xzd.comprehensive.service.IXzdCsContractSuspendService; import org.dromara.xzd.domain.bo.XzdBusinessSealBo; import org.dromara.xzd.domain.vo.XzdBusinessSealVo; +import org.dromara.xzd.domain.vo.XzdProjectVo; import org.dromara.xzd.service.IXzdBusinessSealService; +import org.dromara.xzd.service.IXzdProjectService; import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; @@ -55,6 +57,23 @@ public class XzdCsContractInformationController extends BaseController { @Lazy private final IXzdCsContractChangeService xzdCsContractChangeService; + @Lazy + private final IXzdProjectService xzdProjectService; + + + + /** + * 获取项目信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission(value = {"comprehensive:csContractInformation:add","comprehensive:csContractInformation:edit","comprehensive:csContractInformation:list"},mode = SaMode.OR) + @GetMapping("/getProject/{id}") + public R getProjectInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xzdProjectService.queryById(id)); + } + /** * 查询综合服务合同变更列表 From faf434e4d2e789ed99e5f482153d125d5dc4463e Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 17 Nov 2025 18:53:13 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E7=BB=84=E7=BB=87=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/service/impl/SysDeptServiceImpl.java | 3 --- .../xzd/publicUrl/XzdPublicUrlConreoller.java | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java index e2c3e02e..2153b337 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java @@ -537,10 +537,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { @Override public List querListDept() { - List sysDeptVos = baseMapper.selectDeptList(new LambdaQueryWrapper().eq(SysDept::getParentId, "100").eq(SysDept::getStatus, "0").eq(SysDept::getDelFlag, "0")); - - return sysDeptVos; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java index e07e11b0..66ac79ac 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.SysDeptVo; import org.dromara.system.domain.vo.SysUserVo; @@ -61,6 +62,9 @@ public class XzdPublicUrlConreoller { private final IXzdBusinessSealService xzdBusinessSealService; + private final ISysDeptService deptService; + + @@ -123,10 +127,16 @@ public class XzdPublicUrlConreoller { /** * 查询部门 */ +// @GetMapping("/listDept") +// public R> list() { +// List list = iSysDeptService.querListDept(); +// return R.ok(list); +// } + @GetMapping("/listDept") - public R> list() { - List list = iSysDeptService.querListDept(); - return R.ok(list); + public R> list(SysDeptBo dept) { + List depts = deptService.selectDeptList(dept); + return R.ok(depts); } /** From 9a20cf0e4327467ec951d22c7c26e18544e2b6e8 Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 17 Nov 2025 19:06:52 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E9=83=A8=E9=97=A8=E6=A0=91=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xzd/publicUrl/XzdPublicUrlConreoller.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java index 66ac79ac..b5aa54cb 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/publicUrl/XzdPublicUrlConreoller.java @@ -3,6 +3,7 @@ package org.dromara.xzd.publicUrl; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaMode; +import cn.hutool.core.lang.tree.Tree; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; @@ -121,6 +122,18 @@ public class XzdPublicUrlConreoller { @GetMapping("/userList") public TableDataInfo list(SysUserBo user, PageQuery pageQuery) { return userService.selectPageUserList(user, pageQuery); + + + + } + + + /** + * 获取部门树列表 + */ + @GetMapping("/deptTree") + public R>> deptTree(SysDeptBo dept) { + return R.ok(deptService.selectDeptTreeList(dept)); }