瀏覽代碼

优化逻辑,统一计算时间

ximinghao 10 月之前
父節點
當前提交
2c2459462a

+ 0 - 21
src/main/java/com/skyversation/xjcy/query/DMSQuery.java

@@ -1,21 +0,0 @@
-package com.skyversation.xjcy.query;
-
-import com.skyversation.xjcy.bean.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@AllArgsConstructor
-@Getter
-public enum DMSQuery {
-
-    INDUSTRIAL_PARK("1580", IndustrialPark.class),
-    ENTERPRISE      ("1593", Enterprise.class),
-    ECONOMIC_ALL_INDEED("1594", EnterpriseEconomic.class),
-    ORDER           ("1587", Order.class),
-    LAST_LEASE_DETAIL("1574", LeaseDetail.class),
-    LAST_YEAR_LEASE_DETAIL("1574", LeaseDetail.class);
-
-    private final String columnId;
-    private final Class<? extends FromJSON> resultType;
-
-}

+ 154 - 116
src/main/java/com/skyversation/xjcy/service/DMSService.java

@@ -3,11 +3,11 @@ package com.skyversation.xjcy.service;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.parser.ParserConfig;
-import com.skyversation.xjcy.bean.FromJSON;
-import com.skyversation.xjcy.query.DMSQuery;
+import com.skyversation.xjcy.bean.*;
 import com.skyversation.xjcy.util.HttpUtil;
 import com.skyversation.xjcy.util.SpecialisationStringCollector;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.LinkedMultiValueMap;
