Przeglądaj źródła

fw统计报表分析

chenendian 6 dni temu
rodzic
commit
ad4cc989bb

+ 399 - 43
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/HouseAnalysisController.java

@@ -5,10 +5,14 @@ import com.siwei.apply.service.cadastre.IHouselService;
 import com.siwei.common.core.domain.R;
 import com.siwei.common.core.web.controller.BaseController;
 import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 
 /**
@@ -79,37 +83,16 @@ public class HouseAnalysisController extends BaseController {
             return R.fail(e.getMessage());
         }
     }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 
 
     /**
-     * 宗地分析报表-宗地权利报表
-     * 按地籍子区统计各权利类型(已登记/未登记/合计)面积(单位:亩)
-     *
-     * @return ZdqlReportVO 含列头定义、各地籍子区数据行、合计行
+     * 房屋用途报表统计
+     * @return
      */
-    @GetMapping("/report/zdql")
-    public R<ZdqlReportVO> getZdqlReport() {
+    @GetMapping("/report/fwyt")
+    public R<FwytReportVO> getFwytReport() {
         try {
-            ZdqlReportVO res = null;
+            FwytReportVO res = houselService.getZRZFwytReport();
             return R.ok(res);
         } catch (Exception e) {
             e.printStackTrace();
@@ -118,31 +101,209 @@ public class HouseAnalysisController extends BaseController {
     }
 
 
-    /**
-     * 导出宗地权利报表(Excel格式)
-     * 表格结构:
-     *   - 第1行:报表标题
-     *   - 第2行:列头(地籍子区代码、地籍子区名称、5种权利类型名称)
-     *   - 第3行:列头子行(合计面积、已登记面积、未登记面积)
-     *   - 数据行:各地籍子区数据
-     *   - 末行:合计行
-     */
-    @PostMapping("/zdql/export")
-    public void exportZdqlReport(HttpServletResponse response) {
 
+    @PostMapping("/fwyt/export")
+    public void exportFwytReport(HttpServletResponse response) {
+        try {
+            FwytReportVO res = houselService.getZRZFwytReport();
+            if (res == null) {
+                return;
+            }
+
+            Workbook workbook = new XSSFWorkbook();
+            Sheet sheet = workbook.createSheet("房屋用途报表");
+
+            CellStyle titleStyle = workbook.createCellStyle();
+            titleStyle.setAlignment(HorizontalAlignment.CENTER);
+            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            Font titleFont = workbook.createFont();
+            titleFont.setBold(true);
+            titleFont.setFontHeightInPoints((short) 14);
+            titleStyle.setFont(titleFont);
+            titleStyle.setBorderTop(BorderStyle.THIN);
+            titleStyle.setBorderBottom(BorderStyle.THIN);
+            titleStyle.setBorderLeft(BorderStyle.THIN);
+            titleStyle.setBorderRight(BorderStyle.THIN);
+
+            CellStyle headerStyle = workbook.createCellStyle();
+            headerStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+            Font headerFont = workbook.createFont();
+            headerFont.setBold(true);
+            headerStyle.setFont(headerFont);
+            headerStyle.setBorderTop(BorderStyle.THIN);
+            headerStyle.setBorderBottom(BorderStyle.THIN);
+            headerStyle.setBorderLeft(BorderStyle.THIN);
+            headerStyle.setBorderRight(BorderStyle.THIN);
+
+            CellStyle dataStyle = workbook.createCellStyle();
+            dataStyle.setAlignment(HorizontalAlignment.CENTER);
+            dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            dataStyle.setBorderTop(BorderStyle.THIN);
+            dataStyle.setBorderBottom(BorderStyle.THIN);
+            dataStyle.setBorderLeft(BorderStyle.THIN);
+            dataStyle.setBorderRight(BorderStyle.THIN);
+
+            CellStyle totalStyle = workbook.createCellStyle();
+            totalStyle.setAlignment(HorizontalAlignment.CENTER);
+            totalStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            Font totalFont = workbook.createFont();
+            totalFont.setBold(true);
+            totalStyle.setFont(totalFont);
+            totalStyle.setBorderTop(BorderStyle.THIN);
+            totalStyle.setBorderBottom(BorderStyle.THIN);
+            totalStyle.setBorderLeft(BorderStyle.THIN);
+            totalStyle.setBorderRight(BorderStyle.THIN);
+
+            int rowIndex = 0;
+
+            // 第1行:报表标题,跨11列(房屋用途代码+名称 2列 + 3个登记状态×3列=9列)
+            Row titleRow = sheet.createRow(rowIndex++);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue("房屋用途报表");
+            titleCell.setCellStyle(titleStyle);
+            titleRow.setHeight((short) 500);
+            for (int i = 1; i <= 10; i++) {
+                titleRow.createCell(i).setCellStyle(titleStyle);
+            }
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 10));
+
+            // 第2行:列头 - 房屋用途代码(合并2行)、房屋用途名称(合并2行)、3个登记状态分组名(各跨3列)
+            Row headerRow = sheet.createRow(rowIndex++);
+            Cell codeHeader = headerRow.createCell(0);
+            codeHeader.setCellValue("房屋用途代码");
+            codeHeader.setCellStyle(headerStyle);
+            Cell nameHeader = headerRow.createCell(1);
+            nameHeader.setCellValue("房屋用途名称");
+            nameHeader.setCellStyle(headerStyle);
+
+            int colIndex = 2;
+            if (res.getRows() != null && !res.getRows().isEmpty()) {
+                for (FwytReportVO.DjztStatCell cell : res.getRows().get(0).getCells()) {
+                    Cell groupHeader = headerRow.createCell(colIndex);
+                    groupHeader.setCellValue(cell.getDjztName());
+                    groupHeader.setCellStyle(headerStyle);
+                    sheet.addMergedRegion(new CellRangeAddress(1, 1, colIndex, colIndex + 2));
+                    colIndex += 3;
+                }
+            }
+
+            // 第3行:列头子行 - 数量(个)、占用面积(亩)、建筑总面积(亩)
+            Row subHeaderRow = sheet.createRow(rowIndex++);
+            subHeaderRow.createCell(0).setCellStyle(headerStyle);
+            subHeaderRow.createCell(1).setCellStyle(headerStyle);
+            sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0));
+            sheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1));
+
+            int subColIndex = 2;
+            if (res.getRows() != null && !res.getRows().isEmpty()) {
+                for (int g = 0; g < res.getRows().get(0).getCells().size(); g++) {
+                    Cell countHeader = subHeaderRow.createCell(subColIndex++);
+                    countHeader.setCellValue("数量(个)");
+                    countHeader.setCellStyle(headerStyle);
+
+                    Cell occupiedHeader = subHeaderRow.createCell(subColIndex++);
+                    occupiedHeader.setCellValue("占用面积(亩)");
+                    occupiedHeader.setCellStyle(headerStyle);
+
+                    Cell buildingHeader = subHeaderRow.createCell(subColIndex++);
+                    buildingHeader.setCellValue("建筑总面积(亩)");
+                    buildingHeader.setCellStyle(headerStyle);
+                }
+            }
+
+            // 数据行
+            if (res.getRows() != null) {
+                for (FwytReportVO.RowData rowData : res.getRows()) {
+                    Row dataRow = sheet.createRow(rowIndex++);
+                    dataRow.setHeight((short) 400);
+
+                    Cell codeCell = dataRow.createCell(0);
+                    codeCell.setCellValue(rowData.getUseTypeCode() != null ? rowData.getUseTypeCode() : "");
+                    codeCell.setCellStyle(dataStyle);
+
+                    Cell nameCell = dataRow.createCell(1);
+                    nameCell.setCellValue(rowData.getUseTypeName() != null ? rowData.getUseTypeName() : "");
+                    nameCell.setCellStyle(dataStyle);
+
+                    int cellIndex = 2;
+                    for (FwytReportVO.DjztStatCell cell : rowData.getCells()) {
+                        Cell countCell = dataRow.createCell(cellIndex++);
+                        countCell.setCellValue(cell.getCount() != null ? cell.getCount() : 0);
+                        countCell.setCellStyle(dataStyle);
+
+                        Cell occupiedCell = dataRow.createCell(cellIndex++);
+                        occupiedCell.setCellValue(cell.getOccupiedArea() != null ? cell.getOccupiedArea() : 0.0);
+                        occupiedCell.setCellStyle(dataStyle);
+
+                        Cell buildingCell = dataRow.createCell(cellIndex++);
+                        buildingCell.setCellValue(cell.getBuildingTotalArea() != null ? cell.getBuildingTotalArea() : 0.0);
+                        buildingCell.setCellStyle(dataStyle);
+                    }
+                }
+            }
+
+            // 合计行
+            if (res.getTotal() != null) {
+                Row totalRow = sheet.createRow(rowIndex++);
+                totalRow.setHeight((short) 400);
+
+                Cell totalCodeCell = totalRow.createCell(0);
+                totalCodeCell.setCellValue("");
+                totalCodeCell.setCellStyle(totalStyle);
+
+                Cell totalNameCell = totalRow.createCell(1);
+                totalNameCell.setCellValue(res.getTotal().getUseTypeName());
+                totalNameCell.setCellStyle(totalStyle);
+
+                int cellIndex = 2;
+                for (FwytReportVO.DjztStatCell cell : res.getTotal().getCells()) {
+                    Cell countCell = totalRow.createCell(cellIndex++);
+                    countCell.setCellValue(cell.getCount() != null ? cell.getCount() : 0);
+                    countCell.setCellStyle(totalStyle);
+
+                    Cell occupiedCell = totalRow.createCell(cellIndex++);
+                    occupiedCell.setCellValue(cell.getOccupiedArea() != null ? cell.getOccupiedArea() : 0.0);
+                    occupiedCell.setCellStyle(totalStyle);
+
+                    Cell buildingCell = totalRow.createCell(cellIndex++);
+                    buildingCell.setCellValue(cell.getBuildingTotalArea() != null ? cell.getBuildingTotalArea() : 0.0);
+                    buildingCell.setCellStyle(totalStyle);
+                }
+            }
+
+            for (int i = 0; i <= 10; i++) {
+                sheet.autoSizeColumn(i);
+                int currentWidth = sheet.getColumnWidth(i);
+                if (currentWidth < 3000) {
+                    sheet.setColumnWidth(i, 3000);
+                }
+            }
+
+            String fileName = "房屋用途报表";
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String encodedName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20");
+            response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedName);
+
+            workbook.write(response.getOutputStream());
+            workbook.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 
 
