Procházet zdrojové kódy

Merge branch 'dev-excel0521' into dev-to-user-1

chenendian před 3 dny
rodič
revize
e538d75472
49 změnil soubory, kde provedl 2786 přidání a 290 odebrání
  1. 222 2
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/common/Constant.java
  2. 5 5
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/JsydghxkController.java
  3. 3 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/ProjectController.java
  4. 19 2
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/CadastreManageController.java
  5. 371 48
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/ReportBatchController.java
  6. 105 67
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/StorageController.java
  7. 26 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/SupplyController.java
  8. 22 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/third/DealExcelController.java
  9. 2 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/CadastreFile.java
  10. 2 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/Tdgy.java
  11. 4 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/YdbpData.java
  12. 13 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/res/JsydghxkRes.java
  13. 3 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/res/TrendUseStatisticsData.java
  14. 40 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/vo/BatchTrendReportVO.java
  15. 1 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/vo/LandSupplyProjectVO.java
  16. 5 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/GjShijiShouchuMapper.java
  17. 2 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/NodeLandMapper.java
  18. 2 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/ProjectWorkflowMapper.java
  19. 1 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/TdgyMapper.java
  20. 7 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/YdbpDataMapper.java
  21. 4 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/YdbpMapper.java
  22. 1 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/cadastre/ZdjbxxMapper.java
  23. 2 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/JsydghxkService.java
  24. 1 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/NodeLandService.java
  25. 4 2
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/CadastreManageService.java
  26. 3 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/ISupplyService.java
  27. 499 20
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/BatchServiceImpl.java
  28. 168 14
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/CadastreManageServiceImpl.java
  29. 38 21
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/ParcelServiceImpl.java
  30. 331 11
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/StorageServiceImpl.java
  31. 190 18
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/SupplyServiceImpl.java
  32. 16 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/JsydghxkImpl.java
  33. 11 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/NodeLandImpl.java
  34. 6 0
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/ProjectImpl.java
  35. 12 30
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/TdgyImpl.java
  36. 223 14
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/third/impl/DealExcelServiceImpl.java
  37. 1 1
      siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/third/impl/TakeDataServiceImpl.java
  38. 1 1
      siwei-modules/siwei-apply/src/main/resources/mapper/FwmxMapper.xml
  39. 42 2
      siwei-modules/siwei-apply/src/main/resources/mapper/GjShijiShouchuMapper.xml
  40. 6 1
      siwei-modules/siwei-apply/src/main/resources/mapper/GjShouchuJihuaMapper.xml
  41. 1 1
      siwei-modules/siwei-apply/src/main/resources/mapper/GongdiJihuaMapper.xml
  42. 1 1
      siwei-modules/siwei-apply/src/main/resources/mapper/JsydghxkMapper.xml
  43. 17 0
      siwei-modules/siwei-apply/src/main/resources/mapper/NodeLandMapper.xml
  44. 13 0
      siwei-modules/siwei-apply/src/main/resources/mapper/ProjectWorkflowMapper.xml
  45. 47 1
      siwei-modules/siwei-apply/src/main/resources/mapper/TdgyMapper.xml
  46. 166 15
      siwei-modules/siwei-apply/src/main/resources/mapper/YdbpDataMapper.xml
  47. 112 3
      siwei-modules/siwei-apply/src/main/resources/mapper/YdbpMapper.xml
  48. 10 2
      siwei-modules/siwei-apply/src/main/resources/mapper/cadastre/ZdjbxxMapper.xml
  49. 5 0
      siwei-modules/siwei-apply/src/main/resources/mapper/cadastre/ZrzMapper.xml

+ 222 - 2
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/common/Constant.java

@@ -1,5 +1,7 @@
 package com.siwei.apply.common;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -102,6 +104,225 @@ public class Constant {
             "DX2026"
     );
 
+
+    public static final List<String> BDCDYH_LIST = new ArrayList<>(Arrays.asList(
+            "360122009006GB00002W00000000",
+            "360122009006GB00159W00000000",
+            "360122009006GB00160W00000000",
+            "360122009006GB00161W00000000",
+            "360122009006GB60008W00000000",
+            "360122009006GB60107W00000000",
+            "360122009006GB60168W00000000",
+            "360122009006GB60169W00000000",
+            "360122009006GB60170W00000000",
+            "360122009006GB60171W00000000",
+            "360122009006GB60182W00000000",
+            "360122009006GB60183W00000000",
+            "360122009006GB60190W00000000",
+            "360122009006GB60242W00000000",
+            "360122009006GB60243W00000000",
+            "360122009006GB60273W00000000",
+            "360122009015GB00006W00000000",
+            "360122009015GB00013W00000000",
+            "360122009015GB00015W00000000",
+            "360122009015GB00016W00000000",
+            "360122009015GB60002W00000000",
+            "360122009015GB60053W00000000",
+            "360122009015GB60056W00000000",
+            "360122009015GB60057W00000000",
+            "360122009015GB60058W00000000",
+            "360122009015GB60059W00000000",
+            "360122009015GB60060W00000000",
+            "360122011002GB00004W00000000",
+            "360122011002GB00008W00000000",
+            "360122011002GB00013W00000000",
+            "360122011002GB00029W00000000",
+            "360122011002GB00030W00000000",
+            "360122011002GB00031W00000000",
+            "360122011002GB00308W00000000",
+            "360122011002GB60006W00000000",
+            "360122011002GB60007W00000000",
+            "360122011002GB60012W00000000",
+            "360122011002GB60013W00000000",
+            "360122011003GB00077W00000000",
+            "360122011003GB00246W00000000",
+            "360122011003GB00332W00000000",
+            "360122011003GB00333W00000000",
+            "360122011003GB00334W00000000",
+            "360122011003GB00335W00000000",
+            "360122011003GB00486W00000000",
+            "360122011004GB00381W00000000",
+            "360122011004GB00383W00000000",
+            "360122011004GB00389W00000000",
+            "360122011004GB00391W00000000",
+            "360122011004GB00392W00000000",
+            "360122011004GB00393W00000000",
+            "360122011004GB00394W00000000",
+            "360122011004GB00395W00000000",
+            "360122011004GB00418W00000000",
+            "360122011004GB00419W00000000",
+            "360122011004GB00533W00000000",
+            "360122011004GB00534W00000000",
+            "360122011005GB00002W00000000",
+            "360122011005GB00003W00000000",
+            "360122011005GB60002W00000000",
+            "360122011005GB60003W00000000",
+            "360122011005GB60005W00000000",
+            "360122011005GB60006W00000000",
+            "360122011006GB00001W00000000",
+            "360122011006GB00002W00000000",
+            "360122011006GB00007W00000000",
+            "360122011006GB00008W00000000",
+            "360122011006GB00009W00000000",
+            "360122011006GB00319W00000000",
+            "360122011006GB00320W00000000",
+            "360122011007GB00002W00000000",
+            "360122011007GB00005W00000000",
+            "360122011007GB00009W00000000",
+            "360122011007GB00016W00000000",
+            "360122011007GB00310W00000000",
+            "360122011007GB00324W00000000",
+            "360122011007GB00333W00000000",
+            "360122011007GB00336W00000000",
+            "360122011007GB00337W00000000",
+            "360122011007GB00338W00000000",
+            "360122011007GB00340W00000000",
+            "360122011007GB00341W00000000",
+            "360122011009GB00334W00000000",
+            "360122011009GB00335W00000000",
+            "360122011010GB00018W00000000",
+            "360122011010GB00021W00000000",
+            "360122011010GB00308W00000000",
+            "360122011010GB00312W00000000",
+            "360122011010GB00318W00000000",
+            "360122011010GB00319W00000000",
+            "360122011010GB60011W00000000",
+            "360122013029GB60001W00000000",
+            "360122014003GB00011W00000000",
+            "360122014003GB00045W00000000",
+            "360122014003GB00115W00000000",
+            "360122014003GB60001W00000000",
+            "360122014003GB60002W00000000",
+            "360122014003GB60003W00000000",
+            "360122014003GB60014W00000000",
+            "360122014003GB62229W00000000",
+            "360122014003GB62230W00000000",
+            "360122014003GB62231W00000000",
+            "360122014003GB62232W00000000",
+            "360122014003GB62233W00000000",
+            "360122014003GB62234W00000000",
+            "360122014003GB62235W00000000",
+            "360122014003GB62236W00000000",
+            "360122014003GB62237W00000000",
+            "360122014003GB62238W00000000",
+            "360122014003GB62243W00000000",
+            "360122014003GB62270W00000000",
+            "360122014003GB62277W00000000",
+            "360122014003GB62280W00000000",
+            "360122014003GB62302W00000000",
+            "360122014003GB62305W00000000",
+            "360122014003GB62306W00000000",
+            "360122014003GB62307W00000000",
+            "360122014003GB62309W00000000",
+            "360122014003GB62310W00000000",
+            "360122014003GB62317W00000000",
+            "360122014003GB62328W00000000",
+            "360122014003GB62340W00000000",
+            "360122014003GB62341W00000000",
+            "360122014003GB62360W00000000",
+            "360122014003GB62361W00000000",
+            "360122014003GB62362W00000000",
+            "360122014003GB62367W00000000",
+            "360122014003GB62368W00000000",
+            "360122014004GB00071W00000000",
+            "360122014004GB00072W00000000",
+            "360122014004GB00073W00000000",
+            "360122014004GB00074W00000000",
+            "360122014004GB00075W00000000",
+            "360122014004GB00076W00000000",
+            "360122014004GB00077W00000000",
+            "360122014004GB00078W00000000",
+            "360122014004GB00079W00000000",
+            "360122014004GB00081W00000000",
+            "360122014004GB00083W00000000",
+            "360122014004GB00084W00000000",
+            "360122014004GB00085W00000000",
+            "360122014004GB00086W00000000",
+            "360122014004GB00087W00000000",
+            "360122014004GB00088W00000000",
+            "360122014004GB00089W00000000",
+            "360122014004GB00090W00000000",
+            "360122014004GB00092W00000000",
+            "360122014004GB00094W00000000",
+            "360122014004GB00098W00000000",
+            "360122014004GB00099W00000000",
+            "360122014004GB00104W00000000",
+            "360122014004GB00105W00000000",
+            "360122014004GB00106W00000000",
+            "360122014004GB00107W00000000",
+            "360122014004GB00108W00000000",
+            "360122014004GB00109W00000000",
+            "360122014004GB00110W00000000",
+            "360122014004GB00111W00000000",
+            "360122014004GB00113W00000000",
+            "360122014004GB00114W00000000",
+            "360122014004GB00121W00000000",
+            "360122014004GB00128W00000000",
+            "360122014004GB00129W00000000",
+            "360122014004GB60001W00000000",
+            "360122014004GB60006W00000000",
+            "360122014004GB60017W00000000",
+            "360122014004GB60018W00000000",
+            "360122014004GB60024W00000000",
+            "360122014004GB60035W00000000",
+            "360122014005GB00044W00000000",
+            "360122014005GB00046W00000000",
+            "360122014005GB00047W00000000",
+            "360122014005GB00048W00000000",
+            "360122014005GB00050W00000000",
+            "360122014005GB60001W00000000",
+            "360122014005GB60012W00000000",
+            "360122014008GB00050W00000000",
+            "360122015001GB60001W00000000",
+            "360122015001GB60010W00000000",
+            "360122015001GB60011W00000000",
+            "360122015001GB60012W00000000",
+            "360122015001GB60013W00000000",
+            "360122015001GB60014W00000000",
+            "360122015001GB70001W00000000",
+            "360122015001GB70002W00000000",
+            "360122015002GB00001W00000000",
+            "360122015002GB00002W00000000",
+            "360122015002GB00003W00000000",
+            "360122015002GB00005W00000000",
+            "360122015002GB00019W00000000",
+            "360122015002GB00020W00000000",
+            "360122015002GB00021W00000000",
+            "360122015002GB00022W00000000",
+            "360122015002GB00023W00000000",
+            "360122015002GB00024W00000000",
+            "360122015002GB00025W00000000",
+            "360122015003GB00003W00000000",
+            "360122015003GB00004W00000000",
+            "360122015003GB00005W00000000",
+            "360122020005GB00137W00000000",
+            "360122999000GB60002W00000000",
+            "360425001012GB00027W00000000",
+            "360425005005GB60001W00000000",
+            "360425005005GB60003W00000000",
+            "360425005005GB60005W00000000",
+            "360425005005GB60006W00000000",
+            "360425005005GB60007W00000000",
+            "360425005005GB60008W00000000",
+            "360425005005GB60009W00000000",
+            "360425005005GB60014W00000000",
+            "360425005005GB60015W00000000",
+            "360425005005GB60017W00000000"
+    ));
+
+
+
+
     //项目excel导入路径
     //public static final String  IMPORT_EXCEL_DATA_FILE_PATH = "D:\\one_code_manage\\project_excel_data";
     public static final String  IMPORT_EXCEL_DATA_FILE_PATH = "D:\\tmp\\one_code_manage\\excel_deom";
@@ -110,7 +331,6 @@ public class Constant {
 
     public static final String  GG = "GONGGAI";
     public static final String  BDC = "BUDONGCHAN";
-
-
+    public static final String  BDC_FILE_DOWN_PATH = "C:\\Users\\Administrator\\Desktop\\11\\excel_out\\output\\02";
 
 }

+ 5 - 5
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/JsydghxkController.java

@@ -41,10 +41,10 @@ public class JsydghxkController extends BaseController {
     @PostMapping()
     public R<Map> Add(@RequestBody JsydghxkVo jsydghxkVo) {
         try {
-            Boolean b = jsydghxkService.isExit(jsydghxkVo.getProjectId());
-            if (b == true) {
-                return R.fail("此项目已添加建设用地规划许可");
-            }
+//            Boolean b = jsydghxkService.isExit(jsydghxkVo.getProjectId());
+//            if (b == true) {
+//                return R.fail("此项目已添加建设用地规划许可");
+//            }
             String id = jsydghxkService.add(jsydghxkVo);
             Map<String, String> map = new HashMap<>();
             map.put("id", id);
@@ -63,7 +63,7 @@ public class JsydghxkController extends BaseController {
     @GetMapping("/{projectId}")
     public R<JsydghxkRes> Get(@PathVariable String projectId) {
         try {
-            return R.ok(jsydghxkService.get(projectId));
+            return R.ok(jsydghxkService.getAll(projectId));
         } catch (Exception e) {
             return R.fail(e.getMessage());
         }

+ 3 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/ProjectController.java

@@ -10,6 +10,8 @@ import com.siwei.apply.domain.vo.*;
 import com.siwei.apply.service.ProjectService;
 import com.siwei.common.core.domain.R;
 import com.siwei.common.core.web.controller.BaseController;
+import com.siwei.common.log.annotation.Log;
+import com.siwei.common.log.enums.BusinessType;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.ibatis.annotations.Param;
 import org.apache.poi.ss.usermodel.*;
@@ -81,6 +83,7 @@ public class ProjectController extends BaseController {
      *
      * @return
      */
+    @Log(title = "项目列表查询", businessType = BusinessType.OTHER)
     @PostMapping("/list")
     public R<Map<String, Object>> GetList(@RequestBody ProjectFilterVo projectFilterVo) {
         try {

+ 19 - 2
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/CadastreManageController.java

@@ -48,6 +48,23 @@ public class CadastreManageController extends BaseController {
     private IZymlService zymlService;
 
 
+    /**
+     * 宗地变化情况表
+     * @param theFilePath
+     * @param landRightType
+     * @param landChangeMode
+     * @return
+     */
+    @PostMapping("/addLandChangeData")
+    public R<String> landChange(String theFilePath, String landRightType, String landChangeMode) {
+        try {
+            String res = cadastreManageService.addLandChange(theFilePath, landRightType, landChangeMode);
+            return R.ok("success");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
 
 
 
@@ -65,9 +82,9 @@ public class CadastreManageController extends BaseController {
      * @return
      */
     @PostMapping("/checkUploadDquality")
-    public R<CheckInfoResultVo> checkData(String theFileName, String theFilePath, String fileType, String updateType) {
+    public R<CheckInfoResultVo> checkData(String theFileName, String theFilePath, String fileType, String updateType, @RequestParam(required = false,defaultValue = "") String landRightType) {
         try {
-            CheckInfoResultVo res = cadastreManageService.checkFileData(theFileName, theFilePath, fileType, updateType);
+            CheckInfoResultVo res = cadastreManageService.checkFileData(theFileName, theFilePath, fileType, updateType, landRightType);
             return R.ok(res);
         } catch (Exception e) {
             e.printStackTrace();

+ 371 - 48
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/ReportBatchController.java

@@ -1,25 +1,26 @@
 package com.siwei.apply.controller.cadastre;
 
-import com.siwei.apply.domain.GongdiJihua;
-import com.siwei.apply.domain.LandType;
-import com.siwei.apply.domain.cadastre.LandSupplyReportDTO;
+import com.siwei.apply.domain.YdbpData;
 import com.siwei.apply.domain.res.BatchRateRes;
-import com.siwei.apply.domain.res.SupplyYearStatisticsRes;
-import com.siwei.apply.domain.res.TrendStatisticsRes;
-import com.siwei.apply.domain.vo.LandSupplyProjectVO;
+import com.siwei.apply.domain.vo.BatchTrendReportVO;
 import com.siwei.apply.domain.vo.LandSupplyReportVO;
-import com.siwei.apply.domain.vo.YdbpDataFilterVo;
 import com.siwei.apply.service.cadastre.ISupplyService;
 import com.siwei.apply.service.cadastre.impl.BatchServiceImpl;
-import com.siwei.apply.service.cadastre.impl.StorageServiceImpl;
 import com.siwei.common.core.domain.R;
 import com.siwei.common.core.web.controller.BaseController;
+import org.apache.commons.collections4.CollectionUtils;
 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.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -35,11 +36,9 @@ public class ReportBatchController extends BaseController {
     @Autowired
     private ISupplyService supplyService;
 
-
     @Autowired
     private BatchServiceImpl batchServiceImpl;
 
-
     /**
      *
      * 年度统计
@@ -56,19 +55,14 @@ public class ReportBatchController extends BaseController {
         }
     }
 
-
-
-
-
-
     /**
      *
      * 趋势分析
      */
     @GetMapping("/trendStatistics")
-    public R<BatchRateRes> getTrendStatistics() {
+    public R<List<Map<String,Object>>> getTrendStatistics() {
         try {
-            BatchRateRes res =  batchServiceImpl.trendStatistics("");
+            List<Map<String,Object>> res =  batchServiceImpl.trendStatistics("");
             return R.ok(res);
         } catch (Exception e) {
             e.printStackTrace();
@@ -76,52 +70,73 @@ public class ReportBatchController extends BaseController {
         }
     }
 
+    /**
+     * 已批未供数据
+     */
+    @GetMapping("/approval/notSupply")
+    public R<List<Map<String,Object>>> approvalAndNotSupply() {
+        try {
+            List<Map<String,Object>> res = batchServiceImpl.approvalAndNotSupply("");
+            return R.ok(res);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
 
 
 
-
-
-
-
-
-
-
+    /**
+     *
+     * @param year
+     * @return
+     */
+    @GetMapping("/notSupply/list")
+    public R<List<?>> getNotSupplyList(@RequestParam(required = false) String year) {
+        try {
+            List<?> resList =  batchServiceImpl.getNotSupplyList(year);
+            return R.ok(resList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
 
 
     /**
-     * 根据年份和供地类型查询土地供应统计报表数据
+     *
      * @param year
-     * @param supplyType (1-计划,2-完成)
+     * @param batchType (1-单独选址批次,2-报批项目批次,0-全部)
      * @return
      */
     @GetMapping("/projectList")
-    public R<List<LandSupplyProjectVO>> getProjectList(@RequestParam(required = false) String year,@RequestParam Integer supplyType) {
+    public R<List<?>> getProjectList(@RequestParam(required = false) String year,@RequestParam Integer batchType) {
         try {
-                List<LandSupplyProjectVO> resList =  supplyService.projectList(year,supplyType);
-                return R.ok(resList);
+            List<?> resList =  batchServiceImpl.projectList(year,batchType,"");
+            return R.ok(resList);
         } catch (Exception e) {
             e.printStackTrace();
             return R.fail(e.getMessage());
         }
     }
 
-
-    @GetMapping("/getPlanProject")
-    public R<GongdiJihua> getPlanProject(@RequestParam String propertyId) {
+/*
+    @GetMapping("/getSingleProject")
+    public R<Map<String,Object>> getSingleProject(@RequestParam String propertyId) {
         try {
-            GongdiJihua res =  supplyService.getPlanProject(propertyId);
+            Map<String,Object> res =  batchServiceImpl.getSingleProject(propertyId);
             return R.ok(res);
         } catch (Exception e) {
             e.printStackTrace();
             return R.fail(e.getMessage());
         }
     }
+*/
 
-
-    @GetMapping("/getActualProject")
-    public R<Map<String,Object>> getActualProject(@RequestParam String propertyId) {
+    @GetMapping("/getReportProject")
+    public R<YdbpData> getReportProject(@RequestParam String propertyId) {
         try {
-            Map<String,Object> res =  supplyService.getActualProject(propertyId);
+            YdbpData res =  batchServiceImpl.getReportProject(propertyId);
             return R.ok(res);
         } catch (Exception e) {
             e.printStackTrace();
@@ -130,16 +145,174 @@ public class ReportBatchController extends BaseController {
     }
 
 
+//
+//    /**
+//     *
+//     * 根据时间范围查询土地供应统计报表数据
+//     * 供应用途分析报表
+//     *
+//     */
+//    @GetMapping("/report/purpose")
+//    public R<LandSupplyReportVO> getTdgyProjectList(@RequestParam String startYear, @RequestParam String endYear) {
+//        try {
+//            LandSupplyReportVO res =  supplyService.getTdgyPurposeReport(startYear,endYear);
+//            return R.ok(res);
+//        } catch (Exception e) {
+//            return R.fail(e.getMessage());
+//        }
+//    }
+//
+//    @GetMapping("/landTypeList")
+//    public R<List<LandType>> getLandTypeList() {
+//        try {
+//            return R.ok(supplyService.getLandTypeList());
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            return R.fail(e.getMessage());
+//        }
+//    }
+
+
     /**
-     *
-     * 根据时间范围查询土地供应统计报表数据
-     * 供应用途分析报表
-     *
+     * 台账列表
      */
-    @GetMapping("/report/purpose")
-    public R<LandSupplyReportVO> getTdgyProjectList(@RequestParam String startYear, @RequestParam String endYear) {
+    @GetMapping("/report/bill/{year}")
+    public R<?> billProjectList(@PathVariable String year) {
         try {
-            LandSupplyReportVO res =  supplyService.getTdgyPurposeReport(startYear,endYear);
+            List<YdbpData> resList =  batchServiceImpl.billProjectList(year);
+            return R.ok(resList);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+    //台账导出
+    @PostMapping("/bill/export")
+    public void exportBillReport(HttpServletResponse response, @RequestParam String year) {
+        try {
+            List<YdbpData> resList =  batchServiceImpl.billProjectList(year);
+
+            if (resList == null || CollectionUtils.isEmpty(resList)) {
+                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);
+
+            String[] headers = {"序号", "项目名称", "批次类型", "用地面积(亩)", "占用面积(亩)", "报批日期", "批复文号", "批复日期"};
+
+            int rowIndex = 0;
+
+            Row titleRow = sheet.createRow(rowIndex++);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue("土地报批台账(" + year + "年)");
+            titleCell.setCellStyle(titleStyle);
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));
+            titleRow.setHeight((short) 600);
+
+            Row headerRow = sheet.createRow(rowIndex++);
+            for (int i = 0; i < headers.length; i++) {
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(headers[i]);
+                cell.setCellStyle(headerStyle);
+            }
+
+            int seq = 1;
+            for (YdbpData data : resList) {
+                Row dataRow = sheet.createRow(rowIndex++);
+
+                Cell seqCell = dataRow.createCell(0);
+                seqCell.setCellValue(seq++);
+                seqCell.setCellStyle(dataStyle);
+
+                Cell nameCell = dataRow.createCell(1);
+                nameCell.setCellValue(data.getName() != null ? data.getName() : "");
+                nameCell.setCellStyle(dataStyle);
+
+                Cell typeCell = dataRow.createCell(2);
+                typeCell.setCellValue("1".equals(data.getBatchType()) ? "单独选址批次" : ("2".equals(data.getBatchType()) ? "报批项目批次" : (data.getBatchType() != null ? data.getBatchType() : "")));
+                typeCell.setCellStyle(dataStyle);
+
+                Cell ydAreaCell = dataRow.createCell(3);
+                ydAreaCell.setCellValue(data.getYdArea() != null ? data.getYdArea() : 0.0);
+                ydAreaCell.setCellStyle(dataStyle);
+
+                Cell zsAreaCell = dataRow.createCell(4);
+                zsAreaCell.setCellValue(data.getZsArea() != null ? data.getZsArea() : 0.0);
+                zsAreaCell.setCellStyle(dataStyle);
+
+                Cell bpDateCell = dataRow.createCell(5);
+                bpDateCell.setCellValue(data.getBpDate() != null ? data.getBpDate() : "");
+                bpDateCell.setCellStyle(dataStyle);
+
+                Cell pfwhCell = dataRow.createCell(6);
+                pfwhCell.setCellValue(data.getPfwh() != null ? data.getPfwh() : "");
+                pfwhCell.setCellStyle(dataStyle);
+
+                Cell pfDateCell = dataRow.createCell(7);
+                pfDateCell.setCellValue(data.getPfDate() != null ? data.getPfDate() : "");
+                pfDateCell.setCellStyle(dataStyle);
+            }
+
+            for (int i = 0; i < headers.length; i++) {
+                sheet.autoSizeColumn(i);
+            }
+
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = "土地报批台账.xlsx";
+            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();
+        }
+    }
+
+
+    /**
+     * 趋势分析报表
+     */
+    @GetMapping("/report/trendStatistics")
+    public R<BatchTrendReportVO> trendReport(@RequestParam String startYear, @RequestParam String endYear) {
+        try {
+            BatchTrendReportVO res =  batchServiceImpl.trendReport(startYear,endYear);
             return R.ok(res);
         } catch (Exception e) {
             return R.fail(e.getMessage());
@@ -148,13 +321,159 @@ public class ReportBatchController extends BaseController {
 
 
 
-    @GetMapping("/landTypeList")
-    public R<List<LandType>> getLandTypeList() {
+    @PostMapping("/trend/export")
+    public void exportTrendReport(HttpServletResponse response, @RequestParam String startYear, @RequestParam String endYear) {
         try {
-            return R.ok(supplyService.getLandTypeList());
+            BatchTrendReportVO res =  batchServiceImpl.trendReport(startYear,endYear);
+
+            if (res == null || CollectionUtils.isEmpty(res.getRows())) {
+                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);
+            totalStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+            totalStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+            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);
+
+            String[] categories = {"单独选址", "批次报批", "合计"};
+            String[] subHeaders = {"项目数", "占用面积(亩)"};
+
+            int rowIndex = 0;
+
+            Row titleRow = sheet.createRow(rowIndex++);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue("报批趋势分析报表(" + startYear + "-" + endYear + ")");
+            titleCell.setCellStyle(titleStyle);
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 1 + categories.length * 2));
+            titleRow.setHeight((short) 600);
+
+            Row headerRow1 = sheet.createRow(rowIndex++);
+            Row headerRow2 = sheet.createRow(rowIndex++);
+
+            Cell yearHeader = headerRow1.createCell(0);
+            yearHeader.setCellValue("年份");
+            yearHeader.setCellStyle(headerStyle);
+            sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0));
+            headerRow2.createCell(0).setCellStyle(headerStyle);
+
+            int colIndex = 1;
+            for (int i = 0; i < categories.length; i++) {
+                Cell categoryCell = headerRow1.createCell(colIndex);
+                categoryCell.setCellValue(categories[i]);
+                categoryCell.setCellStyle(headerStyle);
+                sheet.addMergedRegion(new CellRangeAddress(1, 1, colIndex, colIndex + 1));
+
+                for (int j = 0; j < subHeaders.length; j++) {
+                    Cell subCell = headerRow2.createCell(colIndex + j);
+                    subCell.setCellValue(subHeaders[j]);
+                    subCell.setCellStyle(headerStyle);
+                }
+                colIndex += 2;
+            }
+
+            for (BatchTrendReportVO.RowData rowData : res.getRows()) {
+                Row dataRow = sheet.createRow(rowIndex++);
+
+                Cell yearCell = dataRow.createCell(0);
+                yearCell.setCellValue(rowData.getYear() != null ? rowData.getYear() : "");
+                yearCell.setCellStyle(dataStyle);
+
+                int dataColIndex = 1;
+                BatchTrendReportVO.TrendData[] trendArr = {rowData.getSignleData(), rowData.getReportData(), rowData.getTotalData()};
+                for (BatchTrendReportVO.TrendData trendData : trendArr) {
+                    Cell countCell = dataRow.createCell(dataColIndex++);
+                    countCell.setCellValue(trendData != null && trendData.getCount() != null ? trendData.getCount() : 0);
+                    countCell.setCellStyle(dataStyle);
+
+                    Cell areaCell = dataRow.createCell(dataColIndex++);
+                    areaCell.setCellValue(trendData != null && trendData.getArea() != null ? trendData.getArea() : 0.0);
+                    areaCell.setCellStyle(dataStyle);
+                }
+            }
+
+            Row totalRow = sheet.createRow(rowIndex++);
+            Cell totalLabelCell = totalRow.createCell(0);
+            totalLabelCell.setCellValue("合计");
+            totalLabelCell.setCellStyle(totalStyle);
+
+            int totalColIndex = 1;
+            BatchTrendReportVO.TrendData[] totalTrendArr = {
+                    res.getTotal() != null ? res.getTotal().getSignleData() : null,
+                    res.getTotal() != null ? res.getTotal().getReportData() : null,
+                    res.getTotal() != null ? res.getTotal().getTotalData() : null
+            };
+            for (BatchTrendReportVO.TrendData trendData : totalTrendArr) {
+                Cell countCell = totalRow.createCell(totalColIndex++);
+                countCell.setCellValue(trendData != null && trendData.getCount() != null ? trendData.getCount() : 0);
+                countCell.setCellStyle(totalStyle);
+
+                Cell areaCell = totalRow.createCell(totalColIndex++);
+                areaCell.setCellValue(trendData != null && trendData.getArea() != null ? trendData.getArea() : 0.0);
+                areaCell.setCellStyle(totalStyle);
+            }
+
+            for (int i = 0; i <= 1 + categories.length * 2; i++) {
+                sheet.autoSizeColumn(i);
+            }
+
+
+
+
+
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = "报批趋势分析报表.xlsx";
+            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 R.fail(e.getMessage());
         }
     }
 
@@ -165,4 +484,8 @@ public class ReportBatchController extends BaseController {
 
 
 
+
+
+
+
 }

+ 105 - 67
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/StorageController.java

@@ -4,9 +4,7 @@ import com.siwei.apply.domain.cadastre.LandStorageInOutReportDTO;
 import com.siwei.apply.domain.cadastre.LandStorageReportDTO;
 import com.siwei.apply.domain.res.StorageYearStatisticsRes;
 import com.siwei.apply.domain.res.TrendStatisticsData;
-import com.siwei.apply.domain.res.TrendStatisticsRes;
 import com.siwei.apply.domain.res.TrendUseStatisticsData;
-import com.siwei.apply.domain.vo.IdsVo;
 import com.siwei.apply.domain.vo.LandSupplyProjectVO;
 import com.siwei.apply.service.cadastre.impl.StorageServiceImpl;
 import com.siwei.common.core.domain.R;
@@ -21,7 +19,6 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -39,7 +36,7 @@ public class StorageController extends BaseController {
      * 年度统计
      */
     @GetMapping("/yearStatistics/{year}")
-    public R<StorageYearStatisticsRes> getYearStatistics(@PathVariable String year) {
+    public R<StorageYearStatisticsRes> getYearStatistics(@PathVariable(required = false) String year) {
         try {
             return R.ok(storageServiceImpl.getYearStatistics(year));
         } catch (Exception e) {
@@ -48,56 +45,56 @@ public class StorageController extends BaseController {
         }
     }
 
-    /**
-     * 趋势统计
-     */
-    @GetMapping("/trendStatistics/{landType}")
-    public R<TrendStatisticsRes> getTrendStatistics(@PathVariable String landType) {
-        try {
-            TrendStatisticsRes res = new TrendStatisticsRes();
-            List<Map<String, Object>> areaTrendStatisticsList = new java.util.ArrayList<>(List.of());
-            List<Map<String, Object>> supplyModeStatisticsList = new java.util.ArrayList<>(List.of());
-
-            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);
-
-            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(modeMap3);
-            res.setSupplyModeStatisticsList(supplyModeStatisticsList);
-            return R.ok(res);
-        } catch (Exception e) {
-            return R.fail(e.getMessage());
-        }
-    }
+//    /**
+//     * 趋势统计
+//     */
+//    @GetMapping("/trendStatistics/{landType}")
+//    public R<TrendStatisticsRes> getTrendStatistics(@PathVariable String landType) {
+//        try {
+//            TrendStatisticsRes res = new TrendStatisticsRes();
+//            List<Map<String, Object>> areaTrendStatisticsList = new java.util.ArrayList<>(List.of());
+//            List<Map<String, Object>> supplyModeStatisticsList = new java.util.ArrayList<>(List.of());
+//
+//            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);
+//
+//            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(modeMap3);
+//            res.setSupplyModeStatisticsList(supplyModeStatisticsList);
+//            return R.ok(res);
+//        } catch (Exception e) {
+//            return R.fail(e.getMessage());
+//        }
+//    }
 
     /**
      * 出入库趋势统计
@@ -106,19 +103,20 @@ public class StorageController extends BaseController {
     public R<List<TrendStatisticsData>> getData1() {
         try {
             List<TrendStatisticsData> areaTrendStatisticsList = storageServiceImpl.getData1();
-            for (TrendStatisticsData obj : areaTrendStatisticsList) {
-                if (obj.getYear().equals("2022")) {
-                    obj.setOutDataArea(String.valueOf(384 + 9.5f));
-                } else if (obj.getYear().equals("2023")) {
-                    obj.setOutDataArea(String.valueOf(110 + 5.5f));
-                } else if (obj.getYear().equals("2024")) {
-                    obj.setOutDataArea(String.valueOf(25 + 44.5f));
-                } else if (obj.getYear().equals("2025")) {
-                    obj.setOutDataArea(String.valueOf(16.f));
-                }
-            }
+//            for (TrendStatisticsData obj : areaTrendStatisticsList) {
+//                if (obj.getYear().equals("2022")) {
+//                    obj.setOutDataArea(String.valueOf(384 + 9.5f));
+//                } else if (obj.getYear().equals("2023")) {
+//                    obj.setOutDataArea(String.valueOf(110 + 5.5f));
+//                } else if (obj.getYear().equals("2024")) {
+//                    obj.setOutDataArea(String.valueOf(25 + 44.5f));
+//                } else if (obj.getYear().equals("2025")) {
+//                    obj.setOutDataArea(String.valueOf(16.f));
+//                }
+//            }
             return R.ok(areaTrendStatisticsList);
         } catch (Exception e) {
+            e.printStackTrace();
             return R.fail(e.getMessage());
         }
     }
@@ -132,10 +130,28 @@ public class StorageController extends BaseController {
             List<TrendUseStatisticsData> useAreaTrendStatisticsList = storageServiceImpl.getData2(year);
             return R.ok(useAreaTrendStatisticsList);
         } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 年末收储统计数据
+     */
+    @GetMapping("/getLandStock")
+    public R<List<Map<String, Object>>> landStock(@RequestParam String year) {
+        try {
+            List<Map<String, Object>> res = storageServiceImpl.landStock(year);
+            return R.ok(res);
+        } catch (Exception e) {
+            e.printStackTrace();
             return R.fail(e.getMessage());
         }
     }
 
+
+
     /**
      * 根据年份和类型查询土地收储统计项目列表
      * supplyType: 0-全部,1-计划,2-完成
@@ -143,9 +159,29 @@ public class StorageController extends BaseController {
     @GetMapping("/projectList")
     public R<List<LandSupplyProjectVO>> getProjectList(@RequestParam(required = false) String year,
                                                        @RequestParam Integer supplyType,
-                                                       @RequestParam(required = false) String keyWord) {
+                                                       @RequestParam(required = false) String supplyMethod,
+                                                       @RequestParam(required = false) String useType) {
+
+        try {
+            List<LandSupplyProjectVO> resList = storageServiceImpl.projectList(year, supplyType, supplyMethod,useType);
+            return R.ok(resList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 出入库分析
+     * supplyType: 0-全部,1-入库,2-出库
+     */
+    @GetMapping("/inOutProjectList")
+    public R<List<LandSupplyProjectVO>> inOutProjectList(@RequestParam(required = false) String year,
+                                                       @RequestParam Integer supplyType,
+                                                       @RequestParam(required = false) String useType) {
         try {
-            List<LandSupplyProjectVO> resList = storageServiceImpl.projectList(year, supplyType, keyWord);
+            List<LandSupplyProjectVO> resList = storageServiceImpl.inOutProjectList(year, supplyType, useType);
             return R.ok(resList);
         } catch (Exception e) {
             e.printStackTrace();
@@ -153,6 +189,8 @@ public class StorageController extends BaseController {
         }
     }
 
+
+
     /**
      * 获取计划收储详情
      */

+ 26 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/cadastre/SupplyController.java

@@ -47,7 +47,7 @@ public class SupplyController extends BaseController {
      *
      */
     @GetMapping("/yearStatistics/{year}")
-    public R<SupplyYearStatisticsRes> getYearStatistics(@PathVariable String year) {
+    public R<SupplyYearStatisticsRes> getYearStatistics(@PathVariable(required = false) String year) {
         try {
             SupplyYearStatisticsRes res =  supplyService.yearStatistics(year);
             return R.ok(res);
@@ -271,6 +271,31 @@ public class SupplyController extends BaseController {
     }
 
 
+
+    /**
+     * 根据年份和供地类型查询土地供应统计报表数据
+     * @param year
+     * @param supplyType (1-计划,2-完成)
+     * @return
+     */
+    @GetMapping("/useMethodList")
+    public R<List<LandSupplyProjectVO>> useTypeAndMethodList(@RequestParam String year,
+                                                             @RequestParam(required = false) String useType,
+                                                             @RequestParam(required = false) String methodType,
+                                                             @RequestParam(required = true) String supplyType) {
+        try {
+            List<LandSupplyProjectVO> resList =  supplyService.useTypeAndMethodList(year,useType,supplyType,methodType);
+            return R.ok(resList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+
+
+
     /**
      * 根据年份和供地类型查询土地供应统计报表数据
      * @param year

+ 22 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/controller/third/DealExcelController.java

@@ -30,10 +30,31 @@ import java.util.*;
 public class DealExcelController extends BaseController {
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-
     @Autowired
     DealExcelServiceImpl  dealExcelService;
 
+    /**
+     * 不动产数据下载
+     */
+    @GetMapping("/excelImmobileDown/{fileName}")
+    public R<Map<String, List<Map<String,String>>>> excelImmobileDown(@PathVariable String fileName)  {
+        try {
+            String uploadFile = "C:\\Users\\Administrator\\Desktop\\11\\excel_out"+"\\"+fileName;
+            Path filePath = Paths.get(uploadFile);
+            File file = filePath.toFile();
+            Map<String, List<Map<String, String>>> dataMap = readExcelWithMergedHeaders(file);
+            String res = dealExcelService.excelImmobileDownFile_HOUSE(dataMap);
+            logger.info("检查数据结果{}",res);
+            return R.ok(dataMap);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail(e.getMessage());
+        }
+    }
+
+
+
+
 
     /**
      * 处理excel数据,批次报批数据

+ 2 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/CadastreFile.java

@@ -33,4 +33,6 @@ public class CadastreFile extends BaseId {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updateTime;
     private Long fileSize;
+    private String landRightType;
+
 }

+ 2 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/Tdgy.java

@@ -31,4 +31,6 @@ public class Tdgy extends BaseId {
     private Date createdAt;        // 创建时间
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updatedAt;        // 更新时间
+    private String nf;        // 更新时间
+
 }

+ 4 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/YdbpData.java

@@ -25,4 +25,8 @@ public class YdbpData extends BaseId {
     private Date createdAt;
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updatedAt;
+    private String projectPropertyId;
+    private String batchType;
+    private String geom;
+
 }

+ 13 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/res/JsydghxkRes.java

@@ -1,13 +1,25 @@
 package com.siwei.apply.domain.res;
 
+import com.siwei.apply.domain.Jsgcghxk;
 import com.siwei.apply.domain.Jsydghxk;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * 建设用地规划许可 结果对象
  */
 @Data
-public class JsydghxkRes extends Jsydghxk {
+//public class JsydghxkRes extends Jsydghxk {
+//    String projectName;// 项目名称
+//    String projectCode;// 项目代码
+//}
+
+
+// 这里回头修改支持多个节点
+public class JsydghxkRes {
+    String projectId; // 项目ID
     String projectName;// 项目名称
     String projectCode;// 项目代码
+    List<Jsydghxk> JsydghxkList; // 规划许可列表
 }

+ 3 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/res/TrendUseStatisticsData.java

@@ -12,4 +12,7 @@ public class TrendUseStatisticsData {
     private String useName; // 用途名称
     private String inDataArea; //入库地块面积
     private String outDataArea; //出库地块面积
+//    private String inDataGeom; //入库地块矢量
+//    private String outDataGeom; //出库地块矢量
+
 }

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

@@ -0,0 +1,40 @@
+package com.siwei.apply.domain.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 房屋性质统计报表响应对象
+ * <p>
+ * </p>
+ */
+@Data
+public class BatchTrendReportVO {
+    /**
+     * 合计行
+     */
+    private RowData total;
+    /**
+     * 各数据行列表
+     */
+    private List<RowData> rows;
+    /**
+     * 报表数据行
+     */
+    @Data
+    public static class RowData {
+        private String year;
+        private TrendData totalData;
+        private TrendData signleData;
+        private TrendData reportData;
+    }
+
+    @Data
+    public static class TrendData {
+        /** 项目数 */
+        private Integer count;
+        /** 占用面积 */
+        private Double area;
+    }
+}

+ 1 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/domain/vo/LandSupplyProjectVO.java

@@ -13,6 +13,7 @@ public class LandSupplyProjectVO {
     private String supplyMethod;
     private String supplyType;
     private String dateType;
+    private String useType;
     @JsonFormat(pattern = "yyyy-MM-dd")
     private Date year;
     private String area;

+ 5 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/GjShijiShouchuMapper.java

@@ -35,4 +35,9 @@ public interface GjShijiShouchuMapper {
     List<TdgyStatisticsRes> gjShijiShouchuListByYear(@Param("year") String year,@Param("startYear") String startYear,@Param("endYear") String endYear,@Param("landTypeCode") String landTypeCode, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
     Map<String, Object> getActualProject(@Param("gid") String gid);
+
+    //统计年末的收储存量数据
+    List<Map<String, Object>> queryDifferenceGeomAreaByYearOfShouchu(@Param("year") String year);
+
+
 }

+ 2 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/NodeLandMapper.java

@@ -57,6 +57,8 @@ public interface NodeLandMapper {
 
     Map<String, String> selectGeomContainsNode(@Param("detailsId")String detailsId);
 
+    List<Map<String, String>> selectGeomIntersectsNode(@Param("detailsId")String detailsId);
+
     List<Map<String, Object>> selectGeomDetailsByGeomDbId( @Param("geomDbId")String geomDbId);
 
     List<NodeLand> selectByGeom(@Param("ewkt") String ewkt);

+ 2 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/mapper/ProjectWorkflowMapper.java

@@ -73,6 +73,8 @@ public interface ProjectWorkflowMapper {
 
     void deleteById(String id);
 
+    void deleteByProjectId(@Param("projectId") String projectId,@Param("nodeId") String nodeId,@Param("nodeTableName") String nodeTableName);
+
     Map<String,Object> getCurrentNode(@Param("id") String id, @Param("projectId") String projectId, @Param("tableName") String tableName);
 
     List<Map<String,String>> selectTableColumnComments(@Param("tableName") String tableName);

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

@@ -68,7 +68,7 @@ public interface TdgyMapper {
     List<TdgyStatisticsRes> getSjgdListByNf(@Param("startYear") String startYear,@Param("endYear") String endYear);
 
 
-
+    List<Tdgy> getTdgyList(@Param("startYear") String startYear,@Param("endYear") String endYear);
 
 
 }

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

@@ -53,9 +53,15 @@ public interface YdbpDataMapper {
 
     void updateHasOnchain(@Param("id") String id, @Param("hasOnchain") Boolean hasOnchain);
 
-    List<YdbpData> getStatisticsList(@Param("year") String year);
+    List<YdbpData> getStatisticsList(@Param("year") String year,
+                                     @Param("startYear") String startYear,@Param("endYear") String endYear,
+                                     @Param("keyWord") String keyWord,@Param("hasGeom")Boolean hasGeom);
 
+    List<Map<String,Object>> queryRemainGeomAreaByYear();
 
+    List<Map<String,Object>> queryRemainGeomListByYear(@Param("year") String year);
+
+    List<Map<String,Object>> queryDifferenceGeomAreaByYear(@Param("year") String year);
 
 
 }

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

@@ -54,8 +54,11 @@ public interface YdbpMapper {
     void updateHasOnchain(@Param("id") String id, @Param("hasOnchain") Boolean hasOnchain);
 
 
+    List<Map<String, Object>> getStatisticsList(@Param("year") String year,@Param("startYear") String startYear,@Param("endYear") String endYear,
+                                                @Param("keyWord") String keyWord,@Param("hasGeom") Boolean hasGeom);
 
-    List<Map<String, Object>> getStatisticsList(@Param("year") String year);
+    List<Map<String,Object>> queryRemainGeomAreaByYearOfYdbp();
 
+    List<Map<String,Object>> queryRemainGeomListByYearOfYdbp(@Param("year") String year);
 
 }

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

@@ -26,7 +26,7 @@ public interface ZdjbxxMapper {
     /**
      * 根据项目编号获取宗地基本信息记录列表
      */
-    List<Zdjbxx> getListByDjzqdm (@Param("djzqdm") String djzqdm);
+    List<Zdjbxx> getListByDjzqdm (@Param("djzqdm") String djzqdm,@Param("qllx") String qllx);
 
 
     List<String> getListByQllx (@Param("qllxIds") String qllxIds);

+ 2 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/JsydghxkService.java

@@ -34,6 +34,8 @@ public interface JsydghxkService {
      */
     JsydghxkRes getById(String id);
 
+    JsydghxkRes getAll(String projectId);
+
     /**
      * 更新建设用地规划许可信息
      *

+ 1 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/NodeLandService.java

@@ -55,6 +55,6 @@ public interface NodeLandService {
 
     Map<String, String> getDjzqContainsNodeList(String geomDetailsId);
 
-
+    List<Map<String,String>> selectGeomIntersectsNode(String geomDetailsId);
 
 }

+ 4 - 2
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/CadastreManageService.java

@@ -14,15 +14,17 @@ import java.util.Map;
 
 public interface CadastreManageService {
 
+    String addLandChange(String theFilePath, String landRightType,String landChangeMode);
+
     CompareResultVo getCompareData(String uploadId) ;
 
-    CadastreFile saveUploadFile(String theFileName, String theFilePath, String fileType,String updateType);
+    CadastreFile saveUploadFile(String theFileName, String theFilePath, String fileType,String updateType,String landRightType);
 
     String addBatchGdbData(String uploadId);
 
     String addBatchMdbData(String uploadId);
 
-    CheckInfoResultVo checkFileData(String theFileName, String theFilePath, String fileType,String updateType);
+    CheckInfoResultVo checkFileData(String theFileName, String theFilePath, String fileType,String updateType,String landRightType);
 
     /**
      * 获取列表

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

@@ -36,4 +36,7 @@ public interface ISupplyService {
 
     List<Map<String, Object>> supplyList(String tableName,String sourceType,String year);
 
+    List<LandSupplyProjectVO> useTypeAndMethodList(String year,String useType,String  supplyType,String methodType);
+
+
 }

+ 499 - 20
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/BatchServiceImpl.java

@@ -2,17 +2,18 @@ package com.siwei.apply.service.cadastre.impl;
 
 import com.siwei.apply.domain.YdbpData;
 import com.siwei.apply.domain.res.*;
+import com.siwei.apply.domain.vo.BatchTrendReportVO;
 import com.siwei.apply.mapper.*;
+import com.siwei.common.core.exception.ServiceException;
 import com.siwei.common.core.utils.StringUtils;
-import com.siwei.spatial.api.RemoteSpatialFilesDbService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.*;
+import java.util.stream.Collectors;
 
 
 @Slf4j
@@ -20,41 +21,519 @@ import java.util.*;
 public class BatchServiceImpl{
 
     @Autowired
-    private GongdiJihuaMapper gongdiJihuaMapper;
+    private YdbpMapper ydbpMapper;
 
     @Autowired
-    private TdgyMapper dgyMapper;
+    private YdbpDataMapper ydbpDataMapper;
 
-    @Autowired
-    private LandTypeMapper landTypeMapper;
+    public List<?> getNotSupplyList(String year) {
+        List<Map<String, Object>> resList = new ArrayList<>();
+        String param = year;
+        if(StringUtils.isBlank(year)||"0".equals(year)||"1000".equals(year)||"2016年前".equals(year)){
+            param ="";
+        }
+        List<Map<String,Object>> ydbpNotSupplyList =  ydbpMapper.queryRemainGeomListByYearOfYdbp(param);
+        List<Map<String,Object>> ydbpDataNotSupplyList =  ydbpDataMapper.queryDifferenceGeomAreaByYear(param);
 
-    @Autowired
-    private RemoteSpatialFilesDbService remoteSpatialFilesDbService;
+        if(CollectionUtils.isNotEmpty(ydbpNotSupplyList)){
+            resList.addAll(ydbpNotSupplyList);
+        }
+        if(CollectionUtils.isNotEmpty(ydbpDataNotSupplyList)){
+            resList.addAll(ydbpDataNotSupplyList);
+        }
 
-    @Autowired
-    private YdbpMapper ydbpMapper;
+        //条件过滤兼容特使情况
+        if("1000".equals(year)){
+            resList = resList.stream().filter(
+                    s->"其它".equals(s.get("year")) || "其它".equals(s.get("nf")) || "1000".equals(s.get("nf"))).collect(Collectors.toList());
+        }else if("2016年前".equals(year)) {
+            resList = resList.stream().filter(s -> {
+                String yearString = Objects.nonNull(s.get("year"))? s.get("year").toString(): "";
+                String nf = Objects.nonNull(s.get("nf"))? s.get("nf").toString(): "";
+                if (StringUtils.isNumeric(yearString) && Integer.parseInt(yearString) > 1000 && Integer.parseInt(yearString) < 2016) {
+                    return true;
+                } else if (StringUtils.isNumeric(nf) && Integer.parseInt(nf)>1000 && Integer.parseInt(nf) < 2016) {
+                    return true;
+                }
+                return false;
+            }).collect(Collectors.toList());
+        }
+        return resList;
+    }
 
-    @Autowired
-    private YdbpDataMapper ydbpDataMapper;
 
 
+    /**
+     *  batchType (1-单批次项目,2-报批项目,0-全部)
+     * 获取项目列表
+     * @param year
+     * @param batchType
+     * @param keyWord
+     * @return
+     */
+    public List<?> projectList(String year, Integer batchType, String keyWord) {
+        List<Object> resList = new ArrayList<>();
+        if (batchType == 1) {
+            return buildSingleProjectList(year, keyWord);
+        } else if (batchType == 2) {
+            return buildReportProjectList(year, keyWord);
+        } else if (batchType == 0) {
+            resList.addAll(buildSingleProjectList(year, keyWord));
+            resList.addAll(buildReportProjectList(year, keyWord));
+        }
+        return resList;
+    }
 
 
+    private List<Map<String,Object>> buildSingleProjectList(String year, String keyWord) {
+        List<Map<String,Object>> singleBatchList =  ydbpMapper.getStatisticsList(year,keyWord,"","",true);
+        if (CollectionUtils.isEmpty(singleBatchList)) {
+            return new ArrayList<>();
+        }
+         singleBatchList.forEach(item -> {
+            item.put("projectPropertyId",item.get("project_id") == null ? "" : String.valueOf(item.get("project_id")));
+            item.put("batchType",item.get("batch_type") == null ? "" : String.valueOf(item.get("batch_type")));
+            Double mj_mu = (Double) item.get("mj_mu");
+            item.put("mj_mu",String.format("%.2f", mj_mu == null ? 0d : mj_mu));
+        });
+        return singleBatchList;
+    }
+
+    private List<YdbpData> buildReportProjectList(String year, String keyWord) {
+        List<YdbpData> reportBatchList =  ydbpDataMapper.getStatisticsList(year,keyWord,"","",true);
+        if (CollectionUtils.isEmpty(reportBatchList)) {
+            return new ArrayList<>();
+        }
+         reportBatchList.forEach(item -> {
+            item.setProjectPropertyId(item.getId());
+            item.setZsArea(Float.valueOf(String.format("%.2f", item.getZsArea() == null ? 0f : item.getZsArea())));
+        });
+        return reportBatchList;
+    }
+
 
     /**
-     * 年度统计
-     * @param year
+     *
+     *  获取报批项目详情
+     * @param propertyId
      * @return
      */
-    public BatchRateRes trendStatistics(String year) {
+    public YdbpData getReportProject(String propertyId) {
+        return  ydbpDataMapper.getById(propertyId);
+    }
+
+
+    public BatchTrendReportVO trendReport(String startYear, String endYear) {
+        if(StringUtils.isBlank(startYear)||StringUtils.isBlank(endYear)){
+            throw new  ServiceException("年份不能为空");
+        }
+        BatchTrendReportVO batchTrendReportVO = new BatchTrendReportVO();
+        List<BatchTrendReportVO.RowData> rows = new ArrayList<>();
+
+        List<Map<String,Object>> singleBatchList =  ydbpMapper.getStatisticsList("",startYear,endYear,"",false);
+        List<YdbpData> reportBatchList =  ydbpDataMapper.getStatisticsList("",startYear,endYear,"",false);
+
+        Map<String,List<Map<String,Object>>> groupedSingleBatch = new HashMap<>();
+        Map<String, List<YdbpData>> groupedReportBatch = new HashMap<>();
+
+        if(CollectionUtils.isNotEmpty(singleBatchList)) {
+            groupedSingleBatch = singleBatchList.stream()
+                    .collect(Collectors.groupingBy(s->{
+                        Object nfStr = s.get("nf");
+                        if(nfStr==null || String.valueOf(nfStr).isEmpty()||"1000".equals(String.valueOf(nfStr))){
+                            return "其它";
+                        }
+                        return String.valueOf(nfStr);
+                    }));
+        }
+
+        if(CollectionUtils.isNotEmpty(reportBatchList)) {
+            groupedReportBatch = reportBatchList.stream()
+                    .collect(Collectors.groupingBy(s->{
+                        String pfDate = s.getPfDate();
+                        if(StringUtils.isBlank(pfDate)){
+                            return "其它";
+                        }
+                        pfDate = StringUtils.substring(pfDate,0,4);
+                        return pfDate;
+                    }));
+        }
+
+        Set<String> yearSet = new TreeSet<>();
+        if(MapUtils.isNotEmpty(groupedSingleBatch)) {
+            yearSet.addAll(groupedSingleBatch.keySet());
+        }
+        if(MapUtils.isNotEmpty(groupedReportBatch)) {
+            yearSet.addAll(groupedReportBatch.keySet());
+        }
+
+        for(String yearKey : yearSet){
+            List<Map<String,Object>> singleList = groupedSingleBatch.get(yearKey);
+            List<YdbpData> reportList = groupedReportBatch.get(yearKey);
+
+            //计算单独选址的value
+            Double singleArea = sumAreaForSingle(singleList);
+            Integer singleCount = singleList==null?0:singleList.size();
+            BatchTrendReportVO.TrendData singleTrendData = new BatchTrendReportVO.TrendData();
+            singleTrendData.setArea(singleArea);
+            singleTrendData.setCount(singleCount);
+
+            //计算报批项目的value
+            Double reportArea = sumArea(reportList);
+            Integer reportCount = reportList==null?0:reportList.size();
+            BatchTrendReportVO.TrendData reportTrendData = new BatchTrendReportVO.TrendData();
+            reportTrendData.setArea(reportArea);
+            reportTrendData.setCount(reportCount);
+
+            //计算总量
+            BatchTrendReportVO.TrendData totalTrendData = new BatchTrendReportVO.TrendData();
+            totalTrendData.setCount(singleCount+reportCount);
+            totalTrendData.setArea(singleArea+reportArea);
+
+            //这里组装row
+            BatchTrendReportVO.RowData rowData = new BatchTrendReportVO.RowData();
+            rowData.setYear(yearKey);//设置名称
+            rowData.setSignleData(singleTrendData);
+            rowData.setReportData(reportTrendData);
+            rowData.setTotalData(totalTrendData);
+
+            rows.add(rowData);
+        }
+        batchTrendReportVO.setRows(rows);
+
+        //这里计算合计行
+        BatchTrendReportVO.RowData total = new BatchTrendReportVO.RowData();
+        {
+            String year = "合计";
+
+            //计算单独选址的value
+            Double singleArea = sumAreaForSingle(singleBatchList);
+            Integer singleCount = singleBatchList==null?0:singleBatchList.size();
+            BatchTrendReportVO.TrendData singleTrendData = new BatchTrendReportVO.TrendData();
+            singleTrendData.setArea(singleArea);
+            singleTrendData.setCount(singleCount);
+
+            //计算报批项目的value
+            Double reportArea = sumArea(reportBatchList);
+            Integer reportCount = reportBatchList==null?0:reportBatchList.size();
+            BatchTrendReportVO.TrendData reportTrendData = new BatchTrendReportVO.TrendData();
+            reportTrendData.setArea(reportArea);
+            reportTrendData.setCount(reportCount);
+
+            //计算总量
+            BatchTrendReportVO.TrendData totalTrendData = new BatchTrendReportVO.TrendData();
+            totalTrendData.setCount(singleCount+reportCount);
+            totalTrendData.setArea(singleArea+reportArea);
+
+            //这里组装row
+            total.setYear(year);//设置名称
+            total.setSignleData(singleTrendData);
+            total.setReportData(reportTrendData);
+            total.setTotalData(totalTrendData);
+        }
+
+        batchTrendReportVO.setTotal(total);
+        return batchTrendReportVO;
+    }
+
+    public List<YdbpData> billProjectList(String year) {
+        if(StringUtils.isBlank(year)){
+            throw new  ServiceException("年份不能为空");
+        }
+        List<YdbpData> resList = new ArrayList<>();
+        List<YdbpData> reportBatchList =  ydbpDataMapper.getStatisticsList(year,"","","",false);
+        if(CollectionUtils.isNotEmpty(reportBatchList)){
+            resList.addAll(reportBatchList);
+        }
+        List<Map<String,Object>> singleBatchList =  ydbpMapper.getStatisticsList(year,"","","",false);
+        if(CollectionUtils.isNotEmpty(singleBatchList)){
+            singleBatchList.stream().map(s->{
+                YdbpData ydbpData = new YdbpData();
+                ydbpData.setId(s.get("id")+"");
+                ydbpData.setProjectPropertyId(s.get("project_id") == null ? "" : String.valueOf(s.get("project_id")));
+                ydbpData.setName(s.get("project_name")+"");
+                ydbpData.setBatchType(s.get("batch_type")+"");
+                ydbpData.setYdArea(s.get("yd_area") == null ? 0f : Float.parseFloat(String.valueOf(s.get("yd_area"))));
+                ydbpData.setZsArea(s.get("mj_mu") == null ? 0f : Float.parseFloat(String.valueOf(s.get("mj_mu"))));
+                ydbpData.setYdUnit(s.get("yd_unit")+"");
+                ydbpData.setYdUnit(s.get("zs_unit")+"");
+                ydbpData.setBpDate(s.get("bp_date")+"");
+                ydbpData.setPfDate(s.get("pf_date")+"");
+                ydbpData.setPfwh(s.get("pfwh")+"");
+                return ydbpData;
+            }).forEach(resList::add);
+        }
+        return resList;
+    }
+
+
+
+
+    public List<Map<String,Object>> approvalAndNotSupply(String year) {
         if (StringUtils.isBlank(year) || "0".equals(year)) {
             year = "";
         }
-        BatchRateRes res = new BatchRateRes();
-        return null;
+
+        List<Map<String,Object>> resList = new ArrayList<>();
+        List<Map<String,Object>> singleBatchList = ydbpMapper.queryRemainGeomAreaByYearOfYdbp();
+        List<Map<String,Object>> reportBatchList =  ydbpDataMapper.queryDifferenceGeomAreaByYear("");
+
+        Map<String,Map<String,Object>> groupedSingleBatch = new HashMap<>();
+        Map<String,Map<String,Object>> groupedReportBatch = new HashMap<>();
+
+        if(CollectionUtils.isNotEmpty(singleBatchList)) {
+            groupedSingleBatch = singleBatchList.stream()
+                    .collect(Collectors.toMap(
+                            s -> {
+                                Object nfStr = s.get("stat_year");
+                                if(nfStr==null || String.valueOf(nfStr).isEmpty()||"1000".equals(String.valueOf(nfStr))){
+                                    return "其它";
+                                }
+                                return String.valueOf(nfStr);
+                            },
+                            s -> s  // value直接是当前对象
+                    ));
+        }
+
+        if(CollectionUtils.isNotEmpty(reportBatchList)) {
+            groupedReportBatch = reportBatchList.stream()
+                    .collect(Collectors.toMap(s->{
+                                Object nfStr = s.get("nf");
+                                if(nfStr==null || String.valueOf(nfStr).isEmpty()||"1000".equals(String.valueOf(nfStr))){
+                                    return "其它";
+                                }
+                                return String.valueOf(nfStr);
+                            },
+                            s->s));
+        }
+
+        Set<String> yearSet = new TreeSet<>();
+        if(MapUtils.isNotEmpty(groupedSingleBatch)) {
+            yearSet.addAll(groupedSingleBatch.keySet());
+        }
+        if(MapUtils.isNotEmpty(groupedReportBatch)) {
+            yearSet.addAll(groupedReportBatch.keySet());
+        }
+
+        for(String yearKey : yearSet){
+            Map<String,Object> single = groupedSingleBatch.get(yearKey);
+            Map<String,Object> report = groupedReportBatch.get(yearKey);
+
+            Double singleArea =  Objects.nonNull(single) ? (Double)single.get("total_area_mu"):0d;
+            Double reportArea = Objects.nonNull(report) ? (Double) report.get("rest_area"):0d;
+
+            Long singleCount = Objects.nonNull(single) ? (Long) single.get("patch_count"):0;
+            Long reportCount = 0L;
+
+            Map<String,Object> itemMap = new HashMap<>();
+            itemMap.put("year",yearKey);
+            itemMap.put("area",String.format("%.2f", (singleArea+reportArea)));
+            itemMap.put("count",singleCount+reportCount);
+            resList.add(itemMap);
+        }
+
+        if(CollectionUtils.isNotEmpty(resList)) {
+            int tmpYear = 2015;
+            double  tmpArea = 0d;
+            List<Map<String,Object>> newResList = new ArrayList<>();
+            for(Map<String,Object> map : resList) {
+                String theYear = String.valueOf(map.get("year"));
+                if (StringUtils.isNumeric(theYear) && Integer.parseInt(theYear) <= tmpYear) {
+                    tmpArea += Double.parseDouble(String.valueOf(map.get("area")));
+                }else {
+                    newResList.add(map);
+                }
+            }
+            // 这里增加到list中
+            Map<String,Object> itemMap = new HashMap<>();
+            itemMap.put("year","2016年前");
+            itemMap.put("area",String.format("%.2f", tmpArea));
+            itemMap.put("count",0);
+            newResList.add(itemMap);
+            resList = newResList;
+        }
+        return resList;
     }
 
 
+
+
+    public List<Map<String,Object>> approvalAndNotSupply_delete(String year) {
+        if (StringUtils.isBlank(year) || "0".equals(year)) {
+            year = "";
+        }
+
+        List<Map<String,Object>> resList = new ArrayList<>();
+
+        List<Map<String,Object>> singleBatchList = ydbpMapper.queryRemainGeomAreaByYearOfYdbp();
+        List<Map<String,Object>> reportBatchList =  ydbpDataMapper.queryRemainGeomAreaByYear();
+
+        Map<String,Map<String,Object>> groupedSingleBatch = new HashMap<>();
+        Map<String,Map<String,Object>> groupedReportBatch = new HashMap<>();
+
+
+        if(CollectionUtils.isNotEmpty(singleBatchList)) {
+            groupedSingleBatch = singleBatchList.stream()
+                    .collect(Collectors.toMap(
+                            s -> {
+                                Object nfStr = s.get("stat_year");
+                                if(nfStr==null || String.valueOf(nfStr).isEmpty()||"1000".equals(String.valueOf(nfStr))){
+                                    return "其它";
+                                }
+                                return String.valueOf(nfStr);
+                            },
+                            s -> s  // value直接是当前对象
+                    ));
+        }
+
+
+        if(CollectionUtils.isNotEmpty(reportBatchList)) {
+            groupedReportBatch = reportBatchList.stream()
+                    .collect(Collectors.toMap(s->{
+                        Object nfStr = s.get("stat_year");
+                        if(nfStr==null || String.valueOf(nfStr).isEmpty()||"1000".equals(String.valueOf(nfStr))){
+                            return "其它";
+                        }
+                        return String.valueOf(nfStr);
+                    },
+                    s->s));
+        }
+
+        Set<String> yearSet = new TreeSet<>();
+        if(MapUtils.isNotEmpty(groupedSingleBatch)) {
+            yearSet.addAll(groupedSingleBatch.keySet());
+        }
+        if(MapUtils.isNotEmpty(groupedReportBatch)) {
+            yearSet.addAll(groupedReportBatch.keySet());
+        }
+
+        for(String yearKey : yearSet){
+            Map<String,Object> single = groupedSingleBatch.get(yearKey);
+            Map<String,Object> report = groupedReportBatch.get(yearKey);
+
+            Double singleArea =  Objects.nonNull(single) ? (Double)single.get("total_area_mu"):0d;
+            Double reportArea = Objects.nonNull(report) ? (Double) report.get("total_area_mu"):0d;
+
+            Long singleCount = Objects.nonNull(single) ? (Long) single.get("patch_count"):0;
+            Long reportCount = Objects.nonNull(report) ? (Long) report.get("patch_count"):0;
+
+            Map<String,Object> itemMap = new HashMap<>();
+            itemMap.put("year",yearKey);
+            itemMap.put("area",String.format("%.2f", (singleArea+reportArea)));
+            itemMap.put("count",singleCount+reportCount);
+
+            resList.add(itemMap);
+        }
+
+        return resList;
+    }
+
+
+
+
+        /**
+         * 年度统计
+         * @param year
+         * @return
+         */
+    public List<Map<String,Object>> trendStatistics(String year) {
+        if (StringUtils.isBlank(year) || "0".equals(year)) {
+            year = "";
+        }
+
+        List<Map<String,Object>> resList = new ArrayList<>();
+        List<Map<String,Object>> singleBatchList =  ydbpMapper.getStatisticsList(year,"","","",false);
+        List<YdbpData> reportBatchList =  ydbpDataMapper.getStatisticsList(year,"","","",false);
+
+        Map<String,List<Map<String,Object>>> groupedSingleBatch = new HashMap<>();
+        Map<String, List<YdbpData>> groupedReportBatch = new HashMap<>();
+
+        if(CollectionUtils.isNotEmpty(singleBatchList)) {
+            groupedSingleBatch = singleBatchList.stream()
+                    .collect(Collectors.groupingBy(s->{
+                        Object nfStr = s.get("nf");
+                        if(nfStr==null || String.valueOf(nfStr).isEmpty()||"1000".equals(String.valueOf(nfStr))){
+                            return "其它";
+                        }
+                        return String.valueOf(nfStr);
+                    }));
+        }
+
+        if(CollectionUtils.isNotEmpty(reportBatchList)) {
+            groupedReportBatch = reportBatchList.stream()
+                    .collect(Collectors.groupingBy(s->{
+                       String pfDate = s.getPfDate();
+                       if(StringUtils.isBlank(pfDate)){
+                           return "其它";
+                       }
+                        pfDate = StringUtils.substring(pfDate,0,4);
+                        return pfDate;
+                    }));
+        }
+
+        Set<String> yearSet = new TreeSet<>();
+        if(MapUtils.isNotEmpty(groupedSingleBatch)) {
+            yearSet.addAll(groupedSingleBatch.keySet());
+        }
+        if(MapUtils.isNotEmpty(groupedReportBatch)) {
+            yearSet.addAll(groupedReportBatch.keySet());
+        }
+
+        for(String yearKey : yearSet){
+            List<Map<String,Object>> singleList = groupedSingleBatch.get(yearKey);
+            List<YdbpData> reportList = groupedReportBatch.get(yearKey);
+            Double singleArea = sumAreaForSingle(singleList);
+            Double reportArea = sumArea(reportList);
+            Integer singleCount = singleList==null?0:singleList.size();
+            Integer reportCount = reportList==null?0:reportList.size();
+            Map<String,Object> itemMap = new HashMap<>();
+            itemMap.put("year",yearKey);
+            itemMap.put("singleArea",singleArea);
+            itemMap.put("reportArea",reportArea);
+            itemMap.put("singleCount",singleCount);
+            itemMap.put("reportCount",reportCount);
+            resList.add(itemMap);
+        }
+
+        //这里折合2015年前的数据
+        if(CollectionUtils.isNotEmpty(resList)){
+            int tmpYear = 2015;
+            Double tmpSingleArea = 0d;
+            Double tmpReportArea = 0d;
+            Integer tmpSingleCount = 0;
+            Integer tmpReportCount = 0;
+
+            List<Map<String,Object>> newResList = new ArrayList<>();
+            for(Map<String,Object> map:resList){
+                String theYear =  String.valueOf(map.get("year"));
+                if(StringUtils.isNumeric(theYear) && Integer.parseInt(theYear)>tmpYear){
+                    newResList.add(map);
+                }else {
+                    tmpSingleArea += (Double) map.get("singleArea");
+                    tmpReportArea += (Double) map.get("reportArea");
+                    tmpSingleCount += (Integer) map.get("singleCount");
+                    tmpReportCount += (Integer) map.get("reportCount");
+                }
+            }
+
+            Map<String,Object> itemMap = new HashMap<>();
+            itemMap.put("year","2016年前");
+            itemMap.put("singleArea",tmpSingleArea);
+            itemMap.put("reportArea",tmpReportArea);
+            itemMap.put("singleCount",tmpSingleCount);
+            itemMap.put("reportCount",tmpReportCount);
+            newResList.add(itemMap);
+            resList = newResList;
+        }
+
+        return resList;
+    }
+
+
+
+
+
+
     /**
      * 年度统计
      * @param year
@@ -65,8 +544,8 @@ public class BatchServiceImpl{
             year="";
         }
         BatchRateRes res = new BatchRateRes();
-        List<Map<String,Object>> singleBatchList =  ydbpMapper.getStatisticsList(year);
-        List<YdbpData> reportBatchList =  ydbpDataMapper.getStatisticsList(year);
+        List<Map<String,Object>> singleBatchList =  ydbpMapper.getStatisticsList(year,"","","",false);
+        List<YdbpData> reportBatchList =  ydbpDataMapper.getStatisticsList(year,"","","",false);
         if(CollectionUtils.isNotEmpty(singleBatchList)) {
             res.setSingleArea(sumAreaForSingle(singleBatchList));
             res.setSingleProjectCount(singleBatchList.size());

+ 168 - 14
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/CadastreManageServiceImpl.java

@@ -16,7 +16,6 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.gdal.ogr.*;
-import org.gdal.osr.CoordinateTransformation;
 import org.gdal.osr.SpatialReference;
 import org.locationtech.jts.io.ParseException;
 import org.locationtech.jts.io.WKBReader;
@@ -58,6 +57,130 @@ public class CadastreManageServiceImpl implements CadastreManageService {
     @Autowired
     private FzssFxrwrzMapper fzssFxrwrzMapper;
 
+    /**
+     * 解压文件并且根据情况进行拆分或合并的处理
+     * @param  上传文件名
+     * @param theFilePath 文件路径
+     * @param landRightType 宗地权利类型
+     * @param landChangeMode 宗地变更模式
+     * @return
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public String addLandChange(String theFilePath, String landRightType,String landChangeMode) {
+        String result = "success";
+        /**
+         *
+         * 1.必须要上产并解压文件,保证一个gdb文件,并且保证文件名与表名称对应
+         * 2.字段校验权利类型是否正确
+         * 3.能够获取到相关数据,并且数据都合规。
+         * 4.无日志,无对比文件,直接入库,返回变化和变更多少条
+         *
+         */
+        try {
+                String theFileName = "";
+                if (StringUtils.isBlank(theFilePath)) {
+                    log.warn("处理文件失败:filePath不能为空");
+                    throw new ServiceException("处理文件失败:filePath不能为空");
+                }
+                Path currentFilePath = Paths.get(theFilePath);
+                if (!Files.exists(currentFilePath)) {
+                    log.warn("处理文件失败:文件不存在: {}", theFilePath);
+                    throw new ServiceException("处理文件失败:文件不存在:"+theFilePath);
+                }
+                // 判断是否为压缩文件
+                if (FileExtractUtil.isCompressedFile(theFilePath)) {
+                    // 解压文件到同名文件夹并获取目录结构
+                    String extractRes = FileExtractUtil.extractToSameNameFolder(theFilePath);
+                    if (StringUtils.isBlank(extractRes)) {
+                        log.warn("解压文件失败:文件不存在: {}", theFilePath);
+                        throw new ServiceException("解压文件失败:文件不存在,");
+                    }
+                    //解压成功文件保存
+                    if (StringUtils.isNotBlank(extractRes)) {
+                        // -----------------第一部分文件解压处理-------------------------------
+                        String unZipPath = extractRes;
+                        String innerExtractFileName = FileExtractUtil.getInnerFolderByDirName(unZipPath);
+                        // 如果解压后的文件夹名称不为空,则使用解压后的文件夹名称作为文件名
+                        if (StringUtils.isNotBlank(innerExtractFileName)) {
+                            theFileName = innerExtractFileName;
+                        } else {
+                            String suffix = ".gdb"; //需要后缀为.gdb才能被jar包识别为矢量数据进行读取
+                            //这里解压文件名称作为文件名
+                            String fileName = currentFilePath.getFileName().toString();
+                            theFileName = fileName.substring(0, fileName.lastIndexOf('.'));
+                            theFileName += suffix;
+
+                            //如果当前压缩文件为gdb文件,则解压后的文件夹名称需要修改为.gdb结尾
+                            FileExtractUtil.modifyDirName(unZipPath, unZipPath + suffix);
+                            unZipPath += suffix;
+                            unZipPath = unZipPath.replace(theFileName, "");
+                            if (StringUtils.isNotBlank(unZipPath) && (unZipPath.endsWith("/") || unZipPath.endsWith("\\"))) {
+                                unZipPath = unZipPath.substring(0, unZipPath.length() - 1);
+                            }
+                        }
+                        if (StringUtils.isNotBlank(theFileName) && !theFileName.toLowerCase(Locale.ROOT).endsWith(".gdb")) {
+                            throw new ServiceException("文件不是gdb格式矢量数据,请检查重新上传");
+                        }
+
+                        // -----------------第二部分遍历图层进行质量检查 -------------------------------
+                        DataSource ds = ogr.Open(unZipPath + "/" + theFileName, 0); // 0 = 只读
+                        if (ds == null) {
+                            log.warn("无法打开 gdb");
+                            result = "无法打开gdb文件,不能入库";
+                            return result;
+                        }
+
+                        String tableName = "zdjbxx";
+                        if(ds.GetLayerCount()!=1){
+                            throw new ServiceException("当前gdb文件,仅仅支持一个图层,并且图层名称应为("+tableName+")");
+                        }
+
+                        Layer layer = ds.GetLayer(0);
+                        String name = layer.GetName();
+                        //检查表名对应
+                        if (!name.equalsIgnoreCase(tableName)) {
+                            throw new ServiceException("当前gdb文件,图层名称不对,图层名称应为("+tableName+")");
+                        }
+
+                        //检查坐标系
+                        if (checkCoordinateSystem(layer).equals(false)) {
+                            throw new ServiceException(name + ":坐标系不正确,确认是否CGCS2000!");
+                        }
+
+                        boolean haveGeom = false;
+                        //获取字段信息
+                        List<String> dbFieldNameList = cadastreFileMapper.selectTableCollum(name.toLowerCase(Locale.ROOT));
+                        if (dbFieldNameList.contains("geom")) {
+                            haveGeom = true;
+                        }
+                        //这里移除校验字段(非属mdb中的字段)
+                        dbFieldNameList.remove("valid_flag");
+                        List<String> layerFieldNameList = this.getFieldName(layer, haveGeom);
+                        // 判断是否包含相同的元素(不考虑顺序)
+                        boolean areCollectionsEqual = CollectionUtils.containsAll(layerFieldNameList,dbFieldNameList);
+                        if (!areCollectionsEqual) {
+                            List<String> missingFields = (List<String>) CollectionUtils.subtract(dbFieldNameList, layerFieldNameList);
+                            if (CollectionUtils.isNotEmpty(missingFields)) {
+                                throw new ServiceException(name + ":图层缺失数据库字段!缺失字段列表=" + missingFields);
+                            }
+                            //throw new ServiceException(name + ":字段数据不一致!-" + dbFieldNameList);
+                        }
+                        // -----------------第三部分遍历图层进行数据处理 -------------------------------
+
+
+
+                    }
+                }
+            } catch (Exception e) {
+                log.error("矢量数据入库异常,uploadId: {}", "", e);
+                throw new ServiceException("矢量数据入库异常," + e.getMessage());
+            }
+        return result;
+    }
+
+
+
 
     /**
      *
@@ -115,16 +238,19 @@ public class CadastreManageServiceImpl implements CadastreManageService {
                 ));
                 List<Map<String, Object>> theValueList = getValueList(layer, dbFieldNameAndTypeMap, haveGeom);
                 fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "正在执行-" + layerName + "-入库", "info");
-                //这里直接数据入库,区分增量或者全量
+
+                //宗地权利类型(1-使用权;2-所有权)
+                String landRightType = cadastreFile.getLandRightType();
                 Boolean addRes;
+                //这里直接数据入库,区分增量或者全量
                 if ("2".equalsIgnoreCase(cadastreFile.getReadStatus())) {
                     //增量更新
-                    addRes = incrementDataStorage(layerName, theValueList);
+                    addRes = incrementDataStorage(landRightType,layerName, theValueList);
                     if (addRes.equals(true)) {
                         fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "增量更新-" + layerName + "-成功", "info");
                     }
                 } else {
-                    addRes = fullDataStorage(layerName, theValueList);
+                    addRes = fullDataStorage(landRightType,layerName, theValueList);
                     if (addRes.equals(true)) {
                         fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "增量更新-" + layerName + "-成功", "info");
                     }
@@ -176,6 +302,10 @@ public class CadastreManageServiceImpl implements CadastreManageService {
             }
 
             fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "正在执行入库操作。。。", "info");
+
+            //如果是宗地需要区分权利类型(1.使用权数据,2.所有权数据)
+            String landRightType =  cadastreFile.getLandRightType();
+
             for (Map<String, Object> tableMap : allMdbTableList) {
                 String talbleName = String.valueOf(tableMap.get("name"));
                 Map<String, Object> allMdbTableFieldMap = MdbUtil.MdbTableContent(gdbPath + "/" + cadastreFile.getName(), talbleName, "", "", 1, 1000);
@@ -184,12 +314,12 @@ public class CadastreManageServiceImpl implements CadastreManageService {
                 fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "正在执行-" + talbleName + "-入库", "info");
                 Boolean addRes;
                 if ("2".equalsIgnoreCase(cadastreFile.getReadStatus())) {
-                    addRes = incrementDataStorage(talbleName, theValueList);
+                    addRes = incrementDataStorage(landRightType,talbleName, theValueList);
                     if (addRes.equals(true)) {
                         fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "增量更新-" + talbleName + "-成功", "info");
                     }
                 } else {
-                    addRes = fullDataStorage(talbleName, theValueList);
+                    addRes = fullDataStorage(landRightType,talbleName, theValueList);
                     if (addRes.equals(true)) {
                         fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", "全量更新-" + talbleName + "-成功", "info");
                     }
@@ -276,7 +406,7 @@ public class CadastreManageServiceImpl implements CadastreManageService {
      * @return
      */
     @Override
-    public CadastreFile saveUploadFile(String theFileName, String theFilePath, String fileType, String updateType) {
+    public CadastreFile saveUploadFile(String theFileName, String theFilePath, String fileType, String updateType,String landRightType) {
         try {
             if (theFilePath == null || theFilePath.trim().isEmpty()) {
                 log.warn("处理文件失败:filePath不能为空");
@@ -344,11 +474,14 @@ public class CadastreManageServiceImpl implements CadastreManageService {
                     if (StringUtils.isNotBlank(fileType)) {
                         cadastreFile.setFileType(fileType);
                     }
-
                     //0 为全量更新,1为增量更新
                     if (StringUtils.isNotBlank(updateType)) {
                         cadastreFile.setReadStatus(updateType);
                     }
+                    //0 为全量更新,1为增量更新
+                    if (StringUtils.isNotBlank(landRightType)) {
+                        cadastreFile.setLandRightType(landRightType);
+                    }
                     cadastreFile.setFileSize(fileSize);
                     cadastreFile.setStatus("0");
                     cadastreFile.setUploadUser("admin");
@@ -382,13 +515,13 @@ public class CadastreManageServiceImpl implements CadastreManageService {
      * @return
      */
     @Override
-    public CheckInfoResultVo checkFileData(String theFileName, String theFilePath, String fileType, String updateType) {
+    public CheckInfoResultVo checkFileData(String theFileName, String theFilePath, String fileType, String updateType,String landRightType) {
         CheckInfoResultVo checkInfoResult = new CheckInfoResultVo();
         checkInfoResult.setResultStatus(true);
         List<CheckInfoVo> checkInfoSuccessList = new ArrayList<>();
         List<CheckInfoVo> checkInfoFailList = new ArrayList<>();
 
-        CadastreFile uploadFile = this.saveUploadFile(theFileName, theFilePath, fileType, updateType);
+        CadastreFile uploadFile = this.saveUploadFile(theFileName, theFilePath, fileType, updateType,landRightType);
 
         if (Objects.nonNull(uploadFile)) {
             //入库成功
@@ -503,7 +636,11 @@ public class CadastreManageServiceImpl implements CadastreManageService {
         // 判断是否包含相同的元素(不考虑顺序)
         boolean areCollectionsEqual = CollectionUtils.containsAll(layerFieldNameList,dbFieldNameList);
         if (!areCollectionsEqual) {
-            checkInfoList.add(name + ":字段数据不一致!-" + dbFieldNameList);
+            List<String> missingFields = (List<String>) CollectionUtils.subtract(dbFieldNameList, layerFieldNameList);
+            if (CollectionUtils.isNotEmpty(missingFields)) {
+                throw new ServiceException(name + ":图层缺失数据库字段!缺失字段列表=" + missingFields);
+            }
+            //checkInfoList.add(name + ":字段数据不一致!-" + dbFieldNameList);
             fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", name + ":字段数据不一致!-" + dbFieldNameList, "info");
             checkInfoVo.setCheckStatus(false);
         }
@@ -573,7 +710,11 @@ public class CadastreManageServiceImpl implements CadastreManageService {
         // 判断是否包含相同的元素(不考虑顺序)
         boolean areCollectionsEqual = CollectionUtils.containsAll(lowerCaseMdbTableFieldNameList,dbFieldNameList);
         if (!areCollectionsEqual) {
-            checkInfoList.add(mdbTableName + ":字段数据不一致!-" + dbFieldNameList);
+            List<String> missingFields = (List<String>) CollectionUtils.subtract(dbFieldNameList, lowerCaseMdbTableFieldNameList);
+            if (CollectionUtils.isNotEmpty(missingFields)) {
+                throw new ServiceException(mdbTableName + ":图层缺失数据库字段!缺失字段列表=" + missingFields);
+            }
+            //checkInfoList.add(mdbTableName + ":字段数据不一致!-" + dbFieldNameList);
             fzssFxrwrzHandleService.insertFxrwrz(uploadId, "地籍库管理", mdbTableName + ":字段数据不一致!-" + dbFieldNameList, "info");
             checkInfoVo.setCheckStatus(false);
         }
@@ -942,7 +1083,7 @@ public class CadastreManageServiceImpl implements CadastreManageService {
      * @return
      */
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
-    public Boolean fullDataStorage(String tableName, List<Map<String, Object>> theValueList) {
+    public Boolean fullDataStorage(String landRightType,String tableName, List<Map<String, Object>> theValueList) {
         boolean addRes = false;
         Integer shpDbSRID = 4326;
         if (!CollectionUtils.isEmpty(theValueList)) {
@@ -972,6 +1113,12 @@ public class CadastreManageServiceImpl implements CadastreManageService {
             for (Map<String, Object> map : theValueList) {
                 map.put("valid_flag", 0);
                 cleanDataForInsert(map, columnTypeMap);
+                if(tableName.equalsIgnoreCase("zdjbxx")){//这里使用主键自增
+                    map.put("bsm", "DEFAULT");
+                    if(StringUtils.isNotBlank(landRightType)){
+                        map.put("sm", landRightType.trim());
+                    }
+                }
                 cadastreFileMapper.insertTableData(tableName, map, shpDbSRID);
             }
             addRes = true;
@@ -1114,7 +1261,7 @@ public class CadastreManageServiceImpl implements CadastreManageService {
      * @return
      */
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
-    public Boolean incrementDataStorage(String tableName, List<Map<String, Object>> theValueList) {
+    public Boolean incrementDataStorage(String landRightType ,String tableName, List<Map<String, Object>> theValueList) {
         boolean addRes = false;
         Integer shpDbSRID = 4326;
         if (!CollectionUtils.isEmpty(theValueList)) {
@@ -1147,6 +1294,13 @@ public class CadastreManageServiceImpl implements CadastreManageService {
             for (Map<String, Object> map : theValueList) {
                 map.put("valid_flag", 0);
                 cleanDataForInsert(map, columnTypeMap);
+                if(tableName.equalsIgnoreCase("zdjbxx")){//这里使用主键自增
+                    map.put("bsm", "DEFAULT");
+                    //宗地权利类型(1-使用权;2-所有权)
+                    if(StringUtils.isNotBlank(landRightType)){
+                        map.put("sm", landRightType.trim());
+                    }
+                }
                 cadastreFileMapper.insertTableData(tableName, map, shpDbSRID);
             }
             addRes = true;

+ 38 - 21
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/ParcelServiceImpl.java

@@ -36,7 +36,7 @@ public class ParcelServiceImpl implements IParcelService {
         if(StringUtils.isNotBlank(djzqdm) && djzqdm.length() != 12){
             throw new ServiceException("地籍代码长度必须为12位");
         }
-        List<Zdjbxx> zdjbxxListAll = zdjbxxMapper.getListByDjzqdm(djzqdm);
+        List<Zdjbxx> zdjbxxListAll = zdjbxxMapper.getListByDjzqdm(djzqdm,null);
         List<Zdjbxx> zdjbxxList = new ArrayList<>();
 
         // 这里区分所有权和使用权
@@ -81,23 +81,11 @@ public class ParcelServiceImpl implements IParcelService {
         }
 
         ParcelStatisticsRes res = new ParcelStatisticsRes();
-        List<Zdjbxx> zdjbxxListAll = zdjbxxMapper.getListByDjzqdm(djzqdm);
+        List<Zdjbxx> zdjbxxListAll = zdjbxxMapper.getListByDjzqdm(djzqdm,type);
 
         List<Zdjbxx> zdjbxxList = new ArrayList<>();
+        zdjbxxList.addAll(zdjbxxListAll);
         // 这里区分所有权和使用权
-        if("1".equals(type)){
-            zdjbxxMapper.getDictByType("A6","所有权").forEach(item -> {
-                String value = item.get("value").toString();
-                List<Zdjbxx> filterList = zdjbxxListAll.stream().filter(zd-> StringUtils.isBlank(zd.getQllx()) || !value.equals(zd.getQllx())).collect(Collectors.toList());
-                zdjbxxList.addAll(filterList);
-            });
-        }else if("2".equals(type)){
-            zdjbxxMapper.getDictByType("A6","所有权").forEach(item -> {
-                String value = item.get("value").toString();
-                List<Zdjbxx> filterList = zdjbxxListAll.stream().filter(zd-> StringUtils.isNotBlank(zd.getQllx())).filter(zd -> value.equals(zd.getQllx())).collect(Collectors.toList());
-                zdjbxxList.addAll(filterList);
-            });
-        }
 
         List<ParcelStatisticsRes.DetailDTO> detailList = new ArrayList<>();
         List<ParcelStatisticsRes.TdytDTO> tdytStatisticsList = new ArrayList<>();
@@ -127,6 +115,7 @@ public class ParcelServiceImpl implements IParcelService {
 
             //第二部分,主要填充tdytStatisticsList这个对象,统计查询出来的地籍数据的土地用途统计、
             //获取所有一级分类
+            List<Zdjbxx> otherList = new ArrayList<>();
             List<LandType> landTypeList = landTypeMapper.selectFirstLevel();
             Map<String,List<Zdjbxx>> groupedByYtMap = new LinkedHashMap<>();
             landTypeList.forEach(item -> {
@@ -135,8 +124,21 @@ public class ParcelServiceImpl implements IParcelService {
                 List<Zdjbxx> filterList = zdjbxxList.stream().filter(zd-> StringUtils.isNotBlank(zd.getYt())).filter(zd -> value.equals(zd.getYt().substring(0,2))).collect(Collectors.toList());
                 if(CollectionUtils.isNotEmpty(filterList)){
                     groupedByYtMap.put(name, filterList);
+                    otherList.addAll(filterList);
                 }
             });
+            //这里兼容其它类型
+            if(CollectionUtils.isNotEmpty(otherList)){
+                Set<Integer> bsmExtraSet = otherList.stream()
+                        .map(Zdjbxx::getBsm)
+                        .collect(Collectors.toSet());
+                List<Zdjbxx> extraList = zdjbxxList.stream()
+                        .filter(item -> item.getBsm() != null && !bsmExtraSet.contains(item.getBsm()))
+                        .collect(Collectors.toList());
+                if(CollectionUtils.isNotEmpty(extraList)){
+                    groupedByYtMap.put("其它", extraList);
+                }
+            }
 
             //这里遍历map,然后进行统计数据;
             if(MapUtils.isNotEmpty(groupedByYtMap)){
@@ -154,6 +156,7 @@ public class ParcelServiceImpl implements IParcelService {
             res.setTdytStatisticsList(tdytStatisticsList);
 
             //------------------------------------------第三部分,权利性质统计和权利类型统计,这里需要根据查询出来的地籍数据中的权利性质和权利类型进行统计,统计出每种权利性质和权利类型-------------------------------
+            otherList.clear();
             Map<String,List<Zdjbxx>> qlxzGroupedByYtMap = new LinkedHashMap<>();
             zdjbxxMapper.getDictByType("A7",null).forEach(item -> {
                 String name = item.get("name").toString();
@@ -161,9 +164,23 @@ public class ParcelServiceImpl implements IParcelService {
                 List<Zdjbxx> filterList = zdjbxxList.stream().filter(zd-> StringUtils.isNotBlank(zd.getQlxz())).filter(zd -> value.equals(zd.getQlxz())).collect(Collectors.toList());
                 if(CollectionUtils.isNotEmpty(filterList)){
                     qlxzGroupedByYtMap.put(name+"|"+value, filterList);
+                    otherList.addAll(filterList);
                 }
             });
 
+            //这里兼容其它类型
+            if(CollectionUtils.isNotEmpty(otherList)){
+                Set<Integer> bsmExtraSet = otherList.stream()
+                        .map(Zdjbxx::getBsm)
+                        .collect(Collectors.toSet());
+                List<Zdjbxx> extraList = zdjbxxList.stream()
+                        .filter(item -> item.getBsm() != null && !bsmExtraSet.contains(item.getBsm()))
+                        .collect(Collectors.toList());
+                if(CollectionUtils.isNotEmpty(extraList)){
+                    qlxzGroupedByYtMap.put("其它"+"|"+999, extraList);
+                }
+            }
+
             List<ParcelStatisticsRes.QlxzDTO> gy_qlxzStatisticsList = new ArrayList<>(); // 权利性质统计
             List<ParcelStatisticsRes.QlxzDTO> jt_qlxzStatisticsList = new ArrayList<>(); // 权利性质统计
             List<ParcelStatisticsRes.QlxzDTO> wz_qlxzStatisticsList = new ArrayList<>(); // 权利性质统计
@@ -178,11 +195,7 @@ public class ParcelServiceImpl implements IParcelService {
                         totalArea += convertAreaToMu(zd.getZdmj(), zd.getMjdw());
                     }
                     String[] arr = entry.getKey().split("\\|");
-                    if(arr[1].equals("100") || arr[1].equals("200")) {
-                        qlxzDTO.setQlxzmc(arr[0]);
-                        qlxzDTO.setQlxzmj(String.format("%.2f", totalArea));
-                        wz_qlxzStatisticsList.add(qlxzDTO);
-                    }else if(arr[1].startsWith("1")) {
+                    if(arr[1].startsWith("1")) {
                         qlxzDTO.setQlxzmc(arr[0]);
                         qlxzDTO.setQlxzmj(String.format("%.2f", totalArea));
                         gy_qlxzStatisticsList.add(qlxzDTO);
@@ -190,6 +203,10 @@ public class ParcelServiceImpl implements IParcelService {
                         qlxzDTO.setQlxzmc(arr[0]);
                         qlxzDTO.setQlxzmj(String.format("%.2f", totalArea));
                         jt_qlxzStatisticsList.add(qlxzDTO);
+                    }else {
+                        qlxzDTO.setQlxzmc(arr[0]);
+                        qlxzDTO.setQlxzmj(String.format("%.2f", totalArea));
+                        wz_qlxzStatisticsList.add(qlxzDTO);
                     }
                 }
             }
@@ -588,7 +605,7 @@ public class ParcelServiceImpl implements IParcelService {
     @Override
     public List<ParcelStatisticsRes.QlxzDTO> getZdqlxzReport(){
         List<ParcelStatisticsRes.QlxzDTO>  resList = new ArrayList<>();
-        List<Zdjbxx> zdjbxxList = zdjbxxMapper.getListByDjzqdm(null);
+        List<Zdjbxx> zdjbxxList = zdjbxxMapper.getListByDjzqdm(null,null);
         Map<String,List<Zdjbxx>> qlxzGroupedByYtMap = new LinkedHashMap<>();
         zdjbxxMapper.getDictByType("A7",null).forEach(item -> {
             String name = item.get("name").toString();

+ 331 - 11
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/StorageServiceImpl.java

@@ -1,17 +1,18 @@
 package com.siwei.apply.service.cadastre.impl;
 
+import com.siwei.apply.domain.LandType;
+import com.siwei.apply.domain.Tdgy;
 import com.siwei.apply.domain.cadastre.LandStorageInOutReportDTO;
 import com.siwei.apply.domain.cadastre.LandStorageReportDTO;
 import com.siwei.apply.domain.cadastre.LandSupplyReportDTO;
 import com.siwei.apply.domain.res.*;
 import com.siwei.apply.domain.vo.LandSupplyProjectVO;
-import com.siwei.apply.mapper.GjShijiShouchuMapper;
-import com.siwei.apply.mapper.GjShouchuJihuaMapper;
-import com.siwei.apply.mapper.GongdiJihuaMapper;
-import com.siwei.apply.mapper.TdgyMapper;
+import com.siwei.apply.mapper.*;
+import com.siwei.apply.service.NodeLandService;
 import com.siwei.common.core.constant.SecurityConstants;
 import com.siwei.common.core.domain.R;
 import com.siwei.common.core.exception.ServiceException;
+import com.siwei.common.core.utils.DateUtils;
 import com.siwei.common.core.utils.StringUtils;
 import com.siwei.spatial.api.RemoteSpatialFilesDbService;
 import com.siwei.spatial.api.domain.file.TGeomDb;
@@ -19,6 +20,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.ArrayUtils;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.io.WKTReader;
+import org.locationtech.jts.io.WKTWriter;
+import org.locationtech.jts.operation.union.UnaryUnionOp;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -28,6 +33,8 @@ import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.siwei.apply.service.third.impl.DealExcelServiceImpl.allLandTypeList;
+
 @Slf4j
 @Service
 public class StorageServiceImpl {
@@ -63,6 +70,11 @@ public class StorageServiceImpl {
     @Autowired
     private GongdiJihuaMapper gongdiJihuaMapper;
 
+    @Autowired
+    private LandTypeMapper landTypeMapper;
+
+    @Autowired
+    private NodeLandService nodeLandService;
 
 
     public LandStorageInOutReportDTO inOutDetails() {
@@ -451,41 +463,184 @@ public class StorageServiceImpl {
 
     //统计分析
     public List<TrendStatisticsData> getData1() {
-        List<Map<String, Object>> statsList = gjShijiShouchuMapper.getStatsByYear();
         List<TrendStatisticsData> res = new ArrayList<>();
+        //第一部,合并两部分供地数据,把相关的年份和面积计算出来
+        List<TdgyStatisticsRes> completeSjgdList = tdgyMapper.getSjgdListByYear(null, null, null, null);
+        List<Tdgy> tdgyList = tdgyMapper.getTdgyList(null,null);
+        Map<String,Double> outDataAreaMap =  new TreeMap<>();
+        //这里获取实际供地数据:根据年份进行分组:
+        if(CollectionUtils.isNotEmpty(completeSjgdList)){
+            for (TdgyStatisticsRes item : completeSjgdList) {
+                String year = item.getNf();
+                Double area = item.getMjMu() == null ? 0D : item.getMjMu().doubleValue();
+                outDataAreaMap.merge(year, area, Double::sum);
+            }
+        }
+        if(CollectionUtils.isNotEmpty(tdgyList)){
+            for (Tdgy item : tdgyList) {
+                String year = item.getNf();
+                Double area = item.getGdArea() == null ? 0D : item.getGdArea().doubleValue();
+                outDataAreaMap.merge(year, area, Double::sum);
+            }
+        }
+
+        //第二部分,计算入库
+        List<Map<String, Object>> statsList = gjShijiShouchuMapper.getStatsByYear();
         if (CollectionUtils.isNotEmpty(statsList)) {
             for (Map<String, Object> stat : statsList) {
                 TrendStatisticsData data = new TrendStatisticsData();
-                data.setYear(String.valueOf(stat.get("year")));
-                data.setInDataArea(String.valueOf(stat.get("in_data_area")));
+                String year = stat.get("year").toString();
+                data.setYear(year);
+                data.setInDataArea(String.format("%.2f", stat.get("in_data_area")));
                 data.setOutDataArea("0");
+                if(outDataAreaMap.containsKey(year)) {
+                    data.setOutDataArea(String.format("%.2f",outDataAreaMap.remove(year)));
+                }
                 res.add(data);
             }
         }
+
+
+        //如果年份交差情况,剩余的补全
+        if(MapUtils.isNotEmpty(outDataAreaMap)){
+            for (Map.Entry<String, Double> entry : outDataAreaMap.entrySet()) {
+                TrendStatisticsData data = new TrendStatisticsData();
+                String year = entry.getKey();
+                data.setYear(year);
+                data.setOutDataArea(String.format("%.2f",entry.getValue()));
+                data.setInDataArea("0");
+                res.add(data);
+            }
+        }
+
+        //整合2015年前的数据合并到一起
+        List<TrendStatisticsData> tmpRes = new ArrayList<>();
+        int tmpYear = 2015;
+        double  tmpInDataArea = 0d;
+        double  tmpOutDataArea = 0d;
+        for(TrendStatisticsData obj:res){
+            if("其它".equals(obj.getYear())||Integer.parseInt(obj.getYear())>tmpYear){
+                tmpRes.add(obj);
+            }else {
+                tmpInDataArea += Double.parseDouble(obj.getInDataArea());
+                tmpOutDataArea += Double.parseDouble(obj.getOutDataArea());
+            }
+        }
+        if(tmpInDataArea>0d || tmpOutDataArea>0d){
+            TrendStatisticsData data = new TrendStatisticsData();
+            data.setYear("2016年前");
+            data.setInDataArea(String.format("%.2f",tmpInDataArea));
+            data.setOutDataArea(String.format("%.2f",tmpOutDataArea));
+            tmpRes.add(data);
+        }
+        res = tmpRes;
+        //年份排序
+        res = res.stream()
+                .sorted((d1,d2)->{
+                    String y1 = d1.getYear();
+                    String y2 = d2.getYear();
+                    if("其它".equals(y1)) return 1;
+                    if("其它".equals(y2)) return -1;
+                    if("2016年前".equals(y1)) return -1;
+                    if("2016年前".equals(y2)) return 1;
+                    return Integer.parseInt(y1)-Integer.parseInt(y2);
+                }).collect(Collectors.toList());
         return res;
     }
 
+
     public List<TrendUseStatisticsData> getData2(String year) {
         if ("0".equals(year)) {
             year = null;
         }
+
+        //出库数据(供应数据)
+        List<TdgyStatisticsRes> completeSjgdList = tdgyMapper.getSjgdListByYear(year, null, null, null);
+        List<Tdgy> tdgyList = tdgyMapper.getTdgyList(year,year);
+        //这里获取实际供地数据:根据年份进行分组:
+
+        Map<String,Double> outDataAreaMap =  new TreeMap<>();
+        //这里获取实际供地数据:根据年份进行分组:
+        if(CollectionUtils.isNotEmpty(completeSjgdList)){
+            for (TdgyStatisticsRes item : completeSjgdList) {
+                String tdyt = item.getTdyt();
+                Double area = item.getMjMu() == null ? 0D : item.getMjMu().doubleValue();
+                outDataAreaMap.merge(tdyt, area, Double::sum);
+            }
+        }
+        if(CollectionUtils.isNotEmpty(tdgyList)){
+            for (Tdgy item : tdgyList) {
+                String tdyt = item.getTdyt();
+                Double area = item.getGdArea() == null ? 0D : item.getGdArea().doubleValue();
+                outDataAreaMap.merge(tdyt, area, Double::sum);
+            }
+        }
+
+        //这里code -name
+        Map<String,Double> tmpOutDataAreaMap =  new TreeMap<>();
+        if(MapUtils.isNotEmpty(outDataAreaMap)){
+            Set<String> tdytCodeSet =  outDataAreaMap.keySet();
+            for(String code : tdytCodeSet){
+                String category = getTdytByCode(code);
+                if(StringUtils.isBlank(category)){
+                    category = "未知"+code;
+                }
+                tmpOutDataAreaMap.put(category,outDataAreaMap.get(code));
+            }
+            outDataAreaMap = tmpOutDataAreaMap;
+        }
+
+        //入库数据
         List<Map<String, Object>> statsList = gjShijiShouchuMapper.getStatsByYearAndUse(year);
         List<TrendUseStatisticsData> res = new ArrayList<>();
         if (CollectionUtils.isNotEmpty(statsList)) {
             for (Map<String, Object> stat : statsList) {
                 TrendUseStatisticsData data = new TrendUseStatisticsData();
-                data.setUseName(convertCategory(String.valueOf(stat.get("use_name"))));
+                String category = convertCategory(String.valueOf(stat.get("use_name")));
+                data.setUseName(category);
                 data.setInDataArea(String.valueOf(stat.get("in_data_area")));
                 data.setOutDataArea("0");
+                if(outDataAreaMap.containsKey(category)) {
+                    data.setOutDataArea(String.format("%.2f",outDataAreaMap.remove(category)));
+                }
                 res.add(data);
             }
         }
+
+        //如果年份交差情况,剩余的补全
+        if(MapUtils.isNotEmpty(outDataAreaMap)){
+            for (Map.Entry<String, Double> entry : outDataAreaMap.entrySet()) {
+                TrendUseStatisticsData data = new TrendUseStatisticsData();
+                String category = entry.getKey();
+                data.setUseName(category);
+                data.setOutDataArea(String.format("%.2f",entry.getValue()));
+                data.setInDataArea("0");
+                res.add(data);
+            }
+        }
+
         return res;
     }
 
+
+
+
+
+
+    public List<Map<String, Object>> landStock(String year) {
+        if(StringUtils.isBlank(year)||"0".equals(year)){
+            year = null;
+        }
+        List<Map<String, Object>> statsList = gjShijiShouchuMapper.queryDifferenceGeomAreaByYearOfShouchu(year);
+        return  statsList;
+    }
+
+
     public StorageYearStatisticsRes getYearStatistics(String year) {
         StorageYearStatisticsRes res = new StorageYearStatisticsRes();
-
+        if(StringUtils.isBlank(year)||"0".equals(year)){
+            year = "";
+        }
         Map<String, Object> planSummary = gjShouchuJihuaMapper.getPlanSummaryByYear(year);
         List<TdgyStatisticsRes> completeList = gjShijiShouchuMapper.gjShijiShouchuListByYear(year, null, null, null, null, null);
         BigDecimal planArea = toBigDecimal(planSummary == null ? null : planSummary.get("plan_area"));
@@ -512,10 +667,113 @@ public class StorageServiceImpl {
         return res;
     }
 
+
+    public List<LandSupplyProjectVO> inOutProjectList(String year, Integer supplyType,String useType) {
+        List<LandSupplyProjectVO> resList = new ArrayList<>();
+        if (supplyType == 1||supplyType == 0) {//入库
+            List<TdgyStatisticsRes> completeList = gjShijiShouchuMapper.gjShijiShouchuListByYear(year, null, null, null, null, null);
+            if (CollectionUtils.isNotEmpty(completeList)) {
+                for (TdgyStatisticsRes item : completeList) {
+                    LandSupplyProjectVO vo = new LandSupplyProjectVO();
+                    String category = convertCategory(item.getTdyt());
+                    vo.setProjectPropertyId(item.getProjectId());
+                    vo.setNodeId(item.getNodeId());
+                    vo.setProjectName(item.getXmmc());
+                    vo.setCompanyName("暂无");
+                    vo.setSupplyMethod(item.getGyfs());
+                    vo.setSupplyType("1");
+                    vo.setDateType("1");
+                    vo.setGeom(item.getGeom());
+                    vo.setYear(item.getGysj());
+                    vo.setArea(String.format("%.2f", item.getMjMu() == null ? BigDecimal.ZERO : item.getMjMu()));
+                    vo.setUseType(category);
+                    resList.add(vo);
+                }
+            }
+        }
+        if (supplyType == 2||supplyType == 0) {//这里计算供地,用两部分数据进行实例化
+            List<TdgyStatisticsRes> completeSjgdList = tdgyMapper.getSjgdListByYear(year, null, null, null);
+            List<Tdgy> tdgyList = tdgyMapper.getTdgyList(year,year);
+            //这里获取实际供地数据:根据年份进行分组:
+            if(CollectionUtils.isNotEmpty(completeSjgdList)){
+                for (TdgyStatisticsRes item : completeSjgdList) {
+                    LandSupplyProjectVO vo = new LandSupplyProjectVO();
+                    String category = getTdytByCode(item.getTdyt());
+                    vo.setProjectPropertyId(item.getProjectId());
+                    vo.setNodeId(item.getNodeId());
+                    vo.setProjectName(item.getXmmc());
+                    vo.setCompanyName("暂无");
+                    vo.setSupplyMethod(item.getGyfs());
+                    vo.setSupplyType("2");
+                    vo.setDateType("2");
+                    vo.setGeom(item.getGeom());
+                    vo.setYear(item.getGysj());
+                    vo.setArea(String.format("%.2f", item.getMjMu() == null ? BigDecimal.ZERO : item.getMjMu()));
+                    vo.setUseType(category);
+                    resList.add(vo);
+                }// end for
+            }
+
+            if(CollectionUtils.isNotEmpty(tdgyList)){
+                for (Tdgy item : tdgyList) {
+                    LandSupplyProjectVO vo = new LandSupplyProjectVO();
+                    String category = getTdytByCode(item.getTdyt());
+                    vo.setProjectPropertyId(item.getProjectId());
+                    vo.setNodeId(item.getId());
+                    vo.setProjectName("");
+                    vo.setCompanyName("暂无");
+                    vo.setSupplyMethod(item.getGdType());
+                    vo.setSupplyType("3");
+                    vo.setDateType("3");
+                    List<Map<String, String>> geomDetailsList= nodeLandService.selectTGeomDbDetailsByNodeId(item.getId());
+                    if(CollectionUtils.isNotEmpty(geomDetailsList)){
+                        //这里合并geom
+                        List<String> geomWkts = geomDetailsList.stream().map(s -> s.get("geom"))
+                                .filter(StringUtils::isNotBlank)
+                                .collect(Collectors.toList());
+                        if(geomWkts.size() == 1){
+                            vo.setGeom(geomWkts.get(0));
+                        }else {
+                            vo.setGeom(unionGeoms(geomWkts));
+                        }
+                    }
+                    vo.setYear(DateUtils.parseDate(item.getHbcrhtDate()));
+                    vo.setArea(String.format("%.2f", item.getGdArea() == null ? BigDecimal.ZERO : item.getGdArea()));
+                    vo.setUseType(category);
+                    resList.add(vo);
+                }
+            }
+        }
+
+        if(StringUtils.isNotBlank(useType)){ //这里通过用途计算
+            resList = resList.stream().filter(s->s.getUseType().equals(useType)).collect(Collectors.toList());
+        }
+        return resList;
+    }
+
+
     public List<LandSupplyProjectVO> projectList(String year, Integer supplyType) {
         return projectList(year, supplyType, null);
     }
 
+    public List<LandSupplyProjectVO> projectList(String year, Integer supplyType, String supplyMethod,String useType){
+        List<LandSupplyProjectVO> res = new ArrayList<>();
+        List<LandSupplyProjectVO> list = projectList(year, supplyType, null);
+        if(CollectionUtils.isNotEmpty(list)){
+            if(StringUtils.isNotBlank(useType)) {
+                list = list.stream().filter(s -> s.getUseType().equals(useType)).collect(Collectors.toList());
+            }
+            if(StringUtils.isNotBlank(supplyMethod)) {
+                list = list.stream().filter(s -> s.getSupplyMethod().equals(supplyMethod)).collect(Collectors.toList());
+            }
+            res.addAll(list);
+        }
+        return res;
+    }
+
+
+
+
     public List<LandSupplyProjectVO> projectList(String year, Integer supplyType, String keyWord) {
         List<LandSupplyProjectVO> resList = new ArrayList<>();
         if (supplyType == 1) {
@@ -569,6 +827,7 @@ public class StorageServiceImpl {
             vo.setSupplyMethod(item.getGyfs());
             vo.setSupplyType("1");
             vo.setDateType("1");
+            vo.setUseType(item.getTdyt());
             vo.setGeom(item.getGeom());
             vo.setYear(item.getGysj());
             vo.setArea(String.format("%.2f", item.getMjMu() == null ? BigDecimal.ZERO : item.getMjMu()));
@@ -593,6 +852,8 @@ public class StorageServiceImpl {
             vo.setGeom(item.getGeom());
             vo.setYear(item.getGysj());
             vo.setArea(String.valueOf(item.getMjMu()));
+            vo.setUseType(item.getTdyt());
+
             return vo;
         }).collect(Collectors.toList());
     }
@@ -622,7 +883,7 @@ public class StorageServiceImpl {
     private List<ProjectSupplyRes> buildMethodStatistics(String year) {
         List<Map<String, Object>> planStats = gjShouchuJihuaMapper.getPlanStatsByMethod(year);
         List<Map<String, Object>> completeStats = gjShijiShouchuMapper.getCompleteStatsByMethod(year);
-        String[]  category = {"征收","收回","收购","其他"};
+        String[]  category = {"征收","征地","收回","收购","其他"};
         List<ProjectSupplyRes> res = new ArrayList<>();
         for(String cate : category){
             ProjectSupplyRes item = new ProjectSupplyRes();
@@ -704,7 +965,7 @@ public class StorageServiceImpl {
 
     private String convertCategory(String category) {
         if (category == null || category.equals("未知") || category.equals("null") || category.trim().isEmpty()) {
-            return "其";
+            return "其";
         }
         return category;
     }
@@ -930,5 +1191,64 @@ public class StorageServiceImpl {
         }
     }
 
+    public String getTdytByCode(String code) {
+        String name = "";
+        List<LandType> all = landTypeMapper.selectAll();
+        // 转换为节点
+        Optional<LandType> filterRes = all.stream().filter(s -> s.getCode().equalsIgnoreCase(code)).findFirst();
+        if (filterRes.isPresent()) {
+            name = filterRes.get().getName();
+        }
+        return name;
+    }
+
+    /**
+     * 模拟 st_union方法实现
+     * @param geomWkts
+     * @return
+     */
+    private String unionGeoms(List<String> geomWkts) {
+        if (CollectionUtils.isEmpty(geomWkts)) {
+            return null;
+        }
+        WKTReader reader = new WKTReader();
+        WKTWriter writer = new WKTWriter();
+        Integer srid = null;
+        List<Geometry> geoms = new ArrayList<>();
+        for (String wkt : geomWkts) {
+            if (StringUtils.isBlank(wkt)) {
+                continue;
+            }
+            String clean = wkt.trim();
+            // 处理 "SRID=xxxx;" 前缀(PostGIS ST_AsEWKT 的输出格式)
+            if (clean.startsWith("SRID=")) {
+                int semi = clean.indexOf(';');
+                if (semi > 0) {
+                    srid = Integer.parseInt(clean.substring(5, semi));
+                    clean = clean.substring(semi + 1);
+                }
+            }
+            try {
+                Geometry g = reader.read(clean);
+                if (!g.isEmpty()) {
+                    geoms.add(g);
+                }
+            } catch (Exception e) {
+                // 单条解析失败跳过,不要整体崩掉(可记日志)
+                log.error("解析几何失败: {}", clean, e);
+            }
+        }
+        if (geoms.isEmpty()) {
+            return null;
+        }
+        // 只有一条直接返回,避免无意义的 union 计算
+        Geometry result = geoms.size() == 1 ? geoms.get(0) : UnaryUnionOp.union(geoms);   // 等价 ST_Union
+        String wkt = writer.write(result);
+        return srid != null ? "SRID=" + srid + ";" + wkt : wkt;
+    }
+
+
+
+
 
 }

+ 190 - 18
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/cadastre/impl/SupplyServiceImpl.java

@@ -18,6 +18,7 @@ import com.siwei.common.core.domain.R;
 import com.siwei.common.core.exception.ServiceException;
 import com.siwei.common.core.utils.StringUtils;
 import com.siwei.spatial.api.RemoteSpatialFilesDbService;
+import com.siwei.system.api.domain.SysDictData;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
@@ -29,6 +30,8 @@ import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.siwei.apply.service.third.impl.DealExcelServiceImpl.allLandTypeList;
+
 
 @Slf4j
 @Service
@@ -59,6 +62,125 @@ public class SupplyServiceImpl implements ISupplyService {
     }
 
 
+
+    @Override
+    public List<LandSupplyProjectVO> useTypeAndMethodList(String year,String useType,String  supplyType,String methodType) {
+        List<LandSupplyProjectVO> resList = new ArrayList<>();
+        if("0".equals(supplyType)){
+            GongdiJihuaFilterVo filterVo = new GongdiJihuaFilterVo();
+            filterVo.setYear(year);
+            filterVo.setPageSize(100000);
+
+            List<GongdiJihua> planList = gongdiJihuaMapper.getList(filterVo);
+            List<LandSupplyProjectVO> resList1 = planList.stream().map(item -> {
+                LandSupplyProjectVO vo = new LandSupplyProjectVO();
+                vo.setProjectPropertyId(String.valueOf(item.getGid()));
+                vo.setProjectName(item.getXmmc());
+                vo.setCompanyName("暂无");
+                vo.setSupplyMethod(item.getGyfs());
+                vo.setUseType(item.getTdyt());
+                vo.setSupplyType("1");
+                vo.setDateType("1");
+                vo.setGeom(item.getGeom());
+                return vo;
+            }).collect(Collectors.toList());
+
+            //这里合并两部分数据
+            List<TdgyStatisticsRes> completeList = new ArrayList<>();
+            List<TdgyStatisticsRes> completeBusinessStatusList = dgyMapper.getListByYear(year, null, null, null);
+            List<TdgyStatisticsRes> completeSjgdList = dgyMapper.getSjgdListByYear(year, null, null, null);
+            if(CollectionUtils.isNotEmpty(completeBusinessStatusList)){
+                completeList.addAll(completeBusinessStatusList);
+            }
+            if(CollectionUtils.isNotEmpty(completeSjgdList)){
+                completeList.addAll(completeSjgdList);
+            }
+            List<LandSupplyProjectVO> resList2 = completeList.stream().map(item -> {
+                LandSupplyProjectVO vo = new LandSupplyProjectVO();
+                vo.setProjectPropertyId(item.getProjectId());
+                vo.setProjectName(item.getXmmc());
+                vo.setCompanyName(item.getCompany());
+                vo.setSupplyMethod(item.getGyfs());
+                vo.setUseType(item.getTdyt());
+                vo.setSupplyType("2");
+                vo.setDateType("2");
+                if(StringUtils.isBlank(item.getProjectId())){
+                    vo.setDateType("3");
+                }
+                vo.setNodeId(item.getNodeId());
+                vo.setGeom(item.getGeom());
+                return vo;
+            }).collect(Collectors.toList());
+            if(CollectionUtils.isNotEmpty(resList1)) {
+                resList.addAll(resList1);
+            }
+            if(CollectionUtils.isNotEmpty(resList2)) {
+                resList.addAll(resList2);
+            }
+        } else if ("2".equals(supplyType)) {
+            //这里合并两部分数据
+            List<TdgyStatisticsRes> completeList = new ArrayList<>();
+            List<TdgyStatisticsRes> completeBusinessStatusList = dgyMapper.getListByYear(year, null, null, null);
+            List<TdgyStatisticsRes> completeSjgdList = dgyMapper.getSjgdListByYear(year, null, null, null);
+            if(CollectionUtils.isNotEmpty(completeBusinessStatusList)){
+                completeList.addAll(completeBusinessStatusList);
+            }
+            if(CollectionUtils.isNotEmpty(completeSjgdList)){
+                completeList.addAll(completeSjgdList);
+            }
+
+            resList = completeList.stream().map(item -> {
+                LandSupplyProjectVO vo = new LandSupplyProjectVO();
+                vo.setProjectPropertyId(item.getProjectId());
+                vo.setProjectName(item.getXmmc());
+                vo.setCompanyName(item.getCompany());
+                vo.setSupplyMethod(item.getGyfs());
+                vo.setSupplyType(supplyType.toString());
+                vo.setDateType(supplyType.toString());
+                vo.setUseType(item.getTdyt());
+                if(StringUtils.isBlank(item.getProjectId())){
+                    vo.setDateType("3");
+                }
+                vo.setNodeId(item.getNodeId());
+                vo.setGeom(item.getGeom());
+                vo.setYear(item.getGysj());
+                return vo;
+            }).collect(Collectors.toList());
+        }
+
+        if(StringUtils.isNotBlank(methodType)){
+            if("出让".equals(methodType)||"划拨".equals(methodType)){
+                resList = resList.stream().filter(o->o.getSupplyMethod().equals(methodType)).collect(Collectors.toList());
+            }else {
+                resList = resList.stream().filter(o->!o.getSupplyMethod().equals("出让")).filter(o->!o.getSupplyMethod().equals("划拨")).collect(Collectors.toList());
+            }
+        }
+        if (StringUtils.isNotBlank(useType)) {
+            String code = getTdytCodeByName(useType);
+            if(StringUtils.isNotBlank(code)){
+                resList = resList.stream().filter(o->Objects.nonNull(o.getUseType()) && StringUtils.substring(o.getUseType(),0,2).equals(code)).collect(Collectors.toList());
+            }
+        }
+        return resList;
+    }
+
+
+
+    public String getTdytCodeByName(String useName) {
+        if (allLandTypeList.isEmpty()) {
+            List<LandType> all = landTypeMapper.selectAll();
+            allLandTypeList.addAll(all);
+        }
+        String code = "";
+        // 转换为节点
+        Optional<LandType> filterRes = allLandTypeList.stream().filter(s -> s.getName().equalsIgnoreCase(useName)).findFirst();
+        if (filterRes.isPresent()) {
+            code = filterRes.get().getCode();
+        }
+        return code;
+    }
+
+
     /**
      * 年度统计
      * @param year
@@ -66,6 +188,9 @@ public class SupplyServiceImpl implements ISupplyService {
      */
     @Override
     public SupplyYearStatisticsRes yearStatistics(String year) {
+        if(StringUtils.isBlank(year)||"0".equals(year)){
+            year = "";
+        }
         SupplyYearStatisticsRes res = new SupplyYearStatisticsRes();
         GongdiJihuaFilterVo filterVo = new GongdiJihuaFilterVo();
         filterVo.setYear(year);
@@ -83,11 +208,16 @@ public class SupplyServiceImpl implements ISupplyService {
             completeList.addAll(completeSjgdList);
         }
 
-        if(CollectionUtils.isNotEmpty(list)) {
-            double completeRate =0;
-            if(CollectionUtils.isNotEmpty(completeList)) {
-                completeRate = (double) completeList.size() / list.size() * 100;
+        {
+            int size = 1;
+            if(CollectionUtils.isEmpty(list)){
+                list = new ArrayList<>();
+            }else {
+                size = list.size();
             }
+            double completeRate =0;
+            completeRate = (double) completeList.size() / size * 100;
+
             SupplyRateRes supplyRate = new SupplyRateRes();
             //这里先计算一个供应率,后续可以根据实际需求计算其他数据
             supplyRate.setCompleteRate((int) completeRate);
@@ -100,7 +230,6 @@ public class SupplyServiceImpl implements ISupplyService {
                 .mapToDouble(g -> g.getMjM().doubleValue())
                 .sum();
             supplyRate.setPlanArea((float) planArea);
-
             //完成的计算加总值
             double completeArea = completeList.stream()
                     .filter(g -> g.getMjMu() != null)
@@ -134,7 +263,7 @@ public class SupplyServiceImpl implements ISupplyService {
                         String code = g.getTdyt().substring(0, 2);
                         String categoryName = codeToNameCache.computeIfAbsent(code, k -> {
                             LandType landType = landTypeMapper.selectByCode(k);
-                            return landType != null ? landType.getName() : null;
+                            return landType != null ? landType.getName() : "其它";
                         });
 
                         if (categoryName != null) {
@@ -244,9 +373,7 @@ public class SupplyServiceImpl implements ISupplyService {
                     int year = item.getGysj().getYear() + 1900;
                     double area = item.getMjMu() != null ? item.getMjMu().doubleValue() : 0.0;
                     String gyfs = item.getGyfs();
-
                     areaByYear.merge(year, area, Double::sum);
-
                     Map<String, Double> yearModeMap = modeAreaByYear.computeIfAbsent(year, k -> new HashMap<>());
                     if ("划拨".equals(gyfs)) {
                         yearModeMap.merge("allocate", area, Double::sum);
@@ -258,22 +385,67 @@ public class SupplyServiceImpl implements ISupplyService {
                 }
             }
 
-            areaByYear.forEach((year, area) -> {
+            int tmpYear = 2015;
+            double  tmpArea = 0d;
+            for (Map.Entry<Integer, Double> entry : areaByYear.entrySet()){
+                Integer year = entry.getKey();
+                Double area = entry.getValue();
+                if(year>tmpYear){
+                    Map<String, Object> map = new LinkedHashMap<>();
+                    map.put("year", year);
+                    map.put("area", area);
+                    areaTrendStatisticsList.add(map);
+                }else{
+                    tmpArea+=area;
+                }
+            }
+            //2015年之前的数据折合到一个年份中
+            if(tmpArea>0d){
                 Map<String, Object> map = new LinkedHashMap<>();
-                map.put("year", year);
-                map.put("area", area);
+                map.put("year", "2016年前");
+                map.put("area", tmpArea);
                 areaTrendStatisticsList.add(map);
-            });
+            }
 
-            modeAreaByYear.forEach((year, modeAreas) -> {
+            //第二部分015年之前的数据折合到一个年份中
+            double  tmpTransferArea = 0d;
+            double  tmpAllocateArea = 0d;
+            double  tmpOtherArea = 0d;
+            for (Map.Entry<Integer, Map<String, Double>> entry : modeAreaByYear.entrySet()) {
+                Integer year = entry.getKey();
+                Map<String, Double> modeAreas = entry.getValue();
+                if(year>tmpYear) {
+                    Map<String, Object> map = new LinkedHashMap<>();
+                    map.put("year", year);
+                    map.put("transferArea", modeAreas.getOrDefault("transfer", 0.0));
+                    map.put("allocateArea", modeAreas.getOrDefault("allocate", 0.0));
+                    map.put("otherArea", modeAreas.getOrDefault("other", 0.0));
+                    supplyModeStatisticsList.add(map);
+                }else {
+                     tmpTransferArea += modeAreas.getOrDefault("transfer", 0.0);
+                     tmpAllocateArea += modeAreas.getOrDefault("allocate", 0.0);
+                     tmpOtherArea += modeAreas.getOrDefault("other", 0.0);
+                }
+            }
+            {//这里把汇总的增加到返回结果中
                 Map<String, Object> map = new LinkedHashMap<>();
-                map.put("year", year);
-                map.put("transferArea", modeAreas.getOrDefault("transfer", 0.0));
-                map.put("allocateArea", modeAreas.getOrDefault("allocate", 0.0));
-                map.put("otherArea", modeAreas.getOrDefault("other", 0.0));
+                map.put("year", "2016年前");
+                map.put("transferArea", tmpTransferArea);
+                map.put("allocateArea", tmpAllocateArea);
+                map.put("otherArea", tmpOtherArea);
                 supplyModeStatisticsList.add(map);
-            });
+            }
+
+//            modeAreaByYear.forEach((year, modeAreas) -> {
+//                Map<String, Object> map = new LinkedHashMap<>();
+//                map.put("year", year);
+//                map.put("transferArea", modeAreas.getOrDefault("transfer", 0.0));
+//                map.put("allocateArea", modeAreas.getOrDefault("allocate", 0.0));
+//                map.put("otherArea", modeAreas.getOrDefault("other", 0.0));
+//                supplyModeStatisticsList.add(map);
+//            });
         }
+
         res.setAreaTrendStatisticsList(areaTrendStatisticsList);
         res.setSupplyModeStatisticsList(supplyModeStatisticsList);
         return res;

+ 16 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/JsydghxkImpl.java

@@ -91,6 +91,22 @@ public class JsydghxkImpl implements JsydghxkService {
         return jsydghxkRes;
     }
 
+
+
+    //todo 支持多节点
+    public JsydghxkRes getAll(String projectId) {
+        List<Jsydghxk> jsydghxkList = jsydghxkMapper.getList(projectId);
+        Project project = projectMapper.get(projectId);
+        JsydghxkRes jsydghxkRes = new JsydghxkRes();
+        jsydghxkRes.setProjectId(projectId);
+        jsydghxkRes.setProjectName(project.getName());
+        jsydghxkRes.setProjectCode(project.getCode());
+        jsydghxkRes.setJsydghxkList(jsydghxkList);
+        return jsydghxkRes;
+    }
+
+
+
     @Override
     public JsydghxkRes getById(String id) {
         Jsydghxk record = jsydghxkMapper.getById(id);

+ 11 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/NodeLandImpl.java

@@ -209,6 +209,17 @@ public class NodeLandImpl implements NodeLandService {
         return nodeLandMapper.selectGeomContainsNode(geomDetailsId);
     }
 
+
+
+
+    @Override
+    public List<Map<String,String>> selectGeomIntersectsNode(String geomDetailsId) {
+        return nodeLandMapper.selectGeomIntersectsNode(geomDetailsId);
+    }
+
+
+
+
     /**
      * 存在一个节点多个地块,一次上传多个地块
      * @param geomDbId

+ 6 - 0
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/ProjectImpl.java

@@ -332,6 +332,8 @@ public class ProjectImpl implements ProjectService {
                 projectWorkflowList = projectWorkflowList.stream()
                         .sorted(Comparator.comparing(ProjectWorkflow::getWorkflowId).reversed())
                         .collect(Collectors.toList());
+
+                Boolean haveOnchain = false;
                 for (ProjectWorkflow projectWorkflow : projectWorkflowList) {
                     String nodeTableName = projectWorkflow.getNodeTableName();
                     String nodeId = projectWorkflow.getNodeId();
@@ -343,9 +345,13 @@ public class ProjectImpl implements ProjectService {
                         } else {
                             progressMap.put(projectWorkflow.getWorkflowName(), 1);
                         }
+                        haveOnchain = true;
                         break;
                     }
                 }
+                if(haveOnchain.equals(false)){
+                    log.error("无效数据---节点全未上链,但是项目上链数有加总- projectId:{}", projectId);
+                }
             }
 
             // 获取项目进度

+ 12 - 30
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/impl/TdgyImpl.java

@@ -173,44 +173,26 @@ public class TdgyImpl implements TdgyService {
             Map <String, String> resultMap = new HashMap<>();
             for (Map<String, String> geomDetailsMap : geomDetailsList) {
                 String geomDetailsId = geomDetailsMap.get("id");
-                //校验图斑是否包含批次报批节点(重点)
-                Map<String, String> geomDetailsAndNodeMap = nodeLandService.selectGeomContainsNode(geomDetailsId);
-                if(!MapUtils.isEmpty(geomDetailsAndNodeMap)){
+                //校验图斑是否与批次报批节点有交集支持多年份多批次的包含(重点)
+                List<Map<String, String>> geomDetailsAndNodeList = nodeLandService.selectGeomIntersectsNode(geomDetailsId);
+                if(CollectionUtils.isEmpty(geomDetailsAndNodeList)){
+                    throw new ServiceException("当前地块未被包含审核过的批次报批空间数据中,请检查后再上链!");
+                }
+                for(Map<String, String> geomDetailsAndNodeMap : geomDetailsAndNodeList){
                     String nodeId = geomDetailsAndNodeMap.get("node_id");
                     resultMap.put(nodeId, geomDetailsAndNodeMap.get("id"));
                 }
             }
-            if(resultMap.isEmpty()){
-                throw new ServiceException("当前地块未被包含审核过的批次报批空间数据中,请检查后再上链!");
-            }
-            if(resultMap.size()>1){
-                throw new ServiceException("当前地块未包含多个地块,报批数据不在同一批次!");
-            }
 
             String tableName ="t_ydbp_data";
             //获取到对应的批次报批节点,插入到流程表中
-            String nodeId = resultMap.keySet().stream().findFirst().get();
             Workflow workflow = workflowMapper.selectByProjectTypeAndTableName(Integer.valueOf(ProjectType.BATCH.getCode()), tableName);
-            //先检查是否存在,避免重复上链插入多次
-            ProjectWorkflow projectWorkflow = new ProjectWorkflow();
-            List<ProjectWorkflow> projectWorkflowList = projectWorkflowMapper.selectByProjectId(projectId);
-            if(!CollectionUtils.isEmpty(projectWorkflowList)){
-                Optional<ProjectWorkflow>  result = projectWorkflowList.stream().filter(o->o.getNodeTableName().equals(tableName)).findFirst();
-                if(result.isPresent()){
-                    projectWorkflow = result.get();
-                }
-            }
-
-            //todo 这里需要调用附件信息全文检索方法维护列表附件名称数据
-            if(Objects.nonNull(projectWorkflow.getId())){
-                projectWorkflow.setParentId(id);
-                //projectWorkflow.setWorkflowId(workflow.getId());
-                projectWorkflow.setProjectId(projectId);
-                projectWorkflow.setNodeId(nodeId);
-                //projectWorkflow.setNodeTableName(workflow.getTableName());
-                //projectWorkflow.setWorkflowName(workflow.getName());
-                projectWorkflowMapper.update(projectWorkflow);
-            }else {
+            Set<String> nodeIdSet =  new HashSet<>(resultMap.keySet());
+            //首先删除当前项目的数据
+            projectWorkflowMapper.deleteByProjectId(projectId,null,workflow.getTableName());
+            for(String nodeId : nodeIdSet){
+                //先检查是否存在,避免重复上链插入多次
+                ProjectWorkflow projectWorkflow = new ProjectWorkflow();
                 //设置流程主键
                 projectWorkflow.generateId();
                 projectWorkflow.setParentId(id);

+ 223 - 14
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/third/impl/DealExcelServiceImpl.java

@@ -1,26 +1,23 @@
 package com.siwei.apply.service.third.impl;
 
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
 import com.siwei.apply.common.Constant;
 import com.siwei.apply.domain.LandType;
 import com.siwei.apply.domain.NodeLand;
 import com.siwei.apply.domain.ProjectWorkflow;
 import com.siwei.apply.domain.YdbpData;
 import com.siwei.apply.domain.res.TdgyRes;
-import com.siwei.apply.domain.vo.GyjsydscdjVo;
-import com.siwei.apply.domain.vo.GyjsydjfwscdjVo;
-import com.siwei.apply.domain.vo.JsgcghxkVo;
-import com.siwei.apply.domain.vo.JsydghxkVo;
-import com.siwei.apply.domain.vo.ProjectVo;
-import com.siwei.apply.domain.vo.TdgyVo;
-import com.siwei.apply.domain.vo.TdhyhsVo;
-import com.siwei.apply.domain.vo.TjyydhxVo;
-import com.siwei.apply.domain.vo.YdbpDataVo;
-import com.siwei.apply.domain.vo.YdbpVo;
-import com.siwei.apply.domain.vo.YdysyxzVo;
+import com.siwei.apply.domain.vo.*;
 import com.siwei.apply.enums.AloneWorkFlowEnum;
 import com.siwei.apply.mapper.CadastreFileMapper;
 import com.siwei.apply.mapper.LandTypeMapper;
 import com.siwei.apply.service.*;
+import com.siwei.apply.utils.ServiceFileUtil;
+import com.siwei.apply.utils.ServiceUtil;
 import com.siwei.common.core.constant.SecurityConstants;
 import com.siwei.common.core.domain.R;
 import com.siwei.common.core.utils.StringUtils;
@@ -28,6 +25,7 @@ import com.siwei.spatial.api.RemoteSpatialFilesDbService;
 import com.siwei.spatial.api.domain.file.TGeomDb;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.io.FileUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -58,6 +56,8 @@ public class DealExcelServiceImpl {
     private final String rootPath2020 = Constant.IMPORT_EXCEL_DATA_FILE_PATH + "\\数据治理批量导入示例数据\\赣江新区项目文件夹建立\\1.出让项目\\2020";
     private final String rootPathZip = Constant.IMPORT_EXCEL_DATA_FILE_PATH + "\\zip";
     private final String targectDir = Constant.FILE_UPLOAD_PATH;
+    private static final String bdcFileDownPath =  Constant.BDC_FILE_DOWN_PATH;
+
 
     public final static List<LandType> allLandTypeList = new ArrayList<>();
 
@@ -112,6 +112,215 @@ public class DealExcelServiceImpl {
     @Autowired
     private LandOneCodeService landOneCodeService;
 
+
+    /**
+     * 下载相关的不动产材料附件
+     * @param dataMap
+     * @return
+     */
+    public String excelImmobileDownFile_HOUSE(Map<String, List<Map<String, String>>> dataMap) {
+        List<Map<String, String>> immobileList = dataMap.get("不动产权信息列表");
+        int i=0;
+        Set<String> ywhSet = immobileList.stream().map(s->s.get("业务号")).collect(Collectors.toSet());
+        for (String ywbh : ywhSet) {
+            Map<String, Object> retMap = new HashMap<>();
+            String new_ywbh = ywbh+"01";
+            //todo 这里进行远程请求,获取相关数据,解析后入库
+            try {
+                Map<String,Object> paramMap = new LinkedHashMap<>();
+                paramMap.put("ywbh",new_ywbh);
+                paramMap.put("yfbdcdyh","");
+                String remoteResult = ServiceUtil.getRemoteDataByHttpClient("query.houseRegist.datas",paramMap);
+                JSONObject root = JSON.parseObject(remoteResult);
+                log.info("远程调用返回结果: {}", root);
+                JSONObject innerDataCheck = root.getJSONObject("data");
+                if(!innerDataCheck.get("code").equals("200")){
+                    log.warn("接口请求返回: {},ywh:{}", innerDataCheck,ywbh);
+                    continue;
+                }
+                //todo 这里需要确认用户返回的是数组还是对象
+                JSONArray innerArray =  root.getJSONObject("data").getJSONArray("data");
+                String prettyJson = JSON.toJSONString(innerArray, JSONWriter.Feature.PrettyFormat);
+                //这里记录日志
+                writeToLog(ywbh+".txt",prettyJson);
+                retMap.put("body",prettyJson);
+            } catch (Exception e) {
+                log.error("调用矢量保存文件错误,业务编号:{}: ", ywbh);
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+
+            //第二部分获取附件数据
+            try {
+                if(MapUtils.isNotEmpty(retMap)){
+                    Map<String,Object> paramMap = new LinkedHashMap<>();
+                    paramMap.put("ywbh",new_ywbh);
+                    String remoteResult = ServiceUtil.getRemoteDataByHttpClient("query.ywFiles.datas",paramMap);
+                    JSONObject root = JSON.parseObject(remoteResult);
+                    JSONObject innerData = root.getJSONObject("data").getJSONObject("data");
+                    LandFirstParamVo body = JSON.parseObject(innerData.toString(), LandFirstParamVo.class);
+                    //这里保存附件信息
+                    if(Objects.nonNull(body) && Objects.nonNull(body.getAttachment()) && !body.getAttachment().isEmpty()){
+                        this.getThirdAttachmentToLocal(ywbh,body.getAttachment());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("调用不动产获取附件信息错误,业务号:{}: ", ywbh);
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+            if(++i>=2)break;
+        }//end for
+        return null;
+    }
+
+
+    /**
+     * 下载相关的不动产材料附件
+     * @param dataMap
+     * @return
+     */
+    public String excelImmobileDownFile_LND(Map<String, List<Map<String, String>>> dataMap) {
+        List<Map<String, String>> immobileList = dataMap.get("不动产权信息列表");
+        int i=0;
+        for (Map<String, String> batch : immobileList) {
+            String ywbh = batch.get("业务号");
+            String bdcdyh = batch.get("不动产单元号");
+            //ywbh = "BL202603195001";
+
+            Map<String, Object> retMap = new HashMap<>();
+            //todo 这里进行远程请求,获取相关数据,解析后入库
+            try {
+                Map<String,Object> paramMap = new LinkedHashMap<>();
+                ywbh+="01";
+                paramMap.put("ywbh",ywbh);
+                paramMap.put("yfbdcdyh","");
+
+                if(Constant.BDCDYH_LIST.contains(bdcdyh)){
+                    log.info("已经处理过了,pass了");
+                    continue;
+                }
+
+                String remoteResult = ServiceUtil.getRemoteDataByHttpClient("query.landRegist.datas",paramMap);
+                JSONObject root = JSON.parseObject(remoteResult);
+                log.info("远程调用返回结果: {}", root);
+
+                JSONObject innerDataCheck = root.getJSONObject("data");
+                if(!innerDataCheck.get("code").equals("200")){
+                    log.warn("接口请求返回: {},ywh:{}", innerDataCheck,ywbh);
+                    continue;
+                }
+
+                //todo 这里需要确认用户返回的是数组还是对象
+                JSONObject innerData = (JSONObject) root.getJSONObject("data").getJSONArray("data").get(0);
+                LandFirstParamVo body = JSON.parseObject(innerData.toString(), LandFirstParamVo.class);
+                String prettyJson = JSON.toJSONString(innerData, JSONWriter.Feature.PrettyFormat);
+                //这里记录日志
+                writeToLog(bdcdyh+".txt",prettyJson);
+                retMap.put("body",body);
+            } catch (Exception e) {
+                log.error("调用矢量保存文件错误,业务编号:{}: ", ywbh);
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+
+            //第二部分获取附件数据
+            try {
+                if(MapUtils.isNotEmpty(retMap)){
+                    Map<String,Object> paramMap = new LinkedHashMap<>();
+                    paramMap.put("ywbh",ywbh);
+                    String remoteResult = ServiceUtil.getRemoteDataByHttpClient("query.ywFiles.datas",paramMap);
+                    JSONObject root = JSON.parseObject(remoteResult);
+                    JSONObject innerData = root.getJSONObject("data").getJSONObject("data");
+                    LandFirstParamVo body = JSON.parseObject(innerData.toString(), LandFirstParamVo.class);
+                    //这里保存附件信息
+                    if(Objects.nonNull(body) && Objects.nonNull(body.getAttachment()) && !body.getAttachment().isEmpty()){
+                        this.getThirdAttachmentToLocal(bdcdyh,body.getAttachment());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("调用不动产获取附件信息错误,业务号:{}: ", ywbh);
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+            //if(++i>=3)break;
+        }//end for
+        return null;
+    }
+
+
+
+
+
+
+
+
+
+    public String getThirdAttachmentToLocal(String nodeName,List<Map<String, Object>> attachmentList) {
+        String fileDownLoadPath = "";
+        try {
+            //这里增加一个方法,把文件下载下来
+            String unsafeChars = "[<>:\"/\\\\|?*]";
+            if (CollectionUtils.isNotEmpty(attachmentList)) {
+                String[] subDirectoryNameArr = attachmentList.stream().map(s->s.get("dir_name").toString()).distinct().toArray(String[]::new);
+                String[] subDirectoryNameNew = Arrays.stream(subDirectoryNameArr)
+                        .map(name -> name.replaceAll(unsafeChars, "_")).toArray(String[]::new);
+                //重新创建子目录
+                fileDownLoadPath = createMultipartDirectory(nodeName,subDirectoryNameNew);
+                for (Map<String, Object> attachment : attachmentList) {
+                    String url = Optional.ofNullable(attachment.getOrDefault("path", attachment.get("PATH")))
+                            .map(String::valueOf)
+                            .orElse("");
+
+                    if(org.apache.commons.lang3.StringUtils.isBlank(url)){ //这里避免空值造成数据无法传输
+                        continue;
+                    }
+                    //todo 这里需要进行url替换转
+                    String baseUrl = ServiceUtil.THIRD_API_DOMAIN+"/estate";
+                    String otherDomian = "http://172.16.6.23";
+                    url = org.apache.commons.lang3.StringUtils.replace(url,otherDomian,baseUrl);
+                    //子目录路径
+                    String directoryName = Optional.ofNullable(attachment.getOrDefault("dir_name", attachment.get("DIR_NAME")))
+                            .map(String::valueOf)
+                            .orElse("");
+                    //去掉特殊字符
+                    directoryName = directoryName.replaceAll(unsafeChars,"_");
+                    String fileName = Optional.ofNullable(attachment.getOrDefault("file_name", attachment.get("FILE_NAME")))
+                            .map(String::valueOf)
+                            .orElse("");
+
+                    String subDownLoadFilePath = fileDownLoadPath + "/" + directoryName;
+
+                    //todo 这里不需要try catch 如果下载不了,不进行入库,可以便于查找问题
+                    try {
+                        ServiceFileUtil.downloadFile(url,fileName, subDownLoadFilePath,Constant.BDC);
+                    }catch (IOException e){
+                        System.out.println("处理文件异常1" + e);
+                    }
+                }
+            }
+            return "";
+        } catch (Exception e) {
+            System.out.println("处理文件异常2" + e);
+        }
+
+        return "";
+    }
+
+
+    public static String createMultipartDirectory(String directoryName, String[] subDirectoryName) {
+        String directoryPath = bdcFileDownPath;
+        String directoryPathAndName = ServiceFileUtil.createDirectory(directoryPath, directoryName);
+        Arrays.stream(subDirectoryName).forEach(name -> {
+            ServiceFileUtil.createDirectory(directoryPathAndName, name);
+        });
+        return directoryPath + "/" + directoryName;
+    }
+
+
+
+
+
     /**
      * 报批数据导入
      *
@@ -1098,7 +1307,7 @@ public class DealExcelServiceImpl {
      */
     public static String writeToLog(String fileName, String msg) {
         // 转换为节点
-        String filePath = Constant.IMPORT_EXCEL_DATA_FILE_PATH + "\\log\\" + fileName;
+        String filePath = Constant.BDC_FILE_DOWN_PATH + "\\log\\" + fileName;
         //todo 完善当前方法,功能:1.将msg写入到filePath指定的文件中;2.如果文件不存在则创建;3.每次写入都追加到文件末尾;4.写入完成后返回写入结果(成功/失败)
         // 文件就是一个文本文件,每次写入一行日志,格式为:时间戳 + msg
         try {
@@ -1109,8 +1318,8 @@ public class DealExcelServiceImpl {
             }
             // 时间戳 + msg
             String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
-            String logEntry = timestamp + " " + msg + System.lineSeparator();
-
+            //String logEntry = timestamp + " " + msg + System.lineSeparator();
+            String logEntry = msg;
             // 追加写入
             FileUtils.writeStringToFile(file, logEntry, StandardCharsets.UTF_8, true);
             return "成功";

+ 1 - 1
siwei-modules/siwei-apply/src/main/java/com/siwei/apply/service/third/impl/TakeDataServiceImpl.java

@@ -388,7 +388,7 @@ public class TakeDataServiceImpl implements TakeDataService {
 //                gyjsydjfwscdjUpdateVo.setGzdgzsj(djDate);//告知单时间
 //            }
             gyjsydjfwscdjUpdateVo.setGzdgzsj(body.getGzdgzsj());//告知单时间
-            gyjsydjfwscdjUpdateVo.setKfdw(body.getKfdw());
+            gyjsydjfwscdjUpdateVo.setKfdw(body.getKfdw());// 这里开发单位用权利人
             gyjsydjfwscdjUpdateVo.setBdcqk(body.getBdcqk()); //不动产情况
             gyjsydjfwscdjUpdateVo.setJzmj(body.getJzmj()); //建筑面积
             gyjsydjfwscdjUpdateVo.setJzmjDw(body.getJzmjDw());//建筑面积单位

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

@@ -56,7 +56,7 @@
         SELECT
         MIN ( ywh ) AS ywh,
         MIN ( gzdgzsj ) AS gzdgzsj,
-        MIN ( kfdw ) AS kfdw,
+        MIN ( qlrmc ) AS kfdw,
         MIN ( bdcqk ) AS bdcqk,
         MIN ( mjdw ) AS mjdw,
         SUM ( jzmj :: NUMERIC ) AS jzmj,

+ 42 - 2
siwei-modules/siwei-apply/src/main/resources/mapper/GjShijiShouchuMapper.xml

@@ -139,7 +139,7 @@
     <select id="getStatsByYear" resultType="map">
         SELECT
             COALESCE(scnd, '其它') AS year,
-            ROUND(COALESCE(SUM(CAST(scmj AS NUMERIC)), 0), 2) AS in_data_area
+            ROUND(COALESCE(SUM(CAST(mj_m AS NUMERIC)), 0), 2) AS in_data_area
         FROM vector.gj_shouchu_xiangmu_shiji
         GROUP BY scnd
         ORDER BY year
@@ -171,7 +171,7 @@
             xmmc AS xmmc,
             yqsdw AS company,
             CAST(gid AS VARCHAR) AS nodeId,
-            COALESCE(ghyt, '其它') AS tdyt,
+            COALESCE(NULLIF(ghyt, ''), '其它') AS tdyt,
             scfs AS gyfs,
             to_timestamp(scsj, 'YYYY/MM/DD') AS gysj,
             ROUND(CAST(mj_m AS NUMERIC), 2) AS mjMu,
@@ -226,4 +226,44 @@
         LIMIT 1
     </select>
 
+
+
+    <select id="queryDifferenceGeomAreaByYearOfShouchu" resultType="map">
+        WITH  geom_gy_data AS (
+            SELECT   nf, "public".ST_Union(geom) AS union_geom  from (
+                 SELECT  COALESCE(left(hbcrht_date,4), '其它') AS nf, geom
+                 FROM t_geom_db_details gd
+                          INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+                          INNER JOIN t_tdgy gy ON nl.node_id = gy.id
+                          INNER JOIN t_project pro ON gy.project_id = pro.id
+                 WHERE gy.has_onchain = 't'
+                   AND pro.project_type = 2
+                 UNION
+                 SELECT COALESCE(left(nf,4), '其它') AS nf , geom from vector.gj_gd_data
+             )	tmp    GROUP BY nf  ORDER BY nf
+        ),
+          geom_shouchu_data AS (
+              SELECT COALESCE(scnd, '其它') AS 		nf,
+                     count(DISTINCT gid) AS patch_count,
+                     public.ST_Union(geom)  AS union_geom,
+                     ROUND(COALESCE(SUM(CAST(mj_m AS NUMERIC)), 0), 2) AS area
+              FROM vector.gj_shouchu_xiangmu_shiji  GROUP BY scnd
+
+          )
+        SELECT
+            sc.nf,
+            sc.patch_count,
+            ST_AsEWKT( ST_Difference(sc.union_geom, COALESCE(gy.union_geom, ST_GeomFromText('POLYGON EMPTY',4326)))) AS rest_geom,
+            COALESCE (ST_Area( ST_Difference(sc.union_geom, COALESCE(gy.union_geom, ST_GeomFromText('POLYGON EMPTY',4326)))::geography ),0) / 666.6666667 AS rest_area
+        FROM geom_shouchu_data sc
+        LEFT JOIN  geom_gy_data gy   ON sc.nf = gy.nf
+        WHERE
+            NOT ST_IsEmpty( ST_Difference(sc.union_geom,COALESCE(gy.union_geom, ST_GeomFromText('POLYGON EMPTY',4326)) ) )
+        <if test="year != null and year != ''">
+            AND  sc.nf = #{year}
+        </if>
+    </select>
+
+
+
 </mapper>

+ 6 - 1
siwei-modules/siwei-apply/src/main/resources/mapper/GjShouchuJihuaMapper.xml

@@ -14,6 +14,7 @@
         <if test="year != null and year != '' and year != '0'">
             AND scnf = #{year}
         </if>
+        AND source_type='0'
     </select>
 
     <select id="getPlanStatsByLandUse" resultType="map">
@@ -25,6 +26,7 @@
         <if test="year != null and year != '' and year != '0'">
             AND scnf = #{year}
         </if>
+        AND source_type='0'
         GROUP BY COALESCE(ghyt, '其他')
         ORDER BY plan_area DESC
     </select>
@@ -38,6 +40,7 @@
         <if test="year != null and year != '' and year != '0'">
             AND scnf = #{year}
         </if>
+        AND source_type='0'
         GROUP BY COALESCE(scfs, '其他')
         ORDER BY plan_area DESC
     </select>
@@ -50,7 +53,7 @@
             mj_12 AS mjPfm,
             ROUND(COALESCE(mj_m, 0), 2) AS mjMu,
             COALESCE(xmmc, htmc, dzjgh, CONCAT('收储计划-', gid)) AS xmmc,
-            ghyt AS tdyt,
+            COALESCE(NULLIF(ghyt, ''), '其它') AS tdyt,
             scfs AS gyfs,
             COALESCE(qdrq, TO_DATE(scnf || '-01-01', 'YYYY-MM-DD')) AS gysj,
             sccb AS cost,
@@ -72,6 +75,7 @@
         <if test="(startYear != null and startYear != '') and (endYear != null and endYear != '')">
             AND scnf::NUMERIC BETWEEN #{startYear}::NUMERIC AND #{endYear}::NUMERIC
         </if>
+        AND source_type='0'
         ORDER BY gid
     </select>
 
@@ -108,6 +112,7 @@
             ST_AsEWKT(geom) AS geom
         FROM vector.gj_shouchu_xiangmu
         WHERE gid::varchar = #{gid}
+        AND source_type='0'
         LIMIT 1
     </select>
 

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

@@ -54,7 +54,7 @@
                 AND ngysj &lt;= #{endDate}
             </if>
             <if test="year != null and year != ''">
-                AND  TO_CHAR(ngysj, 'YYYY') = #{year}
+                AND  nf = #{year}
             </if>
         </where>
         ORDER BY gid DESC

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

@@ -29,7 +29,7 @@
     </resultMap>
 
     <select id="isExit" resultType="Boolean">
-        SELECT COUNT(1) > 0
+        SELECT COUNT(1) > 3
         FROM t_jsydghxk
         WHERE project_id = #{projectId}
     </select>

+ 17 - 0
siwei-modules/siwei-apply/src/main/resources/mapper/NodeLandMapper.xml

@@ -137,6 +137,23 @@
                 limit 1
     </select>
 
+    <select id="selectGeomIntersectsNode" parameterType="String" resultType="map">
+        SELECT  DISTINCT ON (node.node_id)
+            geom.id , node.node_id   FROM  "t_geom_db_details"  geom
+            LEFT JOIN "public"."t_geom_db"  upload   on geom.upload_id=upload.id
+            LEFT JOIN "public"."t_node_land" node    on  node.geom_db_id=upload.id
+            LEFT JOIN  "public"."t_ydbp_data" ydbp   on  node.node_id=ydbp.id
+        where ydbp.has_onchain=true
+          AND  public.ST_Intersects(geom.geom, (SELECT geom FROM "t_geom_db_details" WHERE  id = #{detailsId}) )
+        order by node.node_id,  ydbp.created_at desc
+    </select>
+
+
+
+
+
+
+
 
     <!--  根据nodeId,查询出当前具体的图斑ID -->
     <select id="selectGeomDetailsByGeomDbId" parameterType="String" resultType="java.util.Map">

+ 13 - 0
siwei-modules/siwei-apply/src/main/resources/mapper/ProjectWorkflowMapper.xml

@@ -240,5 +240,18 @@
         WHERE id =   #{id}
     </delete>
 
+    <delete id="deleteByProjectId">
+        DELETE FROM t_project_workflow
+        <where>
+            project_id = #{projectId}
+            <if test="projectId != null and projectId != ''">
+                AND project_id = #{projectId}
+            </if>
+            <if test="nodeTableName != null and nodeTableName != ''">
+                AND node_table_name = #{nodeTableName}
+            </if>
+        </where>
+    </delete>
+
 
 </mapper>

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

@@ -22,6 +22,7 @@
         <result property="createdAt" column="created_at"/>
         <result property="updatedAt" column="updated_at"/>
         <result property="gdUnit" column="gd_unit"/>
+        <result property="nf" column="nf"/>
     </resultMap>
 
     <select id="isExit" resultType="Boolean">
@@ -177,7 +178,7 @@
         xmmc AS xmmc,
         srr AS company,
         gid AS nodeId,
-        COALESCE ( land.code, '23' ) AS tdyt,
+        COALESCE(NULLIF(land.code, ''), '23') AS tdyt,
         gyfs,
         qdrq AS gysj,
         ROUND(COALESCE ( gymj, 0 ) / 666.6666667,2)     AS mjMu,-- 平方米 -> 亩
@@ -185,6 +186,7 @@
         '' AS uploadId,
         '' AS geomJson,
         0 AS sort,
+        COALESCE(left(nf,4), '其它') AS nf,
         shape_area AS geomArea,
         ST_AsEWKT ( geom ) AS geom
         FROM
@@ -267,4 +269,48 @@
         LIMIT 1
     </select>
 
+    <select id="getTdgyList" resultMap="BaseResultMap">
+        SELECT
+            gd.id AS id,
+            pro.ID AS project_id,
+            pro.name AS project_name,
+            '1' AS batch_type,
+            gd.hbcrht_date,
+            gd.srf,
+            gd.gd_type,
+            gd.hbcrht_date,
+            gd.has_zz,
+            gd.hbcrfapfwh,
+            gd.hbcrht_date,
+            COALESCE(NULLIF(gd.tdyt, ''), '23') AS tdyt,
+            COALESCE (
+                    CASE
+                        WHEN gd.gd_unit = '平方米' THEN
+                            COALESCE ( gd.gd_area, 0 ) / 666.6666667
+                        WHEN gd.gd_unit = '公顷' THEN
+                            COALESCE ( gd.gd_area, 0 ) * 15
+                        WHEN gd.gd_unit = '亩' THEN
+                            COALESCE ( gd.gd_area, 0 ) * 1
+                        END,
+                    0
+            ) AS gd_area,
+            COALESCE(left(gd.hbcrht_date,4), '其它') AS nf,
+            '亩' as gd_unit
+        FROM
+            t_tdgy gd
+                LEFT JOIN t_project pro ON gd.project_id = pro."id"
+        WHERE
+            pro.on_chain_num > 0
+          AND gd.has_onchain = 't'
+        <if test="(startYear != null and startYear != null) and (endYear != '' and endYear != '')">
+            AND left(gd.hbcrht_date,4)::NUMERIC BETWEEN #{startYear}::NUMERIC AND #{endYear}::NUMERIC
+        </if>
+    </select>
+
+
+
+
+
+
+
 </mapper>

+ 166 - 15
siwei-modules/siwei-apply/src/main/resources/mapper/YdbpDataMapper.xml

@@ -18,6 +18,8 @@
         <result property="creatorId" column="creator_id"/>
         <result property="createdAt" column="created_at"/>
         <result property="updatedAt" column="updated_at"/>
+        <result property="batchType" column="batch_type"/>
+        <result property="projectPropertyId" column="project_property_id"/>
     </resultMap>
     <insert id="add" parameterType="com.siwei.apply.domain.YdbpData">
         INSERT INTO t_ydbp_data (
@@ -111,31 +113,180 @@
     </update>
 
     <select id="getStatisticsList" resultMap="YdbpDataResultMap">
-        select
-        COALESCE (
-            CASE
-            WHEN zs_unit = '平方米' THEN
-            COALESCE ( zs_area, 0 ) / 666.6666667
-            WHEN zs_unit = '公顷' THEN
-            COALESCE ( zs_area, 0 ) * 15
-            WHEN zs_unit = '亩' THEN
-            COALESCE ( zs_area, 0 ) * 1
-            END,
-            0
-        ) AS zs_area ,
+        SELECT
+            id, name,  yd_unit,
+            '2' AS batch_type,
+                COALESCE (
+                    CASE
+                    WHEN yd_unit = '平方米' THEN
+                    COALESCE ( yd_area, 0 ) / 666.6666667
+                    WHEN yd_unit = '公顷' THEN
+                    COALESCE ( yd_area, 0 ) * 15
+                    WHEN yd_unit = '亩' THEN
+                    COALESCE ( yd_area, 0 ) * 1
+                    END,
+                    0
+                ) AS yd_area ,
+                COALESCE (
+                        CASE
+                        WHEN zs_unit = '平方米' THEN
+                        COALESCE ( zs_area, 0 ) / 666.6666667
+                        WHEN zs_unit = '公顷' THEN
+                        COALESCE ( zs_area, 0 ) * 15
+                        WHEN zs_unit = '亩' THEN
+                        COALESCE ( zs_area, 0 ) * 1
+                        END,
+                        0
+                ) AS zs_area,
+
+        <if test="hasGeom != null and hasGeom">
+            COALESCE((
+            SELECT ST_AsEWKT(ST_Union(gd.geom))
+            FROM t_node_land nl
+            LEFT JOIN t_geom_db_details gd ON nl.geom_db_id = gd.upload_id
+            WHERE nl.node_id = bp.id AND gd.geom IS NOT NULL
+            ), '') AS geom,
+        </if>
+        -- left(pf_date,4) AS nf,
         '亩' as  zs_unit,
         has_zz, bp_date, pfwh, pf_date, creator_id, created_at, updated_at,has_onchain
-        FROM t_ydbp_data
-        WHERE has_onchain='t'
+        FROM t_ydbp_data bp
+        WHERE bp.has_onchain='t'
         <if test="year != null and year != '' ">
-            AND left(pf_date,4) = #{year}
+            AND left(bp.pf_date,4) = #{year}
+        </if>
+        <if test="(startYear != null and startYear != null) and (endYear != '' and endYear != '')">
+            AND left(bp.pf_date,4)::NUMERIC BETWEEN #{startYear}::NUMERIC AND #{endYear}::NUMERIC
+        </if>
+
+        <if test="keyWord != null and keyWord != ''">
+            AND (
+                COALESCE(bp.name, '') LIKE CONCAT('%', #{keyWord}, '%')
+            )
         </if>
     </select>
 
 
+    <sql id="commonYdbpDataCte" >
+        WITH
+            supply_geom AS (
+                SELECT DISTINCT
+                    ST_Normalize(gd.geom) AS norm_geom
+                FROM t_geom_db_details gd
+                         INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+                         INNER JOIN t_tdgy gy ON nl.node_id = gy.id
+                         INNER JOIN t_project pro ON gy.project_id = pro.id
+                WHERE gy.has_onchain = 't'
+                  AND pro.project_type = 2
+            ),
+            hit_geom_id AS (
+                SELECT DISTINCT gd.id as details_id
+                FROM t_geom_db_details gd
+                         INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+                         INNER JOIN t_ydbp_data bp ON nl.node_id = bp.id
+                WHERE bp.has_onchain = 't'
+                  AND EXISTS (
+                    SELECT 1 FROM supply_geom
+                    WHERE ST_Equals(ST_Normalize(gd.geom), supply_geom.norm_geom)
+                )
+            )
+    </sql>
+
+
 
 
+    <!--
+    方案:已批未供的图层相关:
+    1.把土地供应的所有的地块。并且已经上链的的查找出来。
+    2.把这些地块与报批中所有地块等值判断进行筛选。
+    3.再查找所有的报批的地块,减去上面找出的地块。然后按照年份统计其面积。
+    -->
+    <select id="queryRemainGeomAreaByYear" resultType="java.util.Map">
+        <include refid="commonYdbpDataCte"></include>
+        SELECT
+            LEFT(bp.pf_date, '4') AS stat_year,
+            COUNT(DISTINCT gd.id) AS patch_count,
+            '亩' as  area_unit,
+            SUM( COALESCE(ST_Area(gd.geom::public.geography), 0) / 666.6666667 ) AS total_area_mu
+        FROM t_geom_db_details gd
+            INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+            INNER JOIN t_ydbp_data bp ON nl.node_id = bp.id
+        WHERE bp.has_onchain = 't'
+          AND NOT EXISTS (
+            SELECT 1 FROM hit_geom_id h WHERE h.details_id = gd.id
+            )
+        GROUP BY stat_year
+        ORDER BY stat_year
+    </select>
 
+    <select id="queryDifferenceGeomAreaByYear" resultType="java.util.Map">
+        WITH  geom_gy_data AS (
+            SELECT   nf, "public".ST_Union(geom) AS union_geom  from (
+                SELECT  COALESCE(left(hbcrht_date,4), '其它') AS nf, geom
+                FROM t_geom_db_details gd
+                INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+                INNER JOIN t_tdgy gy ON nl.node_id = gy.id
+                INNER JOIN t_project pro ON gy.project_id = pro.id
+                WHERE gy.has_onchain = 't'
+                AND pro.project_type = 2
+                UNION
+                SELECT COALESCE(left(nf,4), '其它') AS nf , geom from vector.gj_gd_data
+            )	tmp  GROUP BY nf
+        ),
+        geom_ydbp_data AS (
+            SELECT COALESCE(left(pf_date,4), '其它') AS nf ,  "public".ST_Union(geom)  AS union_geom, count(DISTINCT bp.id ) as patch_count
+            FROM t_geom_db_details gd
+            INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+            INNER JOIN  "public"."t_ydbp_data" bp  ON nl.node_id = bp.id
+            WHERE bp.has_onchain = 't'  GROUP BY nf
+        ),
+        diff_result AS (
+            SELECT
+            bp.nf,
+            bp.patch_count,
+            ST_Difference(bp.union_geom, COALESCE(gy.union_geom, ST_GeomFromText('POLYGON EMPTY',4326))) AS diff_geom
+            FROM geom_ydbp_data bp
+            LEFT JOIN  geom_gy_data gy ON bp.nf = gy.nf
+            <if test="year != null and year != ''">
+                WHERE bp.nf = #{year}
+            </if>
+        )
+        SELECT
+            nf,
+            patch_count,
+            ''  AS details_id,
+            '' AS project_id,
+            '' AS node_id,
+            ''  AS  id,
+            '2' AS batch_type,
+            ST_AsEWKT(diff_geom::geography ) AS geom,
+            COALESCE (ST_Area(diff_geom::geography ),0) / 666.6666667 AS rest_area
+            FROM diff_result
+            WHERE NOT ST_IsEmpty(diff_geom)
+            order by nf
+    </select>
+
+    <select id="queryRemainGeomListByYear" resultType="java.util.Map">
+        <include refid="commonYdbpDataCte"></include>
+        SELECT
+        gd.id as details_id,
+        LEFT(bp.pf_date, '4') AS year,
+        '2' AS batch_type,
+        bp.id  as  node_id,
+        bp.id  as  id,
+        '' as project_id,
+        public.st_asewkt(geom) geom
+        FROM t_geom_db_details gd
+            INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+            INNER JOIN t_ydbp_data bp ON nl.node_id = bp.id
+        WHERE bp.has_onchain = 't'
+        <if test="year != null and year != ''">
+            AND LEFT(bp.pf_date, '4')=#{year}
+        </if>
+          AND NOT EXISTS (
+            SELECT 1 FROM hit_geom_id h WHERE h.details_id = gd.id
+            )
+    </select>
 
 
 </mapper>

+ 112 - 3
siwei-modules/siwei-apply/src/main/resources/mapper/YdbpMapper.xml

@@ -50,10 +50,35 @@
 
     <select id="getStatisticsList" resultType="map">
         SELECT
+            bp.id AS id,
             pro.ID AS project_id,
-            bp.ID AS node_id,
-            bp.zs_area,
-            bp.zs_unit,
+            pro.name AS project_name,
+            '1' AS batch_type,
+            COALESCE (
+                CASE
+                WHEN bp.yd_unit = '平方米' THEN
+                COALESCE ( bp.yd_area, 0 ) / 666.6666667
+                WHEN bp.yd_unit = '公顷' THEN
+                COALESCE ( bp.yd_area, 0 ) * 15
+                WHEN bp.yd_unit = '亩' THEN
+                COALESCE ( bp.yd_area, 0 ) * 1
+                END,
+                0
+            ) AS yd_area, -- 用地面积(亩)
+            bp.bp_date,
+            bp.pfwh,
+            bp.pf_date,
+            left(bp.pf_date,4) AS nf,
+            '亩' as yd_unit,
+            '亩' as zs_unit,
+            <if test="hasGeom != null and hasGeom">
+                COALESCE((
+                SELECT ST_AsEWKT(ST_Union(gd.geom))
+                FROM t_node_land nl
+                LEFT JOIN t_geom_db_details gd ON nl.geom_db_id = gd.upload_id
+                WHERE nl.node_id = bp.id AND gd.geom IS NOT NULL
+                ), '') AS geom,
+            </if>
             COALESCE (
                     CASE
                         WHEN bp.zs_unit = '平方米' THEN
@@ -74,9 +99,88 @@
         <if test="year != null and year != '' ">
             AND left(bp.pf_date,4) = #{year}
         </if>
+
+        <if test="(startYear != null and startYear != null) and (endYear != '' and endYear != '')">
+            AND left(bp.pf_date,4)::NUMERIC BETWEEN #{startYear}::NUMERIC AND #{endYear}::NUMERIC
+        </if>
+        <if test="keyWord != null and keyWord != ''">
+            AND (
+            COALESCE(pro.name, '') LIKE CONCAT('%', #{keyWord}, '%')
+            OR COALESCE(pro.company, '') LIKE CONCAT('%', #{keyWord}, '%')
+            )
+        </if>
+
+    </select>
+
+
+    <sql id="commonYdbpCte">
+        WITH
+            supply_geom AS (
+                SELECT DISTINCT
+                    ST_Normalize(gd.geom) AS norm_geom
+                FROM t_geom_db_details gd
+                         INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+                         INNER JOIN t_tdgy gy ON nl.node_id = gy.id
+                         INNER JOIN t_project pro ON gy.project_id = pro.id
+                WHERE gy.has_onchain = 't'
+                  AND pro.project_type = 1
+            ),
+
+            hit_geom_id AS (
+                SELECT DISTINCT gd.id as details_id
+                FROM t_geom_db_details gd
+                         INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+                         INNER JOIN t_ydbp bp ON nl.node_id = bp.id
+                WHERE bp.has_onchain = 't'
+                  AND EXISTS (
+                    SELECT 1 FROM supply_geom
+                    WHERE ST_Equals(ST_Normalize(gd.geom), supply_geom.norm_geom)
+                )
+            )
+    </sql>
+
+
+
+    <select id="queryRemainGeomAreaByYearOfYdbp"   resultType="java.util.Map">
+        <include refid="commonYdbpCte"></include>
+        SELECT
+            LEFT(bp.pf_date, '4') AS stat_year,
+            COUNT(DISTINCT gd.id) AS patch_count,
+            SUM( COALESCE(ST_Area(gd.geom), 0) / 666.6666667 ) AS total_area_mu
+        FROM t_geom_db_details gd
+            INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+            INNER JOIN t_ydbp  bp ON nl.node_id = bp.id
+        WHERE bp.has_onchain = 't'
+          AND NOT EXISTS (
+            SELECT 1 FROM hit_geom_id h WHERE h.details_id = gd.id
+            )
+        GROUP BY stat_year
+        ORDER BY stat_year
     </select>
 
 
+    <select id="queryRemainGeomListByYearOfYdbp"   resultType="java.util.Map">
+        <include refid="commonYdbpCte"></include>
+        SELECT
+        gd.id as details_id,
+        '' as project_id,
+        COALESCE(LEFT(bp.pf_date, '4'),'其它') AS year,
+        bp.id  as  node_id,
+        bp.id  as  id,
+        '1' AS batch_type,
+        public.st_asewkt(geom) geom
+        FROM t_geom_db_details gd
+        INNER JOIN t_node_land nl ON gd.upload_id = nl.geom_db_id
+        INNER JOIN t_ydbp  bp ON nl.node_id = bp.id
+        WHERE bp.has_onchain = 't'
+        <if test="year != null and year != ''">
+            AND LEFT(bp.pf_date, '4')=#{year}
+        </if>
+        AND NOT EXISTS (
+        SELECT 1 FROM hit_geom_id h WHERE h.details_id = gd.id
+        )
+    </select>
+
 
 
 
@@ -104,4 +208,9 @@
         SET has_onchain = #{hasOnchain}, updated_at = now()
         WHERE id = #{id}
     </update>
+
+
+
+
+
 </mapper>

+ 10 - 2
siwei-modules/siwei-apply/src/main/resources/mapper/cadastre/ZdjbxxMapper.xml

@@ -96,6 +96,7 @@
         SELECT *
         FROM vector.zdjbxx
         WHERE bsm = #{bsm}
+          AND valid_flag = 0 AND zt IN ('1', '2')
     </select>
 
     <select id="getListByDjzqdm" resultMap="BaseResultMap">
@@ -109,9 +110,13 @@
             ST_AsEWKT(geom) as geom, valid_flag
         FROM vector.zdjbxx
         <where>
+            valid_flag = 0  and  zt in('1','2')
             <if test="djzqdm != null and djzqdm != ''">
                 and LEFT(zddm, 12) = #{djzqdm}
             </if>
+            <if test="qllx != null and qllx != ''">
+                and sm = #{qllx}
+            </if>
         </where>
     </select>
 
@@ -119,6 +124,7 @@
         SELECT zddm
         FROM vector.zdjbxx
         <where>
+            valid_flag = 0 AND zt IN ('1', '2')
             <if test="qllxIds != null and qllxIds != ''">
                 AND qllx  in(#{qllxIds})
             </if>
@@ -129,6 +135,7 @@
     <select id="getList" resultMap="BaseResultMap">
         SELECT *
         FROM vector.zdjbxx
+        WHERE valid_flag = 0 AND zt IN ('1', '2')
     </select>
 
     <update id="update" parameterType="com.siwei.apply.domain.cadastre.Zdjbxx">
@@ -262,6 +269,7 @@
             ) AS area_mu
         FROM vector.zdjbxx
         WHERE qllx IS NOT NULL
+          AND valid_flag = 0 AND zt IN ('1', '2')
         GROUP BY COALESCE(NULLIF(TRIM(qllx), ''), '其他'), djzt
         ORDER BY COALESCE(NULLIF(TRIM(qllx), ''), '其他')
     </select>
@@ -294,7 +302,7 @@
             ON LEFT(zd.zddm, 12) = dq.djzqdm
         WHERE zd.qllx IS NOT NULL
           AND zd.zdmj IS NOT NULL
-          AND (zd.valid_flag IS NULL OR zd.valid_flag = 0)
+          AND zd.valid_flag = 0 AND zd.zt IN ('1', '2')
           AND (dq.valid_flag IS NULL OR dq.valid_flag = 0)
         <if test="qllxCodes != null and qllxCodes.size() > 0">
             AND zd.qllx IN
@@ -331,7 +339,7 @@
         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 zd.valid_flag = 0 AND zd.zt IN ('1', '2')
           AND LENGTH(TRIM(zd.yt)) >= 2
         GROUP BY LEFT(zd.yt, 2), zd.qlxz
         ORDER BY LEFT(zd.yt, 2), zd.qlxz

+ 5 - 0
siwei-modules/siwei-apply/src/main/resources/mapper/cadastre/ZrzMapper.xml

@@ -94,6 +94,7 @@
         SELECT *, ST_AsEWKT(geom) as geom
         FROM vector.zrz
         WHERE bsm = #{bsm}
+          AND valid_flag = 0 AND zt IN ('1', '2')
     </select>
 
     <select id="getListByDjzqdm" resultMap="BaseResultMap">
@@ -106,6 +107,7 @@
         shyj, shy, shrq, fwdcb, fcct, bdcdyb, dcdw,ST_AsEWKT(geom) as geom
         FROM vector.zrz
         <where>
+            valid_flag = 0  and  zt in('1','2')
             <if test="djzqdm != null and djzqdm != ''">
                 and LEFT(zddm, 12) = #{djzqdm}
             </if>
@@ -115,6 +117,7 @@
     <select id="getList" resultMap="BaseResultMap">
         SELECT *, ST_AsEWKT(geom) as geom
         FROM vector.zrz
+        WHERE valid_flag = 0 AND zt IN ('1', '2')
     </select>
 
     <update id="update" parameterType="com.siwei.apply.domain.cadastre.Zrz">
@@ -194,6 +197,7 @@
             COUNT(*) as count,
             SUM(scjzmj) as total_scjzmj
         FROM vector.zrz
+        WHERE valid_flag = 0 AND zt IN ('1', '2')
         GROUP BY ghyt, ytmc, djzt
     </select>
 
@@ -206,6 +210,7 @@
             SUM(scjzmj) as total_area
         FROM vector.zrz
         <where>
+            valid_flag = 0 AND zt IN ('1', '2')
             <if test="ghytCodes != null and ghytCodes.size() > 0">
                 AND ghyt IN
                 <foreach item="code" collection="ghytCodes" open="(" separator="," close=")">