@@ -31,15 +31,130 @@ public class DMSService {
     @Value("${app.oauth.path}")
     private String oauthPath;
 
+    @AllArgsConstructor
+    @Getter
+    public enum DMSQuery {
+
+        INDUSTRIAL_PARK("1580", IndustrialPark.class) {
+            @Override
+            public DMSRequest preRequest(LocalDate now) {
+                return new DMSRequest();
+            }
+        },
+        ENTERPRISE("1593", Enterprise.class) {
+            @Override
+            public DMSRequest preRequest(LocalDate now) {
+                return new DMSRequest();
+            }
+        },
+        ECONOMIC_ALL_INDEED("1594", EnterpriseEconomic.class) {
+            @Override
+            public DMSRequest preRequest(LocalDate now) {
+                DMSRequest request = new DMSRequest();
+                Set<String> monthInDeed = new HashSet<>();
+                monthInDeed.addAll(SpecialisationStringCollector.YearMonthByLast12Month(now));
+                monthInDeed.addAll(SpecialisationStringCollector.YearMonthByYtd(now));
+                monthInDeed.addAll(SpecialisationStringCollector.YearMonthByYtd(1, now));
+                request.addWhere("c_year_month", "5", monthInDeed);
+                return request;
+            }
+        },
+        ORDER("1587", Order.class) {
+            @Override
+            public DMSRequest preRequest(LocalDate now) {
+                return new DMSRequest();
+            }
+        },
+        LAST_LEASE_DETAIL("1574", LeaseDetail.class) {
+            @Override
+            public DMSRequest preRequest(LocalDate now) {
+                DMSRequest request = new DMSRequest();
+                request.addWhere("c_is_latest_lease", "1", "2");
+                return request;
+            }
+        },
+        LAST_YEAR_LEASE_DETAIL("1574", LeaseDetail.class) {
+            @Override
+            public DMSRequest preRequest(LocalDate now) {
+                DMSRequest request = new DMSRequest();
+                LocalDate indeedStartTime = now.minusMonths(13).withDayOfMonth(1); // 2024-06-01
+                LocalDate indeedEndTime = now.minusMonths(1)                     // 上个月
+                        .withDayOfMonth(
+                                now.minusMonths(1)
+                                        .lengthOfMonth());
+
+                LocalDate timeOfFarBefore = LocalDate.of(1970, 1, 1);
+                LocalDate timeOfFarAfter = indeedEndTime.plusYears(100);
+                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+                request.addWhere("c_start_date", "3", timeOfFarBefore.format(formatter), indeedEndTime.format(formatter));
+                request.addWhere("c_end_date", "3", indeedStartTime.format(formatter), timeOfFarAfter.format(formatter));
+                return request;
+            }
+        };
+
+        private final String columnId;
+        private final Class<? extends FromJSON> resultType;
+
+        abstract DMSRequest preRequest(LocalDate now);
+
+    }
+
     private static class DMSRequest {
         DMSRequestType type;
-        Map<String,String> params = new HashMap<>();
+        Map<String, String> params = new HashMap<>();
         String token;
         JSONArray where = new JSONArray();
         JSONArray order = new JSONArray();
+
+        private void addWhere(String field, String type, String content) {
+            this.where.add(summonWhere(field, type, content));
+        }
+
+        private void addWhere(String field, String type, Set<String> content) {
+            this.where.add(summonWhere(field, type, content));
+        }
+
+        private JSONObject summonWhere(String field, String type, Object content) {
+            JSONObject where = new JSONObject();
+            where.put("field", field);
+            where.put("searchType", type);
+            JSONObject contents = new JSONObject();
+            contents.put("value", content);
+            where.put("content", contents);
+            return where;
+        }
+
+        private void addWhere(String field, String type, String start, String end) {
+            JSONObject where = new JSONObject();
+            where.put("field", field);
+            where.put("searchType", type);
+            JSONObject contents = new JSONObject();
+            contents.put("start", start);
+            contents.put("end", end);
+            where.put("content", contents);
+            this.where.add(where);
+        }
+
+        private void addOrder(DMSRequest request) {
+
+        }
+
+        private void setPage(String page, String pageSize) {
+            this.params.put("page", page);
+            this.params.put("pageSize", pageSize);
+        }
+
+        private void setState() {
+            this.params.put("states", "0,1,2,3");
+        }
+
+        private void setColumnId(String columnId) {
+            this.params.put("columnId", columnId);
+        }
     }
+
     private enum DMSRequestType {
-        List,JOIN_LIST
+        List, JOIN_LIST
     }
 
     public String loginForToken() throws Exception {
@@ -63,168 +178,91 @@ public class DMSService {
         return jsonObject.getString("message");
     }
 
-    private JSONObject sendToDms(DMSRequest request,int depth){
+    private JSONObject sendToDms(DMSRequest request, int depth) {
         JSONObject jsonObject;
-        MultiValueMap<String,String> params = new LinkedMultiValueMap<>();
+        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
         request.params.forEach(params::add);
         params.add("search", request.where.toJSONString());
         try {
             String response;
             switch (request.type) {
-                case List:{
-                    response= HttpUtil.requestPost(path+"/content/selectContentListInfo",params,
-                            Collections.singletonMap("token",request.token));
+                case List: {
+                    response = HttpUtil.requestPost(path + "/content/selectContentListInfo", params,
+                            Collections.singletonMap("token", request.token));
                     break;
                 }
-                case JOIN_LIST:{
+                case JOIN_LIST: {
                     response = "";
                     break;
                 }
-                default:{
+                default: {
                     return null;
                 }
             }
-          jsonObject = JSON.parseObject(response);
+            jsonObject = JSON.parseObject(response);
         } catch (RestClientException e) {
-            if (depth<3){
-                return sendToDms(request,depth+1);
+            if (depth < 3) {
+                return sendToDms(request, depth + 1);
             }
             return null;
-        }catch (Exception e){
+        } catch (Exception e) {
             return null;
         }
-        if (Objects.equals(jsonObject.getString("message"), "无效token")&&depth<3){
+        if (Objects.equals(jsonObject.getString("message"), "无效token") && depth < 3) {
             return null;
         }
         return jsonObject;
     }
-    private JSONObject sendToDms(DMSRequest request){
-        return sendToDms(request,0);
-    }
-    private void addWhere(DMSRequest request,String field,String type , String content){
-        JSONObject where = new JSONObject();
-        where.put("field",field);
-        where.put("searchType",type);
-        JSONObject contents = new JSONObject();
-        contents.put("value",content);
-        where.put("content",contents);
-        request.where.add(where);
-    }
-    private void addWhere(DMSRequest request,String field,String type , Set<String> content) {
-        JSONObject where = new JSONObject();
-        where.put("field",field);
-        where.put("searchType",type);
-        JSONObject contents = new JSONObject();
-        contents.put("value",content);
-        where.put("content",contents);
-        request.where.add(where);
-    }
-    private void addWhere(DMSRequest request,String field,String type , String start,String end){
-        JSONObject where = new JSONObject();
-        where.put("field",field);
-        where.put("searchType",type);
-        JSONObject contents = new JSONObject();
-        contents.put("start",start);
-        contents.put("end",end);
-        where.put("content",contents);
-        request.where.add(where);
-    }
-    private void  addOrder(DMSRequest request){
 
+    private JSONObject sendToDms(DMSRequest request) {
+        return sendToDms(request, 0);
     }
-    private void setPage(DMSRequest request,String page,String pageSize){
-        request.params.put("page",page);
-        request.params.put("pageSize",pageSize);
-    }
-    private void setState(DMSRequest request){
-        request.params.put("states","0,1,2,3");
-    }
-    private void setColumnId(DMSRequest request,String columnId){
-        request.params.put("columnId",columnId);
-    }
-    private List<JSONObject> queryDmsList(DMSRequest request,String token,String columnId){
-        request.token=token;
-        request.type=DMSRequestType.List;
-        setColumnId(request,columnId);
-        setState(request);
+
+    private List<JSONObject> queryDmsList(DMSRequest request, String token, String columnId) {
+        request.token = token;
+        request.type = DMSRequestType.List;
+        request.setColumnId(columnId);
+        request.setState();
         int page = 0;
         int pageSize = 2000;
         List<JSONObject> list = new ArrayList<>();
-        int count;
         do {
             try {
-                setPage(request,page+"",pageSize+"");
+                request.setPage(page + "", pageSize + "");
                 JSONObject jsonObject = sendToDms(request);
                 if ("成功".equals(jsonObject.getString("message"))) {
                     JSONArray content = jsonObject.getJSONArray("content");
-                    if (content.isEmpty()){
+                    if (content.isEmpty()) {
                         break;
                     }
                     for (int i = 0; i < content.size(); i++) {
                         list.add(content.getJSONObject(i));
                     }
-                }else {
+                } else {
                     break;
                 }
             } catch (Exception e) {
                 break;
-            }finally {
+            } finally {
                 page++;
             }
-        }while (true);
+        } while (true);
 
         return list;
     }
-    public List<JSONObject> simpleQuery(String token,String columId){
-        return queryDmsList(new DMSRequest(),token,columId);
-    }
-    public List<JSONObject> indeedEconomicQuery(String token, String columId){
-        DMSRequest request = new DMSRequest();
-        Set<String> monthInDeed = new HashSet<>();
-        monthInDeed.addAll(SpecialisationStringCollector.YearMonthByLast12Month());
-        monthInDeed.addAll(SpecialisationStringCollector.YearMonthByYtd());
-        monthInDeed.addAll(SpecialisationStringCollector.YearMonthByYtd(1));
-        addWhere(request,"c_year_month","5", monthInDeed);
-        return queryDmsList(request,token,columId);
-    }
-    public List<JSONObject> indeedLeaseQuery(String token ,String columId){
-        DMSRequest request = new DMSRequest();
-        LocalDate now = LocalDate.now();
-        LocalDate indeedStartTime = now.minusMonths(13).withDayOfMonth(1); // 2024-06-01
-        LocalDate indeedEndTime   = now.minusMonths(1)                     // 上个月
-                .withDayOfMonth(
-                        now.minusMonths(1)
-                                .lengthOfMonth());
-
-        LocalDate timeOfFarBefore = LocalDate.of(1970,1,1);
-        LocalDate timeOfFarAfter = indeedEndTime.plusYears(100);
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        addWhere(request,"c_start_date","3",timeOfFarBefore.format(formatter),indeedEndTime.format(formatter));
-        addWhere(request,"c_end_date","3",indeedStartTime.format(formatter),timeOfFarAfter.format(formatter));
-        return  queryDmsList(request,token,columId);
-    }
-    public List<JSONObject> lastLeaseQuery(String token ,String columId){
-        DMSRequest request = new DMSRequest();
-        addWhere(request,"c_is_latest_lease","1","2");
-        return queryDmsList(request,token,columId);
+
+    public List<JSONObject> simpleQuery(String token, String columId) {
+        return queryDmsList(new DMSRequest(), token, columId);
     }
-    public <T extends FromJSON> List<T> query(String token,DMSQuery query,Class<T> clazz){
-        if(query.getResultType()!=clazz){
+
+    public <T extends FromJSON> List<T> query(String token, DMSQuery query, Class<T> clazz, LocalDate now) {
+        if (query.getResultType() != clazz) {
             throw new RuntimeException("类型与枚举提供的类型不符,请确认枚举中的类型");
         }
-        List<JSONObject> dmsResult;
-        if (query == DMSQuery.ECONOMIC_ALL_INDEED){
-            dmsResult = indeedEconomicQuery(token,query.getColumnId());
-        }else if (query == DMSQuery.LAST_LEASE_DETAIL){
-            dmsResult = lastLeaseQuery(token,query.getColumnId());
-        }else if (query == DMSQuery.LAST_YEAR_LEASE_DETAIL){
-            dmsResult = indeedLeaseQuery(token,query.getColumnId());
-        }else {
-            dmsResult = simpleQuery(token, query.getColumnId());
-        }
-        return dmsResult.stream().map(jsonObject -> JSON.toJavaObject(jsonObject,clazz)).collect(Collectors.toList());
-    }
+        List<JSONObject> dmsResult = queryDmsList(query.preRequest(now), token, query.getColumnId());
 
+        return dmsResult.stream().map(jsonObject -> JSON.toJavaObject(jsonObject, clazz)).collect(Collectors.toList());
+    }
 
 
 }

+ 117 - 75
src/main/java/com/skyversation/xjcy/service/DataCountService.java

@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.skyversation.xjcy.bean.*;
 import com.skyversation.xjcy.enums.EnterpriseLevel;
-import com.skyversation.xjcy.query.DMSQuery;
 import com.skyversation.xjcy.util.SpecialisationStringCollector;
 import com.skyversation.xjcy.util.TimeUtil;
 import lombok.NoArgsConstructor;
@@ -104,14 +103,16 @@ public class DataCountService {
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-        //统一查询所有需要的数据避免处理时间太长token过期,数据量大不了所以不做流式
-        List<IndustrialPark> allIndustrialPark = dmsService.query(token, DMSQuery.INDUSTRIAL_PARK, IndustrialPark.class);
-        List<Enterprise> allEnterprise = dmsService.query(token, DMSQuery.ENTERPRISE, Enterprise.class);
-        List<EnterpriseEconomic> inDateEnterpriseEconomic = dmsService.query(token, DMSQuery.ECONOMIC_ALL_INDEED, EnterpriseEconomic.class);
-        List<Order> allOrder = dmsService.query(token, DMSQuery.ORDER, Order.class);
-        List<LeaseDetail> lastLeaseDetail = dmsService.query(token, DMSQuery.LAST_LEASE_DETAIL, LeaseDetail.class);
-        List<LeaseDetail> lastYearLease = dmsService.query(token, DMSQuery.LAST_YEAR_LEASE_DETAIL, LeaseDetail.class);
 
+        LocalDate now = LocalDate.now();
+
+        //统一查询所有需要的数据避免处理时间太长token过期,数据量大不了所以不做流式
+        List<IndustrialPark> allIndustrialPark = dmsService.query(token, DMSService.DMSQuery.INDUSTRIAL_PARK, IndustrialPark.class, now);
+        List<Enterprise> allEnterprise = dmsService.query(token, DMSService.DMSQuery.ENTERPRISE, Enterprise.class, now);
+        List<EnterpriseEconomic> inDateEnterpriseEconomic = dmsService.query(token, DMSService.DMSQuery.ECONOMIC_ALL_INDEED, EnterpriseEconomic.class, now);
+        List<Order> allOrder = dmsService.query(token, DMSService.DMSQuery.ORDER, Order.class, now);
+        List<LeaseDetail> lastLeaseDetail = dmsService.query(token, DMSService.DMSQuery.LAST_LEASE_DETAIL, LeaseDetail.class, now);
+        List<LeaseDetail> lastYearLease = dmsService.query(token, DMSService.DMSQuery.LAST_YEAR_LEASE_DETAIL, LeaseDetail.class, now);
         //处理一下拿到的数据,建一建索引
         Map<String, List<EnterpriseEconomic>> enterpriseEconomicMap = new HashMap<>();
         inDateEnterpriseEconomic.forEach(e -> {
@@ -125,10 +126,26 @@ public class DataCountService {
             }
         });
 
+        lastLeaseDetail = new ArrayList<>(lastLeaseDetail.stream()
+                .collect(Collectors.toMap(
+                        LeaseDetail::getCRoomCode,
+                        p -> p,
+                        (existing, replacement) ->{
+                            LocalDate existingEnd = existing.getCEndDate();
+                            LocalDate replacementEnd = replacement.getCEndDate();
+
+                            if (existingEnd == null) return replacement;
+                            if (replacementEnd == null) return existing;
+
+                            return existingEnd.isAfter(replacementEnd) ? existing : replacement;
+                        }
+                ))
+                .values());
+
         //楼宇/企业/企业经济数据遍历,全镇级/产业园级/楼栋级一并处理
 
         //遍历并计算企业相关的结果
-        countEnterprise(allEnterprise, enterpriseEconomicMap);
+        countEnterprise(allEnterprise, enterpriseEconomicMap, now);
 
         //遍历计算产业园相关
         countIndustrialPark(allIndustrialPark);
@@ -137,11 +154,21 @@ public class DataCountService {
         countOrder(allOrder);
 
         //租赁信息相关统计
-        countLease(lastLeaseDetail);
+        countLease(lastLeaseDetail,now);
+
+        countRoomStatusByLease(lastLeaseDetail, now);
+
+        countHistoryData(allEnterprise, allIndustrialPark, lastYearLease, now);
+
+        cacheTownData = tempCacheTownData;
+        cacheParkData = tempCacheParkData;
+        cacheBuildData = tempCacheBuildData;
+    }
 
+    private void countHistoryData(List<Enterprise> allEnterprise, List<IndustrialPark> allIndustrialPark, List<LeaseDetail> lastYearLease, LocalDate now) {
         //历史企业总数统计
         //历史数据,所以不论企业现状如何
-        Map<String, List<Enterprise>> enterpriseMap = TimeUtil.split(allEnterprise);
+        Map<String, List<Enterprise>> enterpriseMap = TimeUtil.split(allEnterprise, now);
         Map<String, Integer> enterpriseByMonth = enterpriseMap.entrySet()
                 .stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().size()));
 
@@ -150,22 +177,22 @@ public class DataCountService {
         Map<String, List<Enterprise>> enterpriseInTownMap = TimeUtil.split(allEnterprise
                 .stream()
                 .filter(e -> Objects.equals(e.getCSsxqCode(), "#YIDIQIYE"))
-                .collect(Collectors.toList()));
+                .collect(Collectors.toList()), now);
         Map<String, Integer> enterpriseInTownByMonth = enterpriseInTownMap.entrySet()
                 .stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().size()));
 
         //历史房间总数统计
         Map<String, List<IndustrialPark>> industrialParkMap = TimeUtil.split(allIndustrialPark
                 .stream()
-                .filter(e->Objects.equals(e.getCResourceType(),"1"))
-                .collect(Collectors.toList())
-        );
-        Map<String,Integer> roomByMonth = industrialParkMap.entrySet().stream().collect(
+                .filter(e -> Objects.equals(e.getCResourceType(), "1"))
+                .collect(Collectors.toList()),
+                now);
+        Map<String, Integer> roomByMonth = industrialParkMap.entrySet().stream().collect(
                 Collectors.toMap(Map.Entry::getKey, e -> e.getValue().size())
         );
 
         //历史已使用房间总数统计
-        Map<String, List<LeaseDetail>> leaseMap = TimeUtil.split(lastYearLease);
+        Map<String, List<LeaseDetail>> leaseMap = TimeUtil.split(lastYearLease, now);
         Map<String, Long> leaseByMonth = leaseMap.entrySet()
                 .stream()
                 .collect(
@@ -187,16 +214,10 @@ public class DataCountService {
                 );
 
 
-
-
         tempCacheTownData.put("enterpriseByMonth", enterpriseByMonth);
         tempCacheTownData.put("enterpriseInTownByMonth", enterpriseInTownByMonth);
         tempCacheTownData.put("leaseByMonth", leaseByMonth);
         tempCacheTownData.put("roomByMonth", roomByMonth);
-
-        cacheTownData = tempCacheTownData;
-        cacheParkData = tempCacheParkData;
-        cacheBuildData = tempCacheBuildData;
     }
 
 
@@ -455,7 +476,7 @@ public class DataCountService {
         tempCacheTownData.put("areaUsed", totalBuildArea.subtract(totalVacantArea));
     }
 
-    private void countEnterprise(List<Enterprise> allEnterprise, Map<String, List<EnterpriseEconomic>> enterpriseEconomicMap) {
+    private void countEnterprise(List<Enterprise> allEnterprise, Map<String, List<EnterpriseEconomic>> enterpriseEconomicMap, LocalDate now) {
         int inTownCount = 0;
         int gsqyCount = 0;
         int aliveCount = 0;
@@ -491,9 +512,9 @@ public class DataCountService {
                     List<EnterpriseEconomic> economicBy12Month = new ArrayList<>();
                     List<EnterpriseEconomic> economicByYtdThisYear = new ArrayList<>();
                     List<EnterpriseEconomic> economicByYtdLastYear = new ArrayList<>();
-                    List<String> Last12Month = SpecialisationStringCollector.YearMonthByLast12Month();
-                    List<String> ytdThisYear = SpecialisationStringCollector.YearMonthByYtd();
-                    List<String> ytdLastYear = SpecialisationStringCollector.YearMonthByYtd(1);
+                    List<String> Last12Month = SpecialisationStringCollector.YearMonthByLast12Month(now);
+                    List<String> ytdThisYear = SpecialisationStringCollector.YearMonthByYtd(now);
+                    List<String> ytdLastYear = SpecialisationStringCollector.YearMonthByYtd(1, now);
                     Optional.ofNullable(enterpriseEconomicList).orElse(new ArrayList<>()).stream()
                             .filter(e -> !"4".equals(e.getCDataStatus()))
                             .forEach(e -> {
@@ -547,13 +568,11 @@ public class DataCountService {
         tempCacheTownData.put("orderCount", orderCount);
     }
 
-    private void countLease(List<LeaseDetail> allLease) {
+    private void countLease(List<LeaseDetail> allLease,LocalDate now) {
         List<LeaseDetail> timeoutIn1Month = new ArrayList<>();
         List<LeaseDetail> timeoutIn3Month = new ArrayList<>();
 
-        LocalDate now = LocalDate.now();
 
-        Map<String, LeaseDetail> leaseMap = new HashMap<>();
         for (LeaseDetail lease : allLease) {
             if (lease.getCEndDate() != null) {
                 if (lease.getCEndDate().isAfter(now)) {
@@ -564,77 +583,100 @@ public class DataCountService {
                     }
                 }
             }
-            leaseMap.put(lease.getCRoomCode(), lease);
         }
+        timeoutIn1Month.sort(Comparator.comparing(LeaseDetail::getCEndDate));
+        timeoutIn3Month.sort(Comparator.comparing(LeaseDetail::getCEndDate));
 
-        int vacantRoomCount = 0;
-        BigDecimal vacantAreaCount = BigDecimal.ZERO;
-        int expiringSoonRoomCount = 0;
-        BigDecimal expiringSoonAreaCount = BigDecimal.ZERO;
-        int utilizedRoomCount = 0;
-        BigDecimal utilizedAreaCount = BigDecimal.ZERO;
-        int reservedRoomCount = 0;
-        BigDecimal reservedAreaCount = BigDecimal.ZERO;
-        int terminatedRoomCount = 0;
-        BigDecimal terminatedAreaCount = BigDecimal.ZERO;
+        List<LeaseDetail> sortedLeaseTimeout = Stream.concat(timeoutIn1Month.stream(), timeoutIn3Month.stream())
+                .sorted(Comparator.comparing(LeaseDetail::getCEndDate))
+                .limit(25)
+                .collect(Collectors.toList());
+
+        tempCacheTownData.put("leaseTimeoutIn1Month", timeoutIn1Month.size());
+        tempCacheTownData.put("leaseTimeoutIn3Month", timeoutIn3Month.size());
+        tempCacheTownData.put("leaseTimeout", sortedLeaseTimeout);
+    }
+
+    private void countRoomStatusByLease(List<LeaseDetail> allLease, LocalDate now) {
+
+        Map<String, LeaseDetail> leaseMap = allLease.stream().collect(
+                Collectors.toMap(
+                        LeaseDetail::getCRoomCode,
+                        v -> v
+                )
+        );
+        String vacant = "vacant";
+        String expiringSoon = "expiringSoon";
+        String utilized = "utilized";
+        String reserved = "reserved";
+        String terminated = "terminated";
+        String[] buckets = new String[]{vacant, expiringSoon, utilized, reserved, terminated};
+
+        Map<String, List<IndustrialPark>> roomBuckets = new HashMap<>();
+
+        for (String bucket : buckets) {
+            roomBuckets.put(bucket, new ArrayList<>());
+        }
         for (List<IndustrialPark> roomList : roomMap.values()) {
             for (IndustrialPark room : roomList) {
                 LeaseDetail lease = leaseMap.get(room.getCParkCode());
                 if (lease == null) {
-                    vacantRoomCount++;
-                    vacantAreaCount = vacantAreaCount.add(Optional.ofNullable(room.getCBuildingArea()).orElse(BigDecimal.ZERO));
+                    roomBuckets.get(vacant).add(room);
                     continue;
                 }
                 if (lease.getCEndDate().isAfter(now) && lease.getCStartDate().isBefore(now)) {
-                    utilizedRoomCount++;
-                    utilizedAreaCount = utilizedAreaCount.add(Optional.ofNullable(room.getCBuildingArea()).orElse(BigDecimal.ZERO));
+                    roomBuckets.get(utilized).add(room);
                     continue;
                 }
                 if (lease.getCStartDate().isAfter(now) && lease.getCEndDate().isAfter(now)) {
-                    reservedRoomCount++;
-                    reservedAreaCount = reservedAreaCount.add(Optional.ofNullable(room.getCBuildingArea()).orElse(BigDecimal.ZERO));
+                    roomBuckets.get(reserved).add(room);
                     continue;
                 }
                 if (lease.getCEndDate().isBefore(now) && lease.getCEndDate().plusMonths(1).isAfter(now)) {
-                    terminatedRoomCount++;
-                    terminatedAreaCount = terminatedAreaCount.add(Optional.ofNullable(room.getCBuildingArea()).orElse(BigDecimal.ZERO));
+                    roomBuckets.get(terminated).add(room);
                     continue;
                 }
                 if (lease.getCEndDate().isAfter(now) && lease.getCEndDate().isBefore(now.plusMonths(3))) {
-                    expiringSoonRoomCount++;
-                    expiringSoonAreaCount = expiringSoonAreaCount.add(Optional.ofNullable(room.getCBuildingArea()).orElse(BigDecimal.ZERO));
+                    roomBuckets.get(expiringSoon).add(room);
                     continue;
                 }
-                vacantRoomCount++;
-                vacantAreaCount = vacantAreaCount.add(Optional.ofNullable(room.getCBuildingArea()).orElse(BigDecimal.ZERO));
+                roomBuckets.get(vacant).add(room);
             }
         }
+        tempCacheTownData.put("leaseVacantRoomCount", roomBuckets.get(vacant).size());
+        tempCacheTownData.put("leaseVacantAreaCount", roomBuckets.get(vacant)
+                .stream()
+                .map(IndustrialPark::getCBuildingArea)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
 
-        timeoutIn1Month.sort(Comparator.comparing(LeaseDetail::getCEndDate));
-        timeoutIn3Month.sort(Comparator.comparing(LeaseDetail::getCEndDate));
-
-        List<LeaseDetail> sortedLeaseTimeout = Stream.concat(timeoutIn1Month.stream(), timeoutIn3Month.stream())
-                .sorted(Comparator.comparing(LeaseDetail::getCEndDate))
-                .limit(25)
-                .collect(Collectors.toList());
-
-        tempCacheTownData.put("leaseTimeoutIn1Month", timeoutIn1Month.size());
-        tempCacheTownData.put("leaseTimeoutIn3Month", timeoutIn3Month.size());
-        tempCacheTownData.put("leaseTimeout", sortedLeaseTimeout);
-        tempCacheTownData.put("leaseVacantRoomCount", vacantRoomCount);
-        tempCacheTownData.put("leaseVacantAreaCount", vacantAreaCount);
-
-        tempCacheTownData.put("leaseExpiringSoonRoomCount", expiringSoonRoomCount);
-        tempCacheTownData.put("leaseExpiringSoonAreaCount", expiringSoonAreaCount);
+        tempCacheTownData.put("leaseExpiringSoonRoomCount", roomBuckets.get(expiringSoon).size());
+        tempCacheTownData.put("leaseExpiringSoonAreaCount", roomBuckets.get(expiringSoon)
+                .stream()
+                .map(IndustrialPark::getCBuildingArea)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
 
-        tempCacheTownData.put("leaseUtilizedRoomCount", utilizedRoomCount);
-        tempCacheTownData.put("leaseUtilizedAreaCount", utilizedAreaCount);
+        tempCacheTownData.put("leaseUtilizedRoomCount", roomBuckets.get(utilized).size());
+        tempCacheTownData.put("leaseUtilizedAreaCount", roomBuckets.get(utilized)
+                .stream()
+                .map(IndustrialPark::getCBuildingArea)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
 
-        tempCacheTownData.put("leaseReservedRoomCount", reservedRoomCount);
-        tempCacheTownData.put("leaseReservedAreaCount", reservedAreaCount);
+        tempCacheTownData.put("leaseReservedRoomCount", roomBuckets.get(reserved).size());
+        tempCacheTownData.put("leaseReservedAreaCount", roomBuckets.get(reserved)
+                .stream()
+                .map(IndustrialPark::getCBuildingArea)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
 
-        tempCacheTownData.put("leaseTerminatedRoomCount", terminatedRoomCount);
-        tempCacheTownData.put("leaseTerminatedAreaCount", terminatedAreaCount);
+        tempCacheTownData.put("leaseTerminatedRoomCount", roomBuckets.get(terminated).size());
+        tempCacheTownData.put("leaseTerminatedAreaCount", roomBuckets.get(terminated)
+                .stream()
+                .map(IndustrialPark::getCBuildingArea)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
     }
 
     public JSONObject getTownData() {

+ 8 - 11
src/main/java/com/skyversation/xjcy/util/SpecialisationStringCollector.java

@@ -7,14 +7,13 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class SpecialisationStringCollector {
-    public static List<String> YearMonthByLast12Month() {
+    public static List<String> YearMonthByLast12Month(LocalDate now) {
         List<String> list = new ArrayList<>();
 
         //先拿时间
-        LocalDate localDate = LocalDate.now();
-        int dayForMonth = localDate.getDayOfMonth();
+        int dayForMonth = now.getDayOfMonth();
         // 计算“起始年月”
-        YearMonth startYm = YearMonth.from(localDate).minusMonths(dayForMonth < 15 ? 2 : 1);
+        YearMonth startYm = YearMonth.from(now).minusMonths(dayForMonth < 15 ? 2 : 1);
 
         // 往前推 12 个月
         DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMM");
@@ -25,11 +24,10 @@ public class SpecialisationStringCollector {
         return list;
     }
 
-    public static List<String> YearMonthByYtd(int offsetYear) {
+    public static List<String> YearMonthByYtd(int offsetYear, LocalDate now) {
         List<String> list = new ArrayList<>();
-
         //先拿时间
-        LocalDate localDate = LocalDate.now();
+        LocalDate localDate = now;
         localDate = localDate.minusYears(offsetYear);
         int dayForMonth = localDate.getDayOfMonth();
         // 计算“起始年月”
@@ -50,15 +48,14 @@ public class SpecialisationStringCollector {
         return list;
     }
 
-    public static List<String> YearMonthByYtd() {
-        return YearMonthByYtd(0);
+    public static List<String> YearMonthByYtd(LocalDate now) {
+        return YearMonthByYtd(0, now);
     }
 
-    private static List<String> summonLastYearStringBySeason() {
+    private static List<String> summonLastYearStringBySeason(LocalDate now) {
         List<String> list = new ArrayList<>();
 
         // 当前季度
-        LocalDate now = LocalDate.now();
         int quarter = (now.getMonthValue() - 1) / 3 + 1;
 
         // 起始季度:如果当前是 1 月 1-15 号,则往前多推一个季度

+ 3 - 4
src/main/java/com/skyversation/xjcy/util/TimeUtil.java

@@ -12,10 +12,9 @@ public class TimeUtil {
 
     private TimeUtil() {}
 
-    public static <T extends DateInterval> Map<String, List<T>> split(List<T> src) {
-        LocalDate today      = LocalDate.now();
-        YearMonth firstMonth = YearMonth.from(today.minusMonths(12));
-        YearMonth lastMonth  = YearMonth.from(today.minusMonths(1));
+    public static <T extends DateInterval> Map<String, List<T>> split(List<T> src, LocalDate now) {
+        YearMonth firstMonth = YearMonth.from(now.minusMonths(12));
+        YearMonth lastMonth  = YearMonth.from(now.minusMonths(1));
 
         // 1. 创建 12 个桶,key 为 "yyyy-MM"
         Map<String, List<T>> map = new LinkedHashMap<>();