-
-
     /**
-     * 宗地用途报表
+     * 房屋性质报表统计
      * @return
      */
-    @GetMapping("/report/zdyt")
-    public R<ZdytReportVO> getZdytReport() {
+    @GetMapping("/report/fwxz")
+    public R<FwxzReportVO> getFwxzReport() {
         try {
-            ZdytReportVO res = null;
+            FwxzReportVO res = houselService.getZRZFwxzReport();
             return R.ok(res);
         } catch (Exception e) {
             e.printStackTrace();
@@ -152,5 +313,200 @@ public class HouseAnalysisController extends BaseController {
 
 
 
+    @PostMapping("/fwxz/export")
+    public void exportFwxzReport(HttpServletResponse response) {
+        try {
+            FwxzReportVO res = houselService.getZRZFwxzReport();
+            if (res == null) {
+                return;
+            }
+
+            Workbook workbook = new XSSFWorkbook();
+            Sheet sheet = workbook.createSheet("房屋性质报表");
+
+            CellStyle titleStyle = workbook.createCellStyle();
+            titleStyle.setAlignment(HorizontalAlignment.CENTER);
+            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            Font titleFont = workbook.createFont();
+            titleFont.setBold(true);
+            titleFont.setFontHeightInPoints((short) 14);
+            titleStyle.setFont(titleFont);
+            titleStyle.setBorderTop(BorderStyle.THIN);
+            titleStyle.setBorderBottom(BorderStyle.THIN);
+            titleStyle.setBorderLeft(BorderStyle.THIN);
+            titleStyle.setBorderRight(BorderStyle.THIN);
+
+            CellStyle headerStyle = workbook.createCellStyle();
+            headerStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+            Font headerFont = workbook.createFont();
+            headerFont.setBold(true);
+            headerStyle.setFont(headerFont);
+            headerStyle.setBorderTop(BorderStyle.THIN);
+            headerStyle.setBorderBottom(BorderStyle.THIN);
+            headerStyle.setBorderLeft(BorderStyle.THIN);
+            headerStyle.setBorderRight(BorderStyle.THIN);
+
+            CellStyle dataStyle = workbook.createCellStyle();
+            dataStyle.setAlignment(HorizontalAlignment.CENTER);
+            dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            dataStyle.setBorderTop(BorderStyle.THIN);
+            dataStyle.setBorderBottom(BorderStyle.THIN);
+            dataStyle.setBorderLeft(BorderStyle.THIN);
+            dataStyle.setBorderRight(BorderStyle.THIN);
+
+            CellStyle totalStyle = workbook.createCellStyle();
+            totalStyle.setAlignment(HorizontalAlignment.CENTER);
+            totalStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            Font totalFont = workbook.createFont();
+            totalFont.setBold(true);
+            totalStyle.setFont(totalFont);
+            totalStyle.setBorderTop(BorderStyle.THIN);
+            totalStyle.setBorderBottom(BorderStyle.THIN);
+            totalStyle.setBorderLeft(BorderStyle.THIN);
+            totalStyle.setBorderRight(BorderStyle.THIN);
+
+            int rowIndex = 0;
+
+            // 第1行:报表标题,跨11列(房屋性质代码+名称 2列 + 3个登记状态×3列=9列)
+            Row titleRow = sheet.createRow(rowIndex++);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue("房屋性质报表");
+            titleCell.setCellStyle(titleStyle);
+            titleRow.setHeight((short) 500);
+            for (int i = 1; i <= 10; i++) {
+                titleRow.createCell(i).setCellStyle(titleStyle);
+            }
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 10));
+
+            // 第2行:列头 - 房屋性质代码(合并2行)、房屋性质名称(合并2行)、3个登记状态分组名(各跨3列)
+            Row headerRow = sheet.createRow(rowIndex++);
+            Cell codeHeader = headerRow.createCell(0);
+            codeHeader.setCellValue("房屋性质代码");
+            codeHeader.setCellStyle(headerStyle);
+            Cell nameHeader = headerRow.createCell(1);
+            nameHeader.setCellValue("房屋性质名称");
+            nameHeader.setCellStyle(headerStyle);
+
+            int colIndex = 2;
+            if (res.getRows() != null && !res.getRows().isEmpty()) {
+                for (FwxzReportVO.DjztStatCell cell : res.getRows().get(0).getCells()) {
+                    Cell groupHeader = headerRow.createCell(colIndex);
+                    groupHeader.setCellValue(cell.getDjztName());
+                    groupHeader.setCellStyle(headerStyle);
+                    sheet.addMergedRegion(new CellRangeAddress(1, 1, colIndex, colIndex + 2));
+                    colIndex += 3;
+                }
+            }
+
+            // 第3行:列头子行 - 数量(个)、占用面积(亩)、建筑总面积(亩)
+            Row subHeaderRow = sheet.createRow(rowIndex++);
+            subHeaderRow.createCell(0).setCellStyle(headerStyle);
+            subHeaderRow.createCell(1).setCellStyle(headerStyle);
+            sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0));
+            sheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1));
+
+            int subColIndex = 2;
+            if (res.getRows() != null && !res.getRows().isEmpty()) {
+                for (int g = 0; g < res.getRows().get(0).getCells().size(); g++) {
+                    Cell countHeader = subHeaderRow.createCell(subColIndex++);
+                    countHeader.setCellValue("数量(个)");
+                    countHeader.setCellStyle(headerStyle);
+
+                    Cell occupiedHeader = subHeaderRow.createCell(subColIndex++);
+                    occupiedHeader.setCellValue("占用面积(亩)");
+                    occupiedHeader.setCellStyle(headerStyle);
+
+                    Cell buildingHeader = subHeaderRow.createCell(subColIndex++);
+                    buildingHeader.setCellValue("建筑总面积(亩)");
+                    buildingHeader.setCellStyle(headerStyle);
+                }
+            }
+
+            // 数据行
+            if (res.getRows() != null) {
+                for (FwxzReportVO.RowData rowData : res.getRows()) {
+                    Row dataRow = sheet.createRow(rowIndex++);
+                    dataRow.setHeight((short) 400);
+
+                    Cell codeCell = dataRow.createCell(0);
+                    codeCell.setCellValue(rowData.getNatureCode() != null ? rowData.getNatureCode() : "");
+                    codeCell.setCellStyle(dataStyle);
+
+                    Cell nameCell = dataRow.createCell(1);
+                    nameCell.setCellValue(rowData.getNatureName() != null ? rowData.getNatureName() : "");
+                    nameCell.setCellStyle(dataStyle);
+
+                    int cellIndex = 2;
+                    for (FwxzReportVO.DjztStatCell cell : rowData.getCells()) {
+                        Cell countCell = dataRow.createCell(cellIndex++);
+                        countCell.setCellValue(cell.getCount() != null ? cell.getCount() : 0);
+                        countCell.setCellStyle(dataStyle);
+
+                        Cell occupiedCell = dataRow.createCell(cellIndex++);
+                        occupiedCell.setCellValue(cell.getOccupiedArea() != null ? cell.getOccupiedArea() : 0.0);
+                        occupiedCell.setCellStyle(dataStyle);
+
+                        Cell buildingCell = dataRow.createCell(cellIndex++);
+                        buildingCell.setCellValue(cell.getBuildingTotalArea() != null ? cell.getBuildingTotalArea() : 0.0);
+                        buildingCell.setCellStyle(dataStyle);
+                    }
+                }
+            }
+
+            // 合计行
+            if (res.getTotal() != null) {
+                Row totalRow = sheet.createRow(rowIndex++);
+                totalRow.setHeight((short) 400);
+
+                Cell totalCodeCell = totalRow.createCell(0);
+                totalCodeCell.setCellValue("");
+                totalCodeCell.setCellStyle(totalStyle);
+
+                Cell totalNameCell = totalRow.createCell(1);
+                totalNameCell.setCellValue(res.getTotal().getNatureName());
+                totalNameCell.setCellStyle(totalStyle);
+
+                int cellIndex = 2;
+                for (FwxzReportVO.DjztStatCell cell : res.getTotal().getCells()) {
+                    Cell countCell = totalRow.createCell(cellIndex++);
+                    countCell.setCellValue(cell.getCount() != null ? cell.getCount() : 0);
+                    countCell.setCellStyle(totalStyle);
+
+                    Cell occupiedCell = totalRow.createCell(cellIndex++);
+                    occupiedCell.setCellValue(cell.getOccupiedArea() != null ? cell.getOccupiedArea() : 0.0);
+                    occupiedCell.setCellStyle(totalStyle);
+
+                    Cell buildingCell = totalRow.createCell(cellIndex++);
+                    buildingCell.setCellValue(cell.getBuildingTotalArea() != null ? cell.getBuildingTotalArea() : 0.0);
+                    buildingCell.setCellStyle(totalStyle);
+                }
+            }
+
+            for (int i = 0; i <= 10; i++) {
+                sheet.autoSizeColumn(i);
+                int currentWidth = sheet.getColumnWidth(i);
+                if (currentWidth < 3000) {
+                    sheet.setColumnWidth(i, 3000);
+                }
+            }
+
+            String fileName = "房屋性质报表";
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String encodedName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20");
+            response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedName);
+
+            workbook.write(response.getOutputStream());
+            workbook.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+
 
 }

+ 71 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/cadastre/FwxzReportVO.java

@@ -0,0 +1,71 @@
+package com.siwei.apply.domain.cadastre;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 房屋性质统计报表响应对象
+ * <p>
+ *       登记状态:
+ *       total        - 自然幢(合计)
+ *       registered   - 自然幢(已登记)
+ *       unregistered - 自然幢(未登记)
+ * </p>
+ */
+@Data
+public class FwxzReportVO {
+
+    /**
+     * 合计行(全量不分性质统计)
+     */
+    private RowData total;
+
+    /**
+     * 各房屋性质分类数据行列表
+     */
+    private List<RowData> rows;
+
+    // -------------------------------------------------------
+    //  内部类:单行数据(一个用途分类或合计)
+    // -------------------------------------------------------
+
+    /**
+     * 报表数据行
+     */
+    @Data
+    public static class RowData {
+        /** 房屋性质代码(合计行为 null) */
+        private String natureCode;
+        /** 房屋性质名称(合计行为"合计") */
+        private String natureName;
+        /**
+         * 按登记状态分组的统计单元列表,顺序与 columns 对应
+         */
+        private List<DjztStatCell> cells;
+    }
+
+    // -------------------------------------------------------
+    //  内部类:单个登记状态统计单元(数量/占用面积/建筑总面积)
+    // -------------------------------------------------------
+
+    /**
+     * 单登记状态统计单元(一个三格小组:数量、占用面积、建筑总面积)
+     * <p>
+     * 注意:djztName 已融合在此处,前端无需额外处理 columns 数组
+     * </p>
+     */
+    @Data
+    public static class DjztStatCell {
+        /** 登记状态代码 */
+        private String djztCode;
+        /** 登记状态名称(从 columns 融合至此,便于前端直接使用) */
+        private String djztName;
+        /** 自然幢数量 */
+        private Integer count;
+        /** 占用面积 */
+        private Double occupiedArea;
+        /** 建筑总面积 */
+        private Double buildingTotalArea;
+    }
+}

+ 74 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/cadastre/FwytReportVO.java

@@ -0,0 +1,74 @@
+package com.siwei.apply.domain.cadastre;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 房屋用途统计报表响应对象
+ * <p>
+ * 报表维度说明:
+ *   - 行:房屋用途分类(如住宅、工业交通仓储等) + 合计行
+ *   - 列:3种登记状态分组,每种含(数量、占用面积、建筑总面积)3个小列,共9列
+ *     登记状态:
+ *       total        - 自然幢(合计)
+ *       registered   - 自然幢(已登记)
+ *       unregistered - 自然幢(未登记)
+ * </p>
+ */
+@Data
+public class FwytReportVO {
+
+    /**
+     * 合计行(全量不分用途统计)
+     */
+    private RowData total;
+
+    /**
+     * 各房屋用途分类数据行列表
+     */
+    private List<RowData> rows;
+
+    // -------------------------------------------------------
+    //  内部类:单行数据(一个用途分类或合计)
+    // -------------------------------------------------------
+
+    /**
+     * 报表数据行
+     */
+    @Data
+    public static class RowData {
+        /** 房屋用途代码(合计行为 null) */
+        private String useTypeCode;
+        /** 房屋用途名称(合计行为"合计") */
+        private String useTypeName;
+        /**
+         * 按登记状态分组的统计单元列表,顺序与 columns 对应
+         */
+        private List<DjztStatCell> cells;
+    }
+
+    // -------------------------------------------------------
+    //  内部类:单个登记状态统计单元(数量/占用面积/建筑总面积)
+    // -------------------------------------------------------
+
+    /**
+     * 单登记状态统计单元(一个三格小组:数量、占用面积、建筑总面积)
+     * <p>
+     * 注意:djztName 已融合在此处,前端无需额外处理 columns 数组
+     * </p>
+     */
+    @Data
+    public static class DjztStatCell {
+        /** 登记状态代码 */
+        private String djztCode;
+        /** 登记状态名称(从 columns 融合至此,便于前端直接使用) */
+        private String djztName;
+        /** 自然幢数量 */
+        private Integer count;
+        /** 占用面积 */
+        private Double occupiedArea;
+        /** 建筑总面积 */
+        private Double buildingTotalArea;
+    }
+}

+ 5 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/IHouselService.java

@@ -14,9 +14,13 @@ public interface IHouselService {
     HouseStatisticsAreaRes statisticsOfArea(String djzqdm);
 
 
-
     List<Zrz> zrzList(String djzqdm);
 
 
+    FwytReportVO getZRZFwytReport();
+
+    FwxzReportVO getZRZFwxzReport();
+
+
 }
 

+ 272 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/HouseServiceImpl.java

@@ -19,11 +19,278 @@ import java.util.stream.Collectors;
 @Service
 public class HouseServiceImpl implements IHouselService {
 
-
     @Autowired
     private ZrzMapper zrzMapper;
 
 
+    /**
+     * 根据房屋性质进行数据统计
+     * @return
+     */
+    @Override
+    public FwxzReportVO getZRZFwxzReport() {
+        List<Zrz> zrzList = zrzMapper.getList();
+
+        List<Map<String, Object>> dictList = zrzMapper.getDictByType("A13", null);
+
+        List<FwxzReportVO.RowData> rows = new ArrayList<>();
+        int totalCountReg = 0;
+        double totalOccupiedReg = 0.0;
+        double totalBuildingReg = 0.0;
+        int totalCountUnreg = 0;
+        double totalOccupiedUnreg = 0.0;
+        double totalBuildingUnreg = 0.0;
+
+        for (Map<String, Object> dict : dictList) {
+            String name = MapUtils.getString(dict, "name");
+            String value = MapUtils.getString(dict, "value");
+
+            List<Zrz> filtered = new ArrayList<>();
+            for (Zrz zrz : zrzList) {
+                if (value != null && value.equals(zrz.getFwxz())) {
+                    filtered.add(zrz);
+                }
+            }
+
+            if (CollectionUtils.isEmpty(filtered)) {
+                continue;
+            }
+
+            int regCount = 0;
+            double regOccupied = 0.0;
+            double regBuilding = 0.0;
+            int unregCount = 0;
+            double unregOccupied = 0.0;
+            double unregBuilding = 0.0;
+
+            for (Zrz zrz : filtered) {
+                String djzt = zrz.getDjzt();
+                if ("1".equals(djzt)) {
+                    regCount++;
+                    regOccupied += convertAreaToMu(zrz.getZzdmj());
+                    regBuilding += convertAreaToMu(zrz.getScjzmj());
+                } else if ("2".equals(djzt) || "3".equals(djzt)) {
+                    unregCount++;
+                    unregOccupied += convertAreaToMu(zrz.getZzdmj());
+                    unregBuilding += convertAreaToMu(zrz.getScjzmj());
+                }
+            }
+
+            List<FwxzReportVO.DjztStatCell> cells = new ArrayList<>();
+
+            FwxzReportVO.DjztStatCell regCell = new FwxzReportVO.DjztStatCell();
+            regCell.setDjztCode("1");
+            regCell.setDjztName("已登记");
+            regCell.setCount(regCount);
+            regCell.setOccupiedArea(roundArea(regOccupied));
+            regCell.setBuildingTotalArea(roundArea(regBuilding));
+            cells.add(regCell);
+
+            FwxzReportVO.DjztStatCell unregCell = new FwxzReportVO.DjztStatCell();
+            unregCell.setDjztCode("2");
+            unregCell.setDjztName("未登记");
+            unregCell.setCount(unregCount);
+            unregCell.setOccupiedArea(roundArea(unregOccupied));
+            unregCell.setBuildingTotalArea(roundArea(unregBuilding));
+            cells.add(unregCell);
+
+            FwxzReportVO.DjztStatCell allCell = new FwxzReportVO.DjztStatCell();
+            allCell.setDjztCode("0");
+            allCell.setDjztName("合计");
+            allCell.setCount(regCount + unregCount);
+            allCell.setOccupiedArea(roundArea(regOccupied + unregOccupied));
+            allCell.setBuildingTotalArea(roundArea(regBuilding + unregBuilding));
+            cells.add(allCell);
+
+            FwxzReportVO.RowData rowData = new FwxzReportVO.RowData();
+            rowData.setNatureCode(value);
+            rowData.setNatureName(name);
+            rowData.setCells(cells);
+            rows.add(rowData);
+
+            totalCountReg += regCount;
+            totalOccupiedReg += regOccupied;
+            totalBuildingReg += regBuilding;
+            totalCountUnreg += unregCount;
+            totalOccupiedUnreg += unregOccupied;
+            totalBuildingUnreg += unregBuilding;
+        }
+
+        List<FwxzReportVO.DjztStatCell> totalCells = new ArrayList<>();
+
+        FwxzReportVO.DjztStatCell totalRegCell = new FwxzReportVO.DjztStatCell();
+        totalRegCell.setDjztCode("1");
+        totalRegCell.setDjztName("已登记");
+        totalRegCell.setCount(totalCountReg);
+        totalRegCell.setOccupiedArea(roundArea(totalOccupiedReg));
+        totalRegCell.setBuildingTotalArea(roundArea(totalBuildingReg));
+        totalCells.add(totalRegCell);
+
+        FwxzReportVO.DjztStatCell totalUnregCell = new FwxzReportVO.DjztStatCell();
+        totalUnregCell.setDjztCode("2");
+        totalUnregCell.setDjztName("未登记");
+        totalUnregCell.setCount(totalCountUnreg);
+        totalUnregCell.setOccupiedArea(roundArea(totalOccupiedUnreg));
+        totalUnregCell.setBuildingTotalArea(roundArea(totalBuildingUnreg));
+        totalCells.add(totalUnregCell);
+
+        FwxzReportVO.DjztStatCell totalAllCell = new FwxzReportVO.DjztStatCell();
+        totalAllCell.setDjztCode("0");
+        totalAllCell.setDjztName("合计");
+        totalAllCell.setCount(totalCountReg + totalCountUnreg);
+        totalAllCell.setOccupiedArea(roundArea(totalOccupiedReg + totalOccupiedUnreg));
+        totalAllCell.setBuildingTotalArea(roundArea(totalBuildingReg + totalBuildingUnreg));
+        totalCells.add(totalAllCell);
+
+        FwxzReportVO.RowData totalRow = new FwxzReportVO.RowData();
+        totalRow.setNatureCode(null);
+        totalRow.setNatureName("合计");
+        totalRow.setCells(totalCells);
+
+        FwxzReportVO report = new FwxzReportVO();
+        report.setRows(rows);
+        report.setTotal(totalRow);
+        return report;
+    }
+
+
+
+
+    /**
+     * 根据房屋用途进行数据统计
+     * @return
+     */
+    @Override
+    public FwytReportVO getZRZFwytReport() {
+        List<Zrz> zrzList = zrzMapper.getList();
+
+        List<Map<String, Object>> dictList = zrzMapper.getDictByType("A11", null);
+
+        List<FwytReportVO.RowData> rows = new ArrayList<>();
+        int totalCountReg = 0;
+        double totalOccupiedReg = 0.0;
+        double totalBuildingReg = 0.0;
+        int totalCountUnreg = 0;
+        double totalOccupiedUnreg = 0.0;
+        double totalBuildingUnreg = 0.0;
+
+        for (Map<String, Object> dict : dictList) {
+            String name = MapUtils.getString(dict, "name");
+            String value = MapUtils.getString(dict, "value");
+
+            List<Zrz> filtered = new ArrayList<>();
+            for (Zrz zrz : zrzList) {
+                if (value != null && value.equals(zrz.getGhyt())) {
+                    filtered.add(zrz);
+                }
+            }
+
+            if (CollectionUtils.isEmpty(filtered)) {
+                continue;
+            }
+
+            int regCount = 0;
+            double regOccupied = 0.0;
+            double regBuilding = 0.0;
+            int unregCount = 0;
+            double unregOccupied = 0.0;
+            double unregBuilding = 0.0;
+
+            for (Zrz zrz : filtered) {
+                String djzt = zrz.getDjzt();
+                if ("1".equals(djzt)) {
+                    regCount++;
+                    regOccupied += convertAreaToMu(zrz.getZzdmj());
+                    regBuilding += convertAreaToMu(zrz.getScjzmj());
+                } else if ("2".equals(djzt) || "3".equals(djzt)) {
+                    unregCount++;
+                    unregOccupied += convertAreaToMu(zrz.getZzdmj());
+                    unregBuilding += convertAreaToMu(zrz.getScjzmj());
+                }
+            }
+
+            List<FwytReportVO.DjztStatCell> cells = new ArrayList<>();
+
+            FwytReportVO.DjztStatCell regCell = new FwytReportVO.DjztStatCell();
+            regCell.setDjztCode("1");
+            regCell.setDjztName("已登记");
+            regCell.setCount(regCount);
+            regCell.setOccupiedArea(roundArea(regOccupied));
+            regCell.setBuildingTotalArea(roundArea(regBuilding));
+            cells.add(regCell);
+
+            FwytReportVO.DjztStatCell unregCell = new FwytReportVO.DjztStatCell();
+            unregCell.setDjztCode("2");
+            unregCell.setDjztName("未登记");
+            unregCell.setCount(unregCount);
+            unregCell.setOccupiedArea(roundArea(unregOccupied));
+            unregCell.setBuildingTotalArea(roundArea(unregBuilding));
+            cells.add(unregCell);
+
+            FwytReportVO.DjztStatCell allCell = new FwytReportVO.DjztStatCell();
+            allCell.setDjztCode("0");
+            allCell.setDjztName("合计");
+            allCell.setCount(regCount + unregCount);
+            allCell.setOccupiedArea(roundArea(regOccupied + unregOccupied));
+            allCell.setBuildingTotalArea(roundArea(regBuilding + unregBuilding));
+            cells.add(allCell);
+
+            FwytReportVO.RowData rowData = new FwytReportVO.RowData();
+            rowData.setUseTypeCode(value);
+            rowData.setUseTypeName(name);
+            rowData.setCells(cells);
+            rows.add(rowData);
+
+            totalCountReg += regCount;
+            totalOccupiedReg += regOccupied;
+            totalBuildingReg += regBuilding;
+            totalCountUnreg += unregCount;
+            totalOccupiedUnreg += unregOccupied;
+            totalBuildingUnreg += unregBuilding;
+        }
+
+        List<FwytReportVO.DjztStatCell> totalCells = new ArrayList<>();
+
+        FwytReportVO.DjztStatCell totalRegCell = new FwytReportVO.DjztStatCell();
+        totalRegCell.setDjztCode("1");
+        totalRegCell.setDjztName("已登记");
+        totalRegCell.setCount(totalCountReg);
+        totalRegCell.setOccupiedArea(roundArea(totalOccupiedReg));
+        totalRegCell.setBuildingTotalArea(roundArea(totalBuildingReg));
+        totalCells.add(totalRegCell);
+
+        FwytReportVO.DjztStatCell totalUnregCell = new FwytReportVO.DjztStatCell();
+        totalUnregCell.setDjztCode("2");
+        totalUnregCell.setDjztName("未登记");
+        totalUnregCell.setCount(totalCountUnreg);
+        totalUnregCell.setOccupiedArea(roundArea(totalOccupiedUnreg));
+        totalUnregCell.setBuildingTotalArea(roundArea(totalBuildingUnreg));
+        totalCells.add(totalUnregCell);
+
+        FwytReportVO.DjztStatCell totalAllCell = new FwytReportVO.DjztStatCell();
+        totalAllCell.setDjztCode("0");
+        totalAllCell.setDjztName("合计");
+        totalAllCell.setCount(totalCountReg + totalCountUnreg);
+        totalAllCell.setOccupiedArea(roundArea(totalOccupiedReg + totalOccupiedUnreg));
+        totalAllCell.setBuildingTotalArea(roundArea(totalBuildingReg + totalBuildingUnreg));
+        totalCells.add(totalAllCell);
+
+        FwytReportVO.RowData totalRow = new FwytReportVO.RowData();
+        totalRow.setUseTypeCode(null);
+        totalRow.setUseTypeName("合计");
+        totalRow.setCells(totalCells);
+
+        FwytReportVO report = new FwytReportVO();
+        report.setRows(rows);
+        report.setTotal(totalRow);
+        return report;
+    }
+
+
+
+
+
+
     @Override
     public List<Zrz> zrzList(String djzqdm) {
         if (StringUtils.isBlank(djzqdm) || djzqdm.matches("[0]+")) {
@@ -152,6 +419,10 @@ public class HouseServiceImpl implements IHouselService {
         return area.doubleValue() / 666.6666667;
     }
 
+    private double roundArea(double value) {
+        return Math.round(value * 100.0) / 100.0;
+    }
+
     private List<HouseStatisticsRes.FwytDTO> getDictStatistics(List<Zrz> zrzList, String dictType, String fieldName) {
         List<HouseStatisticsRes.FwytDTO> result = new ArrayList<>();
         List<Map<String, Object>> dictList = zrzMapper.getDictByType(dictType, null);