Browse Source

供应用途分析报表

chenendian 1 tháng trước cách đây
mục cha
commit
093e1b7bb7

+ 13 - 220
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/SupplyController.java

@@ -2,6 +2,7 @@ package com.siwei.apply.controller.cadastre;
 
 import com.siwei.apply.domain.cadastre.LandSupplyReportDTO;
 import com.siwei.apply.domain.res.*;
+import com.siwei.apply.domain.vo.LandSupplyReportVO;
 import com.siwei.apply.service.cadastre.ISupplyService;
 import com.siwei.apply.service.cadastre.IZymlService;
 import com.siwei.common.core.domain.R;
@@ -52,116 +53,6 @@ public class SupplyController extends BaseController {
     }
 
 
-    /**
-     *
-     * 年度统计2
-     *
-     */
-    @GetMapping("/yearStatistics2/{year}")
-    public R<SupplyYearStatisticsRes> getYearStatistics2(@PathVariable String year) {
-        try {
-            SupplyYearStatisticsRes res = new SupplyYearStatisticsRes();
-            if (year.equalsIgnoreCase("2024")) {
-                SupplyRateRes supplyRate = new SupplyRateRes();
-                List<LandUseRes> landUseStatisticsList = new java.util.ArrayList<>(List.of()); // 用途分析
-                List<ProjectSupplyRes> projectSupplyList = new java.util.ArrayList<>(List.of()); // 供应方式
-
-                supplyRate.setCompleteRate(78);
-                supplyRate.setPlanProjectCount(15);
-                supplyRate.setCompleteProjectCount(11);
-                supplyRate.setPlanArea(788.6f);
-                supplyRate.setCompleteArea(548.2f);
-                supplyRate.setGdUnit("亩");
-                res.setSupplyRate(supplyRate);
-
-                // --------------土地用途分析----------------------
-
-                LandUseRes landUse1 = new LandUseRes();
-                landUse1.setLandUseTypeName("城镇住宅用地");
-                landUse1.setPlanLandUseArea(700);
-                landUse1.setCompleteLandUseArea(300);
-
-                LandUseRes landUse2 = new LandUseRes();
-                landUse2.setLandUseTypeName("教育用地");
-                landUse2.setPlanLandUseArea(900);
-                landUse2.setCompleteLandUseArea(600);
-
-                landUseStatisticsList.addAll(List.of(landUse1, landUse2));
-                res.setLandUseStatisticsList(landUseStatisticsList);
-                // --------------供应方式----------------------
-
-                ProjectSupplyRes projectSupply1 = new ProjectSupplyRes();
-                projectSupply1.setGdArea(263.12f);
-                projectSupply1.setGdType("出让");
-                projectSupply1.setGdUnit("亩");
-
-                ProjectSupplyRes projectSupply2 = new ProjectSupplyRes();
-                projectSupply2.setGdArea(220.12f);
-                projectSupply2.setGdType("划拨");
-                projectSupply2.setGdUnit("亩");
-
-                ProjectSupplyRes projectSupply3 = new ProjectSupplyRes();
-                projectSupply3.setGdArea(190.12f);
-                projectSupply3.setGdType("其它");
-                projectSupply3.setGdUnit("亩");
-
-                projectSupplyList.addAll(List.of(projectSupply1, projectSupply2, projectSupply3));
-                res.setProjectSupplyList(projectSupplyList);
-
-            } else if (year.equalsIgnoreCase("2025") || year.equalsIgnoreCase("2026")) {
-                SupplyRateRes supplyRate = new SupplyRateRes();
-                List<LandUseRes> landUseStatisticsList = new java.util.ArrayList<>(List.of()); // 用途分析
-                List<ProjectSupplyRes> projectSupplyList = new java.util.ArrayList<>(List.of()); // 供应方式
-
-                supplyRate.setCompleteRate(78 + (int) (Math.random() * 10));
-                supplyRate.setPlanProjectCount(15 + (int) (Math.random() * 5));
-                supplyRate.setCompleteProjectCount(11 + (int) (Math.random() * 5));
-                supplyRate.setPlanArea((float) (Math.round((788.6f + (float) (Math.random() * 100)) * 100) / 100.0));
-                supplyRate.setCompleteArea((float) (Math.round((548.2f + (float) (Math.random() * 100)) * 100) / 100.0));
-                supplyRate.setGdUnit("亩");
-                res.setSupplyRate(supplyRate);
-
-                // --------------土地用途分析----------------------
-                // 城镇住宅用地,教育用地,商业用地,工业用地,物流仓储用地,公路用地,工业绿地
-                String[] landTypes = {"城镇住宅用地", "教育用地", "商业用地", "工业用地", "物流仓储用地", "公路用地", "工业绿地"};
-                for (String type : landTypes) {
-                    LandUseRes landUse = new LandUseRes();
-                    landUse.setLandUseTypeName(type);
-                    // 随机生成面积
-                    landUse.setPlanLandUseArea(Integer.parseInt(String.valueOf(500 + (int) (Math.random() * 500))));
-                    landUse.setCompleteLandUseArea(Integer.parseInt(String.valueOf(300 + (int) (Math.random() * 300))));
-                    landUseStatisticsList.add(landUse);
-                }
-                res.setLandUseStatisticsList(landUseStatisticsList);
-
-                // --------------供应方式----------------------
-
-                ProjectSupplyRes projectSupply1 = new ProjectSupplyRes();
-                projectSupply1.setGdArea((float) (Math.round((263.12f + (float) (Math.random() * 100)) * 100) / 100.0));
-                projectSupply1.setGdType("出让");
-                projectSupply1.setGdUnit("亩");
-
-                ProjectSupplyRes projectSupply2 = new ProjectSupplyRes();
-                projectSupply2.setGdArea((float) (Math.round((220.12f + (float) (Math.random() * 100)) * 100) / 100.0));
-                projectSupply2.setGdType("划拨");
-                projectSupply2.setGdUnit("亩");
-
-                ProjectSupplyRes projectSupply3 = new ProjectSupplyRes();
-                projectSupply3.setGdArea((float) (Math.round((190.12f + (float) (Math.random() * 100)) * 100) / 100.0));
-                projectSupply3.setGdType("其它");
-                projectSupply3.setGdUnit("亩");
-
-                projectSupplyList.addAll(List.of(projectSupply1, projectSupply2, projectSupply3));
-                res.setProjectSupplyList(projectSupplyList);
-
-            }
-
-            return R.ok(res);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.fail(e.getMessage());
-        }
-    }
 
 
     /**
@@ -179,54 +70,18 @@ public class SupplyController extends BaseController {
     }
 
 
+
     /**
      *
-     * 趋势统计
+     * 根据时间范围查询土地供应统计报表数据
+     * 土地供应统计报表
      *
      */
-    @GetMapping("/trendStatistics2/{landType}")
-    public R<TrendStatisticsRes> getTrendStatistics2(@PathVariable String landType) {
+    @GetMapping("/report/progress")
+    public R<LandSupplyReportDTO> getTdgyReport(@RequestParam String startTime, @RequestParam String endTime) {
         try {
-            TrendStatisticsRes res = new TrendStatisticsRes();
-            List<Map<String, Object>> areaTrendStatisticsList = new java.util.ArrayList<>(List.of()); // 面积趋势分析list
-            List<Map<String, Object>> supplyModeStatisticsList = new java.util.ArrayList<>(List.of()); // 供应方式分析list
-
-            Map<String, Object> map1 = new HashMap<>();
-            map1.put("year", 2023);
-            map1.put("area", 3365.22);
-
-            Map<String, Object> map2 = new HashMap<>();
-            map2.put("year", 2024);
-            map2.put("area", 18900.35);
-
-            Map<String, Object> map3 = new HashMap<>();
-            map3.put("year", 2025);
-            map3.put("area", 2000.35);
-            areaTrendStatisticsList.addAll(List.of(map1, map2, map3));
-            res.setAreaTrendStatisticsList(areaTrendStatisticsList);
-
-            // --------------下面为供地方式list----------------------
-            Map<String, Object> modeMap1 = new HashMap<>();
-            modeMap1.put("year", 2023);
-            modeMap1.put("transferArea", 587.7); // 出让
-            modeMap1.put("allocateArea", 500.5); // 划拨区域
-            modeMap1.put("otherArea", 498.23); // 其它区域面积
-            supplyModeStatisticsList.add(modeMap1);
-
-            Map<String, Object> modeMap2 = new HashMap<>();
-            modeMap2.put("year", 2024);
-            modeMap2.put("transferArea", 487.7); // 出让
-            modeMap2.put("allocateArea", 400.5); // 划拨区域
-            modeMap2.put("otherArea", 398.23); // 其它区域面积
-            supplyModeStatisticsList.add(modeMap2);
-
-            Map<String, Object> modeMap3 = new HashMap<>();
-            modeMap3.put("year", 2025);
-            modeMap3.put("transferArea", 487.7); // 出让
-            modeMap3.put("allocateArea", 400.5); // 划拨区域
-            modeMap3.put("otherArea", 398.23); // 其它区域面积
-            supplyModeStatisticsList.add(modeMap2);
-            res.setSupplyModeStatisticsList(supplyModeStatisticsList);
+            //todo 调用相关方法,获取数据,封装成LandSupplyReportDTO对象
+            LandSupplyReportDTO res =  supplyService.getTdgyReport(startTime,endTime);
             return R.ok(res);
         } catch (Exception e) {
             return R.fail(e.getMessage());
@@ -234,74 +89,17 @@ public class SupplyController extends BaseController {
     }
 
 
-
-
-
-
-    @GetMapping("/getTestList")
-    public R<String> getTestList(String param) {
-        //ogr.RegisterAll();
-        Driver driver = ogr.GetDriverByName("OpenFileGDB");
-        String gdbPath = "C:\\Users\\Administrator\\Desktop\\06\\KJGH.gdb";
-        DataSource ds = driver.Open(gdbPath, 0);
-        if (ds == null) {
-            System.out.println("无法打开 gdb");
-            return null;
-        }
-
-        System.out.println("图层数量: " + ds.GetLayerCount());
-        for (int i = 0; i < ds.GetLayerCount(); i++) {
-            Layer layer = ds.GetLayer(i);
-            printLayerInfo(layer);
-        }
-        ds.delete();
-        return null;
-    }
-
-
-
-
-
-    private static void printLayerInfo(Layer layer) {
-        System.out.println("=============");
-        System.out.println("图层名: " + layer.GetName());
-        System.out.println("要素数: " + layer.GetFeatureCount());
-        System.out.println("几何类型: " + layer.GetGeomType());
-
-        // 字段信息
-        FeatureDefn defn = layer.GetLayerDefn();
-        System.out.println("字段数: " + defn.GetFieldCount());
-        for (int i = 0; i < defn.GetFieldCount(); i++) {
-            FieldDefn field = defn.GetFieldDefn(i);
-            System.out.println(
-                    field.GetName() + " | " +
-                            field.GetFieldTypeName(field.GetFieldType())
-            );
-        }
-
-        // 坐标系
-        SpatialReference sr = layer.GetSpatialRef();
-        if (sr != null) {
-            System.out.println("EPSG: " + sr.GetAuthorityCode(null));
-            System.out.println(sr.ExportToWkt());
-        }
-    }
-
-
-
-
-
     /**
+     *
      *
      * 根据时间范围查询土地供应统计报表数据
-     * 土地供应统计报表
+     * 供应用途分析报表
      *
      */
-    @GetMapping("/report/progress")
-    public R<LandSupplyReportDTO> getTdgyReport(@RequestParam String startTime, @RequestParam String endTime) {
+    @GetMapping("/report/purpose")
+    public R<LandSupplyReportVO> getTdgyPurposeReport(@RequestParam String startYear, @RequestParam String endYear) {
         try {
-            //todo 调用相关方法,获取数据,封装成LandSupplyReportDTO对象
-            LandSupplyReportDTO res =  supplyService.getTdgyReport(startTime,endTime);
+            LandSupplyReportVO res =  supplyService.getTdgyPurposeReport(startYear,endYear);
             return R.ok(res);
         } catch (Exception e) {
             return R.fail(e.getMessage());
@@ -311,9 +109,4 @@ public class SupplyController extends BaseController {
 
 
 
-
-
-
-
-
 }

+ 108 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/vo/LandSupplyPurposeReportVO.java

@@ -0,0 +1,108 @@
+package com.siwei.apply.domain.vo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 供应用途分析报表VO
+ */
+public class LandSupplyPurposeReportVO {
+
+    /** 年份列表 */
+    private List<Integer> years;
+
+    /** 报表数据 */
+    private List<LandTypeData> data;
+
+    public List<Integer> getYears() {
+        return years;
+    }
+
+    public void setYears(List<Integer> years) {
+        this.years = years;
+    }
+
+    public List<LandTypeData> getData() {
+        return data;
+    }
+
+    public void setData(List<LandTypeData> data) {
+        this.data = data;
+    }
+
+    /**
+     * 用地类型数据
+     */
+    public static class LandTypeData {
+        /** 用地类型名称 */
+        private String landType;
+
+        /** 总计(出让+划拨) */
+        private CategoryData total;
+
+        /** 出让数据 */
+        private CategoryData transfer;
+
+        /** 划拨数据 */
+        private CategoryData allocation;
+
+        public String getLandType() {
+            return landType;
+        }
+
+        public void setLandType(String landType) {
+            this.landType = landType;
+        }
+
+        public CategoryData getTotal() {
+            return total;
+        }
+
+        public void setTotal(CategoryData total) {
+            this.total = total;
+        }
+
+        public CategoryData getTransfer() {
+            return transfer;
+        }
+
+        public void setTransfer(CategoryData transfer) {
+            this.transfer = transfer;
+        }
+
+        public CategoryData getAllocation() {
+            return allocation;
+        }
+
+        public void setAllocation(CategoryData allocation) {
+            this.allocation = allocation;
+        }
+    }
+
+    /**
+     * 类别数据(合计/出让/划拨)
+     */
+    public static class CategoryData {
+        /** 该类别总计 */
+        private Double total;
+
+        /** 各年份数据 */
+        private Map<String, Double> yearData;
+
+        public Double getTotal() {
+            return total;
+        }
+
+        public void setTotal(Double total) {
+            this.total = total;
+        }
+
+        public Map<String, Double> getYearData() {
+            return yearData;
+        }
+
+        public void setYearData(Map<String, Double> yearData) {
+            this.yearData = yearData;
+        }
+    }
+}

+ 40 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/vo/LandSupplyReportVO.java

@@ -0,0 +1,40 @@
+package com.siwei.apply.domain.vo;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class LandSupplyReportVO {
+
+    /** 年份列表 */
+    private List<Integer> years;
+
+    /** 报表数据 */
+    private List<LandTypeData> data;
+
+    @Data
+    public static class LandTypeData {
+        /** 用地类型名称 */
+        private String landType;
+
+        /** 总计(出让+划拨) */
+        private CategoryData total;
+
+        /** 出让数据 */
+        private CategoryData transfer;
+
+        /** 划拨数据 */
+        private CategoryData allocation;
+    }
+
+    @Data
+    public static class CategoryData {
+        /** 该类别总计 */
+        private Double total;
+
+        /** 各年份数据 */
+        private Map<String, Double> yearData;
+    }
+}

+ 6 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/LandTypeMapper.java

@@ -11,5 +11,11 @@ public interface LandTypeMapper {
     List<LandType> selectAll();
 
     LandType  selectByCode(String code);
+
+    /** 查询所有一级地块类型 */
+    List<LandType> selectFirstLevel();
+
+
+
 }
 

+ 1 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/TdgyMapper.java

@@ -59,7 +59,7 @@ public interface TdgyMapper {
     List<ProjectSupplyRes> countAndSumByGdType(@Param("projectType") Integer projectType);
 
 
-    List<TdgyStatisticsRes> getListByYear(@Param("year") String year,@Param("landTypeCode") String landTypeCode);
+    List<TdgyStatisticsRes> getListByYear(@Param("year") String year,@Param("landTypeCode") String landTypeCode, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
 
 

+ 4 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/ISupplyService.java

@@ -4,6 +4,8 @@ package com.siwei.apply.service.cadastre;
 import com.siwei.apply.domain.cadastre.LandSupplyReportDTO;
 import com.siwei.apply.domain.res.SupplyYearStatisticsRes;
 import com.siwei.apply.domain.res.TrendStatisticsRes;
+import com.siwei.apply.domain.vo.LandSupplyPurposeReportVO;
+import com.siwei.apply.domain.vo.LandSupplyReportVO;
 import com.siwei.common.core.domain.R;
 
 
@@ -11,12 +13,14 @@ public interface ISupplyService {
     Object GetList(String param);
 
     LandSupplyReportDTO getTdgyReport(String startTime,String endTime); //  supplyService.getTdgyReport(startTime,endTime);
+    LandSupplyReportDTO getTdgyReport222(String startTime,String endTime); //  supplyService.getTdgyReport(startTime,endTime);
 
 
     SupplyYearStatisticsRes yearStatistics(String year);
 
     TrendStatisticsRes trendStatistics(String landType);
 
+    LandSupplyReportVO getTdgyPurposeReport(String startYear, String endYear);
 
 
 }

+ 279 - 9
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/SupplyServiceImpl.java

@@ -5,6 +5,7 @@ import com.siwei.apply.domain.LandType;
 import com.siwei.apply.domain.cadastre.*;
 import com.siwei.apply.domain.res.*;
 import com.siwei.apply.domain.vo.GongdiJihuaFilterVo;
+import com.siwei.apply.domain.vo.LandSupplyReportVO;
 import com.siwei.apply.enums.LandUseTypeEnum;
 import com.siwei.apply.mapper.GongdiJihuaMapper;
 import com.siwei.apply.mapper.LandTypeMapper;
@@ -35,7 +36,6 @@ public class SupplyServiceImpl implements ISupplyService {
     @Override
     public Object GetList(String param) {
 
-        ///Map<String, Object> planSummary = gongdiJihuaMapper.getList(startTime, endTime);
 
         return null;
     }
@@ -53,11 +53,7 @@ public class SupplyServiceImpl implements ISupplyService {
         filterVo.setYear(year);
         filterVo.setPageSize(100000);
         List<GongdiJihua> list = gongdiJihuaMapper.getList(filterVo);
-        List<TdgyStatisticsRes> completeList = dgyMapper.getListByYear(year,null);
-
-
-
-
+        List<TdgyStatisticsRes> completeList = dgyMapper.getListByYear(year, null, null, null);
 
         if(CollectionUtils.isNotEmpty(list)) {
             double completeRate =0;
@@ -193,7 +189,7 @@ public class SupplyServiceImpl implements ISupplyService {
     @Override
     public TrendStatisticsRes trendStatistics(String landType) {
 
-        List<TdgyStatisticsRes> completeList = dgyMapper.getListByYear(null, landType);
+        List<TdgyStatisticsRes> completeList = dgyMapper.getListByYear(null, landType, null, null);
 
         TrendStatisticsRes res = new TrendStatisticsRes();
         List<Map<String, Object>> areaTrendStatisticsList = new ArrayList<>();
@@ -244,18 +240,281 @@ public class SupplyServiceImpl implements ISupplyService {
     }
 
 
+    @Override
+    public LandSupplyReportDTO getTdgyReport(String startTime, String endTime) {
+        LandSupplyReportDTO report = new LandSupplyReportDTO();
+        report.setTitle("土地供应进度分析报表");
+        report.setStatTimeRange(startTime + " 至 " + endTime);
+
+        // 获取时间范围内的完成数据
+        List<TdgyStatisticsRes> completeList = dgyMapper.getListByYear(null, null, startTime, endTime);
+
+        // 获取时间范围内的计划数据
+        Map<String, Object> planSummary = gongdiJihuaMapper.getPlanSummaryByTimeRange(startTime, endTime);
+        List<Map<String, Object>> planStatsByLandType = gongdiJihuaMapper.getPlanStatsByLandType(startTime, endTime);
+
+        // 获取所有一级分类
+        List<LandType> landTypeList = landTypeMapper.selectFirstLevel();
+        Map<String, String> codeToFirstName = landTypeList.stream()
+                .collect(Collectors.toMap(LandType::getCode, LandType::getName, (v1, v2) -> v1));
+
+        // 按一级分类名称汇总统计数据的 Map
+        Map<String, LandSupplyReportDTO.DetailDTO> detailMap = new HashMap<>();
+
+        // 1. 统计计划数据并按一级分类归类
+        for (Map<String, Object> landTypeStat : planStatsByLandType) {
+            String category = (String) landTypeStat.get("category");
+            String parentName = "其他";
+            
+            // 通过枚举查找对应的一级分类名称
+            for (LandUseTypeEnum type : LandUseTypeEnum.values()) {
+                if (type.getName().equals(category)) {
+                    parentName = type.getParentName();
+                    break;
+                }
+            }
+
+            LandSupplyReportDTO.DetailDTO detail = detailMap.computeIfAbsent(parentName, k -> {
+                LandSupplyReportDTO.DetailDTO d = new LandSupplyReportDTO.DetailDTO();
+                d.setCategory(k);
+                d.setPlan(new LandSupplyReportDTO.PlanDTO());
+                d.getPlan().setArea(0.0);
+                d.getPlan().setCount(0);
+                d.getPlan().setTransfer(0.0);
+                d.getPlan().setAllocation(0.0);
+                d.getPlan().setOther(0.0);
+                d.setCompleted(new LandSupplyReportDTO.CompletedDTO());
+                d.getCompleted().setArea(0.0);
+                d.getCompleted().setCount(0);
+                d.getCompleted().setTransfer(0.0);
+                d.getCompleted().setAllocation(0.0);
+                d.getCompleted().setOther(0.0);
+                return d;
+            });
+
+            LandSupplyReportDTO.PlanDTO plan = detail.getPlan();
+            plan.setArea(plan.getArea() + toDouble(landTypeStat.get("planmu")));
+            plan.setCount(plan.getCount() + toInteger(landTypeStat.get("plancount")));
+            plan.setTransfer(plan.getTransfer() + toDouble(landTypeStat.get("plantransfer")));
+            plan.setAllocation(plan.getAllocation() + toDouble(landTypeStat.get("planallocation")));
+            plan.setOther(plan.getOther() + toDouble(landTypeStat.get("planother")));
+        }
+
+        // 2. 统计完成数据并按一级分类归类
+        if (CollectionUtils.isNotEmpty(completeList)) {
+            for (TdgyStatisticsRes item : completeList) {
+                String tdyt = item.getTdyt();
+                String parentName = "其他";
+                if (tdyt != null && tdyt.length() >= 2) {
+                    String firstLevelCode = tdyt.substring(0, 2);
+                    parentName = codeToFirstName.getOrDefault(firstLevelCode, "其他");
+                }
+
+                LandSupplyReportDTO.DetailDTO detail = detailMap.computeIfAbsent(parentName, k -> {
+                    LandSupplyReportDTO.DetailDTO d = new LandSupplyReportDTO.DetailDTO();
+                    d.setCategory(k);
+                    d.setPlan(new LandSupplyReportDTO.PlanDTO());
+                    d.getPlan().setArea(0.0);
+                    d.getPlan().setCount(0);
+                    d.getPlan().setTransfer(0.0);
+                    d.getPlan().setAllocation(0.0);
+                    d.getPlan().setOther(0.0);
+                    d.setCompleted(new LandSupplyReportDTO.CompletedDTO());
+                    d.getCompleted().setArea(0.0);
+                    d.getCompleted().setCount(0);
+                    d.getCompleted().setTransfer(0.0);
+                    d.getCompleted().setAllocation(0.0);
+                    d.getCompleted().setOther(0.0);
+                    return d;
+                });
+
+                LandSupplyReportDTO.CompletedDTO completed = detail.getCompleted();
+                double area = item.getMjMu() != null ? item.getMjMu().doubleValue() : 0.0;
+                completed.setArea(completed.getArea() + area);
+                completed.setCount(completed.getCount() + 1);
+                
+                String gyfs = item.getGyfs();
+                if ("出让".equals(gyfs)) {
+                    completed.setTransfer(completed.getTransfer() + area);
+                } else if ("划拨".equals(gyfs)) {
+                    completed.setAllocation(completed.getAllocation() + area);
+                } else {
+                    completed.setOther(completed.getOther() + area);
+                }
+            }
+        }
+
+        // 3. 构建 Summary
+        LandSupplyReportDTO.SummaryDTO summary = new LandSupplyReportDTO.SummaryDTO();
+        LandSupplyReportDTO.TotalDTO total = buildTotalDTO(planSummary);
+        
+        // 重新计算 Total 的 Completed 部分,因为之前 buildTotalDTO 填充的是 0
+        if (CollectionUtils.isNotEmpty(completeList)) {
+            double totalArea = completeList.stream().filter(g -> g.getMjMu() != null).mapToDouble(g -> g.getMjMu().doubleValue()).sum();
+            double totalTransfer = completeList.stream().filter(g -> "出让".equals(g.getGyfs()) && g.getMjMu() != null).mapToDouble(g -> g.getMjMu().doubleValue()).sum();
+            double totalAllocation = completeList.stream().filter(g -> "划拨".equals(g.getGyfs()) && g.getMjMu() != null).mapToDouble(g -> g.getMjMu().doubleValue()).sum();
+            double totalOther = totalArea - totalTransfer - totalAllocation;
+            
+            total.setCompleted(buildCompletedDTO(totalArea, completeList.size(), totalTransfer, totalAllocation, totalOther));
+            
+            double planArea = total.getPlan().getArea();
+            if (planArea > 0) {
+                total.setSupplyRate(String.format("%.2f%%", (totalArea / planArea) * 100));
+            } else {
+                total.setSupplyRate("0%");
+            }
+        }
+        
+        summary.setTotal(total);
+        report.setSummary(summary);
+
+        // 4. 构建 Details 列表并计算供应率
+        List<LandSupplyReportDTO.DetailDTO> details = new ArrayList<>(detailMap.values());
+        for (LandSupplyReportDTO.DetailDTO detail : details) {
+            double planArea = detail.getPlan().getArea();
+            double completedArea = detail.getCompleted().getArea();
+            if (planArea > 0) {
+                detail.setSupplyRate(String.format("%.2f%%", (completedArea / planArea) * 100));
+            } else {
+                detail.setSupplyRate("0%");
+            }
+        }
+        
+        // 按计划面积排序
+        details.sort((d1, d2) -> d2.getPlan().getArea().compareTo(d1.getPlan().getArea()));
+        report.setDetails(details);
+
+        return report;
+    }
+
+
 
 
 
     @Override
-    public LandSupplyReportDTO getTdgyReport(String startTime, String endTime) {
+    public LandSupplyReportVO getTdgyPurposeReport(String startYear, String endYear){
+        List<TdgyStatisticsRes> completeList2 = dgyMapper.getListByYear(null, null, startYear, endYear);
+
+        SupplyYearStatisticsRes res = new SupplyYearStatisticsRes();
+        GongdiJihuaFilterVo filterVo = new GongdiJihuaFilterVo();
+        filterVo.setPageSize(100000);
+        List<GongdiJihua> completeList = gongdiJihuaMapper.getList(filterVo);
+
+
+
+
+
+        if (CollectionUtils.isEmpty(completeList)) {
+            return new LandSupplyReportVO();
+        }
+
+        LandSupplyReportVO report = new LandSupplyReportVO();
+        
+        // 1. 获取一级分类映射
+        List<LandType> landTypeList = landTypeMapper.selectFirstLevel();
+        Map<String, String> codeToFirstName = landTypeList.stream()
+                .collect(Collectors.toMap(LandType::getCode, LandType::getName, (v1, v2) -> v1));
+
+        // 2. 统计年份并排序
+        Set<Integer> yearSet = new TreeSet<>();
+        for (GongdiJihua item : completeList) {
+            if (item.getGysj() != null) {
+                yearSet.add(item.getGysj().getYear() + 1900);
+            }
+        }
+        report.setYears(new ArrayList<>(yearSet));
+
+        // 3. 按一级分类、供应方式、年份进行汇总统计
+        // Map<一级分类名称, Map<供应方式, Map<年份, 面积汇总>>>
+        Map<String, Map<String, Map<String, Double>>> stats = new HashMap<>();
+
+        for (GongdiJihua item : completeList) {
+            if (item.getGysj() == null || item.getTdyt() == null || item.getTdyt().length() < 2) continue;
+            String firstLevelCode  = LandUseTypeEnum.getCodeByName(item.getTdyt());
+            //String firstLevelCode = item.getTdyt().substring(0, 2);
+            String parentName = codeToFirstName.getOrDefault(firstLevelCode, "其他");
+            String year = String.valueOf(item.getGysj().getYear() + 1900);
+            String gyfs = "划拨".equals(item.getGyfs()) ? "划拨" : ("出让".equals(item.getGyfs()) ? "出让" : "其他");
+            double area = item.getMjMu() != null ? item.getMjMu().doubleValue() : 0.0;
+
+            stats.computeIfAbsent(parentName, k -> new HashMap<>())
+                 .computeIfAbsent(gyfs, k -> new HashMap<>())
+                 .merge(year, area, Double::sum);
+        }
+
+        // 4. 构建返回对象数据
+        List<LandSupplyReportVO.LandTypeData> dataList = new ArrayList<>();
+        
+        for (LandType lt : landTypeList) {
+            String parentName = lt.getName();
+            Map<String, Map<String, Double>> modeMap = stats.get(parentName);
+            if (modeMap == null) continue;
+
+            LandSupplyReportVO.LandTypeData landTypeData = new LandSupplyReportVO.LandTypeData();
+            landTypeData.setLandType(parentName);
+
+            // 划拨数据
+            landTypeData.setAllocation(buildCategoryData(modeMap.get("划拨"), report.getYears()));
+            // 出让数据
+            landTypeData.setTransfer(buildCategoryData(modeMap.get("出让"), report.getYears()));
+            
+            // 总计数据
+            LandSupplyReportVO.CategoryData totalData = new LandSupplyReportVO.CategoryData();
+            Map<String, Double> totalYearData = new HashMap<>();
+            double grandTotal = 0.0;
+            for (Integer y : report.getYears()) {
+                String yearStr = String.valueOf(y);
+                double areaSum = 0.0;
+                if (modeMap.get("划拨") != null) areaSum += modeMap.get("划拨").getOrDefault(yearStr, 0.0);
+                if (modeMap.get("出让") != null) areaSum += modeMap.get("出让").getOrDefault(yearStr, 0.0);
+                if (modeMap.get("其他") != null) areaSum += modeMap.get("其他").getOrDefault(yearStr, 0.0);
+                
+                totalYearData.put(yearStr, areaSum);
+                grandTotal += areaSum;
+            }
+            totalData.setTotal(grandTotal);
+            totalData.setYearData(totalYearData);
+            landTypeData.setTotal(totalData);
+
+            dataList.add(landTypeData);
+        }
+        report.setData(dataList);
+
+        return report;
+    }
+
+    private LandSupplyReportVO.CategoryData buildCategoryData(Map<String, Double> yearCounts, List<Integer> years) {
+        LandSupplyReportVO.CategoryData data = new LandSupplyReportVO.CategoryData();
+        Map<String, Double> yearData = new HashMap<>();
+        double total = 0.0;
+        for (Integer y : years) {
+            String yearStr = String.valueOf(y);
+            double areaSum = yearCounts != null ? yearCounts.getOrDefault(yearStr, 0.0) : 0.0;
+            yearData.put(yearStr, areaSum);
+            total += areaSum;
+        }
+        data.setTotal(total);
+        data.setYearData(yearData);
+        return data;
+    }
+
+
+
+
+
+
+
+
+
+    @Override
+    public LandSupplyReportDTO getTdgyReport222(String startTime, String endTime) {
         LandSupplyReportDTO report = new LandSupplyReportDTO();
         report.setTitle("土地供应统计报表");
         report.setStatTimeRange(startTime + " 至 " + endTime);
 
         Map<String, Object> planSummary = gongdiJihuaMapper.getPlanSummaryByTimeRange(startTime, endTime);
         List<Map<String, Object>> planStatsByLandType = gongdiJihuaMapper.getPlanStatsByLandType(startTime, endTime);
-        List<Map<String, Object>> planStatsBySupplyMode = gongdiJihuaMapper.getPlanStatsBySupplyMode(startTime, endTime);
+        //List<Map<String, Object>> planStatsBySupplyMode = gongdiJihuaMapper.getPlanStatsBySupplyMode(startTime, endTime);
 
         LandSupplyReportDTO.SummaryDTO summary = new LandSupplyReportDTO.SummaryDTO();
         LandSupplyReportDTO.TotalDTO total = buildTotalDTO(planSummary);
@@ -276,6 +535,7 @@ public class SupplyServiceImpl implements ISupplyService {
         return report;
     }
 
+
     private LandSupplyReportDTO.TotalDTO buildTotalDTO(Map<String, Object> summary) {
         LandSupplyReportDTO.TotalDTO total = new LandSupplyReportDTO.TotalDTO();
         total.setSupplyRate("0%");
@@ -309,6 +569,16 @@ public class SupplyServiceImpl implements ISupplyService {
         return plan;
     }
 
+    private LandSupplyReportDTO.CompletedDTO buildCompletedDTO(Double area, Integer count, Double transfer, Double allocation, Double other) {
+        LandSupplyReportDTO.CompletedDTO completed = new LandSupplyReportDTO.CompletedDTO();
+        completed.setArea(area);
+        completed.setCount(count);
+        completed.setTransfer(transfer);
+        completed.setAllocation(allocation);
+        completed.setOther(other);
+        return completed;
+    }
+
     private String convertCategory(String category) {
         if (category == null || category.equals("未知")) {
             return "其他";

+ 11 - 0
siwei-modules/siwei-apply/src/main/resources/mapper/LandTypeMapper.xml

@@ -20,4 +20,15 @@
     </select>
 
 
+    <select id="selectFirstLevel" resultMap="LandTypeResultMap">
+        SELECT code, name, parent_code, index, source FROM land_type WHERE parent_code is NULL  ORDER BY index
+    </select>
+
+
+
+
+
+
+
+
 </mapper>

+ 7 - 1
siwei-modules/siwei-apply/src/main/resources/mapper/TdgyMapper.xml

@@ -157,7 +157,13 @@
             AND  LEFT(t_node.hbcrht_date, 4) = #{year}
         </if>
         <if test="landTypeCode != null">
-            LEFT(t_node.tdyt,2)=#{landTypeCode}
+            AND LEFT(t_node.tdyt,2)=#{landTypeCode}
+        </if>
+        <if test="startTime != null and startTime != ''">
+            AND t_node.hbcrht_date &gt;= #{startTime}
+        </if>
+        <if test="endTime != null and endTime != ''">
+            AND t_node.hbcrht_date &lt;= #{endTime}
         </if>
     </select>