Explorar o código

宗地报表用途分析

chenendian hai 3 semanas
pai
achega
8486c2f759

+ 1 - 1
.gitignore

@@ -82,5 +82,5 @@ nbdist/
 /lib/spire.doc.free-5.2.0.jar
 /siwei-modules/siwei-apply/lib/spire.doc.free-5.2.0.jar
 /.vscode/settings.json
-/.workbuddy/memory/*
+/.workbuddy/*
 /siwei-modules/siwei-apply/lib/aspose-words-18.6-jdk16-crack.jar

+ 399 - 8
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/ParcelAnalysisController.java

@@ -1,16 +1,18 @@
 package com.siwei.apply.controller.cadastre;
 
-import com.siwei.apply.domain.cadastre.LandSupplyReportDTO;
-import com.siwei.apply.domain.cadastre.ParcelStatisticsRes;
-import com.siwei.apply.domain.cadastre.ZdqlReportVO;
-import com.siwei.apply.domain.cadastre.Zdjbxx;
+import com.siwei.apply.domain.cadastre.*;
 import com.siwei.apply.service.cadastre.IParcelService;
 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;
 import java.util.Map;
 
@@ -94,6 +96,398 @@ public class ParcelAnalysisController extends BaseController {
     }
 
 
+    /**
+     * 导出宗地权利报表(Excel格式)
+     * 表格结构:
+     *   - 第1行:报表标题
+     *   - 第2行:列头(地籍子区代码、地籍子区名称、5种权利类型名称)
+     *   - 第3行:列头子行(合计面积、已登记面积、未登记面积)
+     *   - 数据行:各地籍子区数据
+     *   - 末行:合计行
+     */
+    @PostMapping("/zdql/export")
+    public void exportZdqlReport(HttpServletResponse response) {
+        try {
+            ZdqlReportVO res = parcelService.getZdqlReport();
+            if (res == null) {
+                return;
+            }
+
+            Workbook workbook = new XSSFWorkbook();
+            Sheet sheet = workbook.createSheet("宗地权利报表");
+
+            // 标题样式(居中、加粗、14号字、带边框)
+            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行:报表标题
+            Row titleRow = sheet.createRow(rowIndex++);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue("宗地权利报表");
+            titleCell.setCellStyle(titleStyle);
+            titleRow.setHeight((short) 500);
+            // 合并单元格(标题跨17列:地籍子区代码 + 名称 + 5种权利类型×3列)
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 16));
+
+            // 第2行:列头 - 地籍子区代码、地籍子区名称、5种权利类型×3列
+            Row headerRow = sheet.createRow(rowIndex++);
+            Cell djzqdmHeader = headerRow.createCell(0);
+            djzqdmHeader.setCellValue("地籍子区代码");
+            djzqdmHeader.setCellStyle(headerStyle);
+
+            Cell djzqmcHeader = headerRow.createCell(1);
+            djzqmcHeader.setCellValue("地籍子区名称");
+            djzqmcHeader.setCellStyle(headerStyle);
+
+            // 5种权利类型,每种3列(合计、已登记、未登记)
+            if (res.getRows() != null && !res.getRows().isEmpty()) {
+                List<ZdqlReportVO.QllxStatCell> firstRowCells = res.getRows().get(0).getCells();
+                int colIndex = 2;
+                for (ZdqlReportVO.QllxStatCell cell : firstRowCells) {
+                    String qllxName = cell.getQllxName();
+                    Cell qllxHeader = headerRow.createCell(colIndex);
+                    qllxHeader.setCellValue(qllxName);
+                    qllxHeader.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);
+
+            int subColIndex = 2;
+            if (res.getRows() != null && !res.getRows().isEmpty()) {
+                for (ZdqlReportVO.QllxStatCell cell : res.getRows().get(0).getCells()) {
+                    Cell totalHeader = subHeaderRow.createCell(subColIndex++);
+                    totalHeader.setCellValue("合计面积");
+                    totalHeader.setCellStyle(headerStyle);
+
+                    Cell registeredHeader = subHeaderRow.createCell(subColIndex++);
+                    registeredHeader.setCellValue("已登记面积");
+                    registeredHeader.setCellStyle(headerStyle);
+
+                    Cell unregisteredHeader = subHeaderRow.createCell(subColIndex++);
+                    unregisteredHeader.setCellValue("未登记面积");
+                    unregisteredHeader.setCellStyle(headerStyle);
+                }
+            }
+
+            // 数据行:各地籍子区数据
+            if (res.getRows() != null) {
+                for (ZdqlReportVO.RowData rowData : res.getRows()) {
+                    Row dataRow = sheet.createRow(rowIndex++);
+                    dataRow.setHeight((short) 400);
+
+                    Cell djzqdmCell = dataRow.createCell(0);
+                    djzqdmCell.setCellValue(rowData.getDjzqdm());
+                    djzqdmCell.setCellStyle(dataStyle);
+
+                    Cell djzqmcCell = dataRow.createCell(1);
+                    djzqmcCell.setCellValue(rowData.getDjzqmc());
+                    djzqmcCell.setCellStyle(dataStyle);
+
+                    int cellIndex = 2;
+                    for (ZdqlReportVO.QllxStatCell cell : rowData.getCells()) {
+                        Cell totalCell = dataRow.createCell(cellIndex++);
+                        totalCell.setCellValue(cell.getTotalArea() != null ? cell.getTotalArea() : 0.0);
+                        totalCell.setCellStyle(dataStyle);
+
+                        Cell registeredCell = dataRow.createCell(cellIndex++);
+                        registeredCell.setCellValue(cell.getRegisteredArea() != null ? cell.getRegisteredArea() : 0.0);
+                        registeredCell.setCellStyle(dataStyle);
+
+                        Cell unregisteredCell = dataRow.createCell(cellIndex++);
+                        unregisteredCell.setCellValue(cell.getUnregisteredArea() != null ? cell.getUnregisteredArea() : 0.0);
+                        unregisteredCell.setCellStyle(dataStyle);
+                    }
+                }
+            }
+
+            // 合计行
+            if (res.getTotal() != null) {
+                Row totalRow = sheet.createRow(rowIndex++);
+                totalRow.setHeight((short) 400);
+
+                Cell totalDjzqdmCell = totalRow.createCell(0);
+                totalDjzqdmCell.setCellValue("");
+                totalDjzqdmCell.setCellStyle(totalStyle);
+
+                Cell totalDjzqmcCell = totalRow.createCell(1);
+                totalDjzqmcCell.setCellValue(res.getTotal().getDjzqmc());
+                totalDjzqmcCell.setCellStyle(totalStyle);
+
+                int cellIndex = 2;
+                for (ZdqlReportVO.QllxStatCell cell : res.getTotal().getCells()) {
+                    Cell totalCell = totalRow.createCell(cellIndex++);
+                    totalCell.setCellValue(cell.getTotalArea() != null ? cell.getTotalArea() : 0.0);
+                    totalCell.setCellStyle(totalStyle);
+
+                    Cell registeredCell = totalRow.createCell(cellIndex++);
+                    registeredCell.setCellValue(cell.getRegisteredArea() != null ? cell.getRegisteredArea() : 0.0);
+                    registeredCell.setCellStyle(totalStyle);
+
+                    Cell unregisteredCell = totalRow.createCell(cellIndex++);
+                    unregisteredCell.setCellValue(cell.getUnregisteredArea() != null ? cell.getUnregisteredArea() : 0.0);
+                    unregisteredCell.setCellStyle(totalStyle);
+                }
+            }
+
+            // 自动调整列宽(根据数据内容)
+            for (int i = 0; i <= 16; 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() {
+        try {
+            ZdytReportVO res = parcelService.getZdytReport();
+            return R.ok(res);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 导出报表,宗地用途
+     * 表格结构:
+     *   - 第1行:报表标题
+     *   - 第2行:列头(用途代码、用途名称、合计面积、国有土地、集体土地)
+     *   - 数据行:各地籍用途数据
+     *   - 末行:合计行
+     * @param response
+     */
+    @PostMapping("/zdyt/export")
+    public void exportZdytReport(HttpServletResponse response) {
+        try {
+            ZdytReportVO res = parcelService.getZdytReport();
+            if (res == null) {
+                return;
+            }
+
+            Workbook workbook = new XSSFWorkbook();
+            Sheet sheet = workbook.createSheet("宗地用途报表");
+
+            // 标题样式(居中、加粗、14号字、带边框)
+            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行:报表标题
+            Row titleRow = sheet.createRow(rowIndex++);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue("宗地用途报表");
+            titleCell.setCellStyle(titleStyle);
+            titleRow.setHeight((short) 500);
+            // 合并单元格(标题跨5列:用途代码 + 用途名称 + 合计面积 + 国有土地 + 集体土地)
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 4));
+
+            // 第2行:列头
+            Row headerRow = sheet.createRow(rowIndex++);
+            String[] headers = {"用途代码", "用途名称", "合计面积(亩)", "国有土地(亩)", "集体土地(亩)"};
+            for (int i = 0; i < headers.length; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers[i]);
+                cell.setCellStyle(headerStyle);
+            }
+
+            // 数据行:各地籍用途数据
+            if (res.getRows() != null) {
+                for (ZdytReportVO.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);
+
+                    Cell totalAreaCell = dataRow.createCell(2);
+                    totalAreaCell.setCellValue(rowData.getTotalArea() != null ? rowData.getTotalArea() : 0.0);
+                    totalAreaCell.setCellStyle(dataStyle);
+
+                    Cell stateOwnedCell = dataRow.createCell(3);
+                    stateOwnedCell.setCellValue(rowData.getStateOwnedArea() != null ? rowData.getStateOwnedArea() : 0.0);
+                    stateOwnedCell.setCellStyle(dataStyle);
+
+                    Cell collectiveCell = dataRow.createCell(4);
+                    collectiveCell.setCellValue(rowData.getCollectiveArea() != null ? rowData.getCollectiveArea() : 0.0);
+                    collectiveCell.setCellStyle(dataStyle);
+                }
+            }
+
+            // 合计行
+            if (res.getTotal() != null) {
+                Row totalRow = sheet.createRow(rowIndex++);
+                totalRow.setHeight((short) 400);
+
+                Cell codeCell = totalRow.createCell(0);
+                codeCell.setCellValue("");
+                codeCell.setCellStyle(totalStyle);
+
+                Cell nameCell = totalRow.createCell(1);
+                nameCell.setCellValue("合计");
+                nameCell.setCellStyle(totalStyle);
+
+                Cell totalAreaCell = totalRow.createCell(2);
+                totalAreaCell.setCellValue(res.getTotal().getTotalArea() != null ? res.getTotal().getTotalArea() : 0.0);
+                totalAreaCell.setCellStyle(totalStyle);
+
+                Cell stateOwnedCell = totalRow.createCell(3);
+                stateOwnedCell.setCellValue(res.getTotal().getStateOwnedArea() != null ? res.getTotal().getStateOwnedArea() : 0.0);
+                stateOwnedCell.setCellStyle(totalStyle);
+
+                Cell collectiveCell = totalRow.createCell(4);
+                collectiveCell.setCellValue(res.getTotal().getCollectiveArea() != null ? res.getTotal().getCollectiveArea() : 0.0);
+                collectiveCell.setCellStyle(totalStyle);
+            }
+
+            // 自动调整列宽
+            for (int i = 0; i < 5; 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();
+        }
+    }
+
 
 
 
@@ -107,6 +501,7 @@ public class ParcelAnalysisController extends BaseController {
 //            TrendStatisticsRes res =  supplyService.trendStatistics(landType);
 //            return R.ok(res);
 //        } catch (Exception e) {
+//            e.printStackTrace();
 //            return R.fail(e.getMessage());
 //        }
 //    }
@@ -114,8 +509,4 @@ public class ParcelAnalysisController extends BaseController {
 
 
 
-
-
-
-
 }

+ 40 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/cadastre/ZdytReportVO.java

@@ -0,0 +1,40 @@
+package com.siwei.apply.domain.cadastre;
+
+import lombok.Data;
+
+import java.util.List;
+
+
+@Data
+public class ZdytReportVO {
+
+    /**
+     * 合计行
+     */
+    private RowData total;
+
+    /**
+     * 各个用途名称对应的行
+     */
+    private List<RowData> rows;
+
+
+    /**
+     * 报表数据行
+     */
+    @Data
+    public static class RowData {
+        /** 用途code */
+        private String useTypeCode;
+        /** 用途名称 */
+        private String useTypeName;
+        /** 合计面积 */
+        private Double totalArea;
+        /** 国有土地 */
+        private Double stateOwnedArea;
+        /** 集体土地 */
+        private Double collectiveArea;
+    }
+
+
+}

+ 11 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/cadastre/ZdjbxxMapper.java

@@ -75,4 +75,15 @@ public interface ZdjbxxMapper {
      */
     List<Map<String, Object>> getZdqlReportData(@Param("qllxCodes") List<String> qllxCodes);
 
+    /**
+     * 按土地用途(一级分类)× 权利性质统计宗地面积(用于宗地用途报表)
+     * <p>
+     * 返回字段:yt_prefix, qlxz, area_mu
+     * yt_prefix 为 yt 字段前2位(一级分类代码)
+     * qlxz 权利性质代码(100=国有,200=集体)
+     * </p>
+     * @return 统计结果列表
+     */
+    List<Map<String, Object>> getZdytReportData();
+
 }

+ 5 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/IParcelService.java

@@ -3,6 +3,7 @@ package com.siwei.apply.service.cadastre;
 import com.siwei.apply.domain.cadastre.ParcelStatisticsRes;
 import com.siwei.apply.domain.cadastre.Zdjbxx;
 import com.siwei.apply.domain.cadastre.ZdqlReportVO;
+import com.siwei.apply.domain.cadastre.ZdytReportVO;
 
 import java.util.List;
 import java.util.Map;
@@ -17,5 +18,9 @@ public interface IParcelService {
 
     ZdqlReportVO getZdqlReport();
 
+    ZdytReportVO getZdytReport();
+
+
+
 }
 

+ 117 - 2
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/ParcelServiceImpl.java

@@ -5,6 +5,7 @@ import com.siwei.apply.domain.cadastre.ParcelStatisticsRes;
 import com.siwei.apply.domain.cadastre.Zdjbxx;
 import com.siwei.apply.domain.cadastre.ZdqlReportVO;
 
+import com.siwei.apply.domain.cadastre.ZdytReportVO;
 import com.siwei.apply.mapper.LandTypeMapper;
 import com.siwei.apply.mapper.cadastre.ZdjbxxMapper;
 import com.siwei.apply.service.cadastre.IParcelService;
@@ -422,6 +423,122 @@ public class ParcelServiceImpl implements IParcelService {
         return report;
     }
 
+
+    /**
+     * 生成宗地用途报表
+     * <p>
+     * 报表结构:
+     *   - 行:土地用途一级分类(land_type),每类一行 + 末尾合计行
+     *   - 列:合计面积、国有土地面积、集体土地面积
+     *     国有/集体根据 qlxz 字段区分:
+     *       qlxz=100 → 国有土地
+     *       qlxz=200 → 集体土地
+     *   - 面积单位:亩(根据 mjdw 字段自动换算,SQL 已完成换算)
+     *   - 关联:yt 字段前2位匹配 land_type 一级分类 code
+     * </p>
+     *
+     * @return ZdytReportVO
+     */
+    @Override
+    public ZdytReportVO getZdytReport(){
+
+        // ---------------------------------------------------
+        // 1. 获取土地用途一级分类列表(作为报表行维度)
+        // ---------------------------------------------------
+        List<LandType> landTypeList = landTypeMapper.selectFirstLevel();
+        // 按 code 建立 Map,方便后续查找
+        LinkedHashMap<String, String> ytDefMap = new LinkedHashMap<>();
+        for (LandType lt : landTypeList) {
+            ytDefMap.put(lt.getCode(), lt.getName());
+        }
+        List<String> ytCodes = new ArrayList<>(ytDefMap.keySet());
+
+        // ---------------------------------------------------
+        // 2. 查询原始聚合数据(yt前2位 × qlxz)
+        // ---------------------------------------------------
+        List<Map<String, Object>> rawData = zdjbxxMapper.getZdytReportData();
+
+        // ---------------------------------------------------
+        // 3. 按用途分类聚合:Map<yt_prefix, double[2]>
+        //    double[0] = 国有土地面积(qlxz=100),double[1] = 集体土地面积(qlxz=200)
+        // ---------------------------------------------------
+        LinkedHashMap<String, double[]> ytDataMap = new LinkedHashMap<>();
+        // 初始化所有一级分类,保证即使没有数据也会展示
+        for (String code : ytCodes) {
+            ytDataMap.put(code, new double[]{0.0, 0.0});
+        }
+
+        for (Map<String, Object> row : rawData) {
+            String ytPrefix = (String) row.get("yt_prefix");
+            String qlxz = row.get("qlxz") != null ? row.get("qlxz").toString() : "";
+            double areaMu = row.get("area_mu") != null ? ((Number) row.get("area_mu")).doubleValue() : 0.0;
+
+            if (StringUtils.isBlank(ytPrefix) || !ytDataMap.containsKey(ytPrefix)) {
+                continue;
+            }
+
+            double[] areaArr = ytDataMap.get(ytPrefix);
+            if ("100".equals(qlxz)) {
+                areaArr[0] += areaMu;  // 国有土地
+            } else if ("200".equals(qlxz)) {
+                areaArr[1] += areaMu;  // 集体土地
+            }
+            // 其他 qlxz 值不计入国有或集体
+        }
+
+        // ---------------------------------------------------
+        // 4. 构建数据行列表
+        // ---------------------------------------------------
+        List<ZdytReportVO.RowData> rows = new ArrayList<>();
+        // 合计行累加器
+        double totalStateOwned = 0.0;
+        double totalCollective = 0.0;
+
+        for (Map.Entry<String, double[]> entry : ytDataMap.entrySet()) {
+            String ytCode = entry.getKey();
+            double[] areaArr = entry.getValue();
+            double stateOwned = areaArr[0];
+            double collective = areaArr[1];
+            double total = stateOwned + collective;
+
+            // 只展示有数据的行(面积不为零)
+            if (total <= 0.0) {
+                continue;
+            }
+
+            ZdytReportVO.RowData rowData = new ZdytReportVO.RowData();
+            rowData.setUseTypeCode(ytCode);
+            rowData.setUseTypeName(ytDefMap.getOrDefault(ytCode, ""));
+            rowData.setTotalArea(roundArea(total));
+            rowData.setStateOwnedArea(roundArea(stateOwned));
+            rowData.setCollectiveArea(roundArea(collective));
+            rows.add(rowData);
+
+            // 累计到合计行
+            totalStateOwned += stateOwned;
+            totalCollective += collective;
+        }
+
+        // ---------------------------------------------------
+        // 5. 构建合计行
+        // ---------------------------------------------------
+        ZdytReportVO.RowData totalRow = new ZdytReportVO.RowData();
+        totalRow.setUseTypeCode(null);
+        totalRow.setUseTypeName("合计");
+        totalRow.setTotalArea(roundArea(totalStateOwned + totalCollective));
+        totalRow.setStateOwnedArea(roundArea(totalStateOwned));
+        totalRow.setCollectiveArea(roundArea(totalCollective));
+
+        // ---------------------------------------------------
+        // 6. 组装返回结果
+        // ---------------------------------------------------
+        ZdytReportVO report = new ZdytReportVO();
+        report.setRows(rows);
+        report.setTotal(totalRow);
+        return report;
+    }
+
+
     /**
      * 面积保留两位小数(四舍五入)
      */
@@ -429,6 +546,4 @@ public class ParcelServiceImpl implements IParcelService {
         return Math.round(value * 100.0) / 100.0;
     }
 
-
-
 }

+ 31 - 0
siwei-modules/siwei-apply/src/main/resources/mapper/cadastre/ZdjbxxMapper.xml

@@ -311,4 +311,35 @@
         ORDER BY dq.djzqdm, zd.qllx, zd.djzt
     </select>
 
+    <!--
+        宗地用途报表数据查询
+        按土地用途一级分类(yt前2位) × 权利性质(qlxz) 两维度聚合面积
+        - yt字段前2位对应 land_type 表的一级分类 code
+        - qlxz: 100=国有土地, 200=集体土地
+        - 面积统一换算为亩(mu)
+        - 只统计已登记数据(djzt=1)的 qlxz 字段
+        返回字段:yt_prefix, qlxz, area_mu
+    -->
+    <select id="getZdytReportData" resultType="Map">
+        SELECT
+            LEFT(zd.yt, 2) AS yt_prefix,
+            zd.qlxz,
+            SUM(
+                CASE
+                    WHEN zd.mjdw = '1' THEN zd.zdmj / 666.6666667
+                    WHEN zd.mjdw = '2' THEN zd.zdmj
+                    WHEN zd.mjdw = '3' THEN zd.zdmj * 15
+                    WHEN zd.mjdw = '4' THEN zd.zdmj * 1500
+                    ELSE COALESCE(zd.zdmj, 0)
+                END
+            ) AS area_mu
+        FROM vector.zdjbxx zd
+        WHERE zd.yt IS NOT NULL
+          AND zd.zdmj IS NOT NULL
+          AND (zd.valid_flag IS NULL OR zd.valid_flag = 0)
+          AND LENGTH(TRIM(zd.yt)) >= 2
+        GROUP BY LEFT(zd.yt, 2), zd.qlxz
+        ORDER BY LEFT(zd.yt, 2), zd.qlxz
+    </select>
+
 </mapper>