浏览代码

部分企业健康计算的实现和相关基础建设,向clue导出功能补充一个新筛选字段

ximinghao 3 月之前
父节点
当前提交
9026d7677a

+ 1 - 0
src/main/java/com/skyversation/xjcy/Timer.java

@@ -3,6 +3,7 @@ package com.skyversation.xjcy;
 import com.skyversation.xjcy.service.ParkPreCountService;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 
 @Component

+ 1 - 1
src/main/java/com/skyversation/xjcy/bean/Clue.java

@@ -45,7 +45,7 @@ public class Clue implements FromJSON{
     private String landNature;
 
     /** 用地规模(亩) */
-    private BigDecimal landArea;
+    private String landArea;
 
     /** 物业面积(㎡) */
     private BigDecimal propertyArea;

+ 87 - 0
src/main/java/com/skyversation/xjcy/bean/EnterpriseHealth.java

@@ -0,0 +1,87 @@
+package com.skyversation.xjcy.bean;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * 企业健康计算结果Bean
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class EnterpriseHealth {
+    
+    /**
+     * 标题
+     */
+    private String cTitle;
+    
+    /**
+     * 描述
+     */
+    private String cDescribe;
+    
+    /**
+     * 健康类型值
+     */
+    private Integer cType;
+    
+    /**
+     * 计算时间
+     */
+    private LocalDateTime cComputeTime;
+    
+    /**
+     * 健康开始时间
+     */
+    private LocalDateTime cHealthStartTime;
+    
+    /**
+     * 健康结束时间
+     */
+    private LocalDateTime cHealthEndTime;
+    
+    /**
+     * 企业统一社会信用代码
+     */
+    private String cEnterpriseCode;
+
+    /**
+     * 转换为JSONObject
+     * @return JSONObject
+     */
+    public JSONObject toJson() {
+        JSONObject json = new JSONObject();
+        json.put("c_title", this.cTitle);
+        json.put("c_describe", this.cDescribe);
+        json.put("c_type", this.cType);
+        json.put("c_compute_time", this.cComputeTime);
+        json.put("c_health_start_time", this.cHealthStartTime);
+        json.put("c_health_end_time", this.cHealthEndTime);
+        json.put("c_enterprise_code", this.cEnterpriseCode);
+        json.put("title", this.cTitle);
+        json.put("content", this.cDescribe);
+        return json;
+    }
+
+    /**
+     * 从JSONObject解析
+     * @param json JSONObject
+     * @return EnterpriseHealthResult
+     */
+    public static EnterpriseHealth fromJson(JSONObject json) {
+        EnterpriseHealth result = new EnterpriseHealth();
+        result.setCTitle(json.getString("c_title"));
+        result.setCDescribe(json.getString("c_describe"));
+        result.setCType(json.getInteger("c_type"));
+        result.setCComputeTime(json.getObject("c_compute_time", LocalDateTime.class));
+        result.setCHealthStartTime(json.getObject("c_health_start_time", LocalDateTime.class));
+        result.setCHealthEndTime(json.getObject("c_health_end_time", LocalDateTime.class));
+        result.setCEnterpriseCode(json.getString("c_enterprise_code"));
+        return result;
+    }
+}

+ 555 - 0
src/main/java/com/skyversation/xjcy/computer/EnterpriseHealthComputer.java

@@ -0,0 +1,555 @@
+package com.skyversation.xjcy.computer;
+
+import com.alibaba.fastjson.JSONObject;
+import com.skyversation.xjcy.bean.Enterprise;
+import com.skyversation.xjcy.bean.EnterpriseEconomic;
+import com.skyversation.xjcy.bean.EnterpriseHealth;
+import lombok.Getter;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.time.LocalDateTime;
+import java.time.MonthDay;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+/**
+ * 企业健康状况计算器
+ * 用于分析企业的经营状况并生成健康报告
+ */
+public class EnterpriseHealthComputer {
+
+    /**
+     * 企业健康类型枚举
+     * 定义各种健康状态及其描述
+     */
+    public enum HealthType {
+        /**
+         * 清算注销 - 企业已处于注销流程,请核查经营情况
+         */
+        LIQUIDATION(10, "清算注销", "企业已处于注销流程,请核查经营情况"),
+
+        /**
+         * 严重失信 - 企业列入严重违法失信名单,暂停政策申请
+         */
+        SERIOUS_DISHONESTY(11, "严重失信", "企业列入严重违法失信名单,暂停政策申请"),
+
+        /**
+         * 股权出质 - 股权已全额出质,关注经营稳定性
+         */
+        EQUITY_PLEDGE(12, "股权出质", "股权已全额出质,关注经营稳定性"),
+
+        /**
+         * 终本案件 - 存在大额未履行终本案件,注意法律风险
+         */
+        FINAL_CASE(13, "终本案件", "存在大额未履行终本案件,注意法律风险"),
+
+        /**
+         * 税收跳水 - 税收断崖式下跌,需核实经营情况
+         */
+        TAX_DIVE(14, "税收跳水", "税收断崖式下跌,需核实经营情况"),
+
+        /**
+         * 能耗异常 - 能耗接近零,疑似停产或外迁
+         */
+        ENERGY_ABNORMAL(15, "能耗异常", "能耗接近零,疑似停产或外迁"),
+
+        /**
+         * 租约到期 - 租约即将到期未续签,提前跟进招商
+         */
+        LEASE_EXPIRY(16, "租约到期", "租约即将到期未续签,提前跟进招商"),
+
+        /**
+         * 纳税逾期 - 多次逾期申报,提醒企业及时纳税
+         */
+        TAX_OVERDUE(17, "纳税逾期", "多次逾期申报,提醒企业及时纳税"),
+
+        /**
+         * 税收上升 - 税收稳步提升,潜力优秀
+         */
+        TAX_RISE(20, "税收上升", "税收稳步提升,潜力优秀"),
+
+        /**
+         * 产值上升 - 产值稳步提升,潜力优秀
+         */
+        OUTPUT_RISE(21, "产值上升", "产值稳步提升,潜力优秀"),
+
+        /**
+         * 升规成功 - 企业新晋规上,建议重点服务
+         */
+        UPGRADE_SUCCESS(22, "升规成功", "企业新晋规上,建议重点服务"),
+
+        /**
+         * 专利爆发 - 知识产权快速积累,创新力强
+         */
+        PATENT_EXPLOSION(23, "专利爆发", "知识产权快速积累,创新力强"),
+
+        /**
+         * 500强投资 - 背靠500强,扩张潜力大
+         */
+        TOP500_INVESTMENT(24, "500强投", "背靠500强,扩张潜力大"),
+
+        /**
+         * 产业新星 - 重点产业新落地,建议跟踪服务
+         */
+        INDUSTRIAL_RISING_STAR(25, "产业新星", "重点产业新落地,建议跟踪服务");
+
+        @Getter
+        final int value;
+        @Getter
+        final String defaultName;
+        @Getter
+        final String defaultDescribe;
+
+        HealthType(int value, String defaultName, String defaultDescribe) {
+            this.value = value;
+            this.defaultName = defaultName;
+            this.defaultDescribe = defaultDescribe;
+        }
+    }
+
+    /**
+     * 一系列月份组成的季节<br/>不可变对象
+     */
+    public static class Season {
+        @Getter
+        private final List<YearMonth> yearMonths;
+
+        private Season(List<YearMonth> yearMonths) {
+            this.yearMonths = new ArrayList<>(yearMonths);
+        }
+
+        /**
+         * 获取该季节的起始时间
+         *
+         * @return 第一个月的第一天的0点
+         */
+        public LocalDateTime getStartTime() {
+            return yearMonths.get(0).atDay(1).atStartOfDay();
+        }
+
+        /**
+         * 获取该季节的结束时间
+         *
+         * @return 最后一个月的最后一天的12点
+         */
+        public LocalDateTime getEndTime() {
+            return yearMonths.get(yearMonths.size() - 1).atEndOfMonth().plusDays(1).atStartOfDay();
+        }
+
+        /**
+         * 将当前季节向前推移指定的季节数
+         * 每个季节包含3个月,因此实际推移的月份数为 season * 3
+         *
+         * @param season 要推移的季节数量,正数表示向过去推移,负数表示向未来推移
+         * @return 推移后的新Season对象
+         * @example // 假设当前是2024年第一季度(1-3月)
+         * season.minusSeasons(1) // 返回2023年第四季度(10-12月)
+         * season.minusSeasons(-1) // 返回2024年第二季度(4-6月)
+         */
+        public Season minusSeasons(int season) {
+            return new Season(yearMonths.stream().map(y -> y.minusMonths(season * 3L)).collect(Collectors.toList()));
+        }
+
+        /**
+         * 判断给定的时间是否包含在当前季节的时间范围内。
+         * 时间范围是前闭后开区间,即 [startTime, endTime)
+         *
+         * @param time 要检查的时间
+         * @return 如果时间在季节范围内(即大于等于开始时间,小于结束时间)返回true,否则返回false
+         */
+        public boolean contains(LocalDateTime time) {
+            return !getStartTime().isAfter(time) && getEndTime().isAfter(time);
+        }
+
+        /**
+         * 判断指定年月是否在当前季节的月份范围内
+         * 直接检查YearMonth是否在季节的月份列表中,不涉及具体日期和时间
+         *
+         * @param yearMonth 要检查的年月
+         * @return 如果年月在季节的月份列表中返回true,否则返回false
+         * @example // 假设季节是2024年第一季度(1-3月)
+         * contains(YearMonth.of(2024, 1))  // true
+         * contains(YearMonth.of(2024, 2))  // true
+         * contains(YearMonth.of(2024, 3))  // true
+         * contains(YearMonth.of(2024, 4))  // false
+         * contains(YearMonth.of(2023, 12)) // false
+         */
+        public boolean contains(YearMonth yearMonth) {
+            return yearMonths.contains(yearMonth);
+        }
+
+        @Override
+        public int hashCode() {
+            return yearMonths.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) return true;
+            if (obj == null || obj.getClass() != this.getClass()) return false;
+            return yearMonths.equals(((Season) obj).yearMonths);
+        }
+    }
+
+    // ==================== 静态常量 ====================
+
+    /**
+     * 同步锁对象
+     */
+    public static final Object LOCK = new Object();
+
+    /**
+     * 经济数据年月格式转换器
+     */
+    public static final DateTimeFormatter economicYearMonthFormat = DateTimeFormatter.ofPattern("yyyyMM");
+
+    /**
+     * 简单两位小数decimalFormat
+     */
+    public static final DecimalFormat simpleDecimalFormat = new DecimalFormat("0.00%");
+
+    /**
+     * 季度结束日期集合
+     */
+    private static final Set<MonthDay> SEASON_ENDS = new HashSet<>(Arrays.asList(
+            MonthDay.of(3, 31),
+            MonthDay.of(6, 30),
+            MonthDay.of(9, 30),
+            MonthDay.of(12, 31)));
+
+    // ==================== 实例变量 ====================
+
+    /**
+     * 计算结果列表
+     */
+    @Getter
+    List<EnterpriseHealth> results;
+
+    /**
+     * 企业列表
+     */
+    List<Enterprise> enterprises;
+
+    /**
+     * 企业经济数据映射:企业ID -> (年月 -> 经济数据)
+     */
+    Map<String, Map<YearMonth, EnterpriseEconomic>> enterpriseEconomics;
+
+    // ==================== 构造方法 ====================
+
+    /**
+     * 构造函数
+     *
+     * @param enterprises 企业列表
+     */
+    public EnterpriseHealthComputer(List<Enterprise> enterprises) {
+        this.enterprises = enterprises;
+    }
+
+    // ==================== 公共方法 ====================
+
+    /**
+     * 获取JSON格式的结果列表
+     *
+     * @return JSON对象列表
+     */
+    public List<JSONObject> getResultJsons() {
+        return results.stream().map(EnterpriseHealth::toJson).collect(Collectors.toList());
+    }
+
+    /**
+     * 添加企业经济数据
+     *
+     * @param economics 企业经济数据集合
+     */
+    public void putEnterpriseEconomics(Collection<EnterpriseEconomic> economics) {
+        enterpriseEconomics = economics.stream()
+                .collect(Collectors.groupingBy(
+                        EnterpriseEconomic::getCEnterpriseId,
+                        Collectors.toMap(
+                                enterpriseEconomic -> YearMonth.parse(enterpriseEconomic.getCYearMonth(), economicYearMonthFormat),
+                                Function.identity()
+                        )
+                ));
+    }
+
+    /**
+     * 计算税收上升情况
+     *
+     * @param now 当前时间
+     */
+    public void computeTaxRise(LocalDateTime now) {
+        //最近四个季节
+        List<Season> seasons = getLastFourSeason(now);
+        //四个季节的上一年同季节
+        List<Season> previousYearSeasons = seasons.stream().map(s -> s.minusSeasons(4)).collect(Collectors.toList());
+        for (Enterprise enterprise : enterprises) {
+            List<List<EnterpriseEconomic>> seasonEconomic = getEconomicBySeasonList(enterprise, seasons);
+            List<List<EnterpriseEconomic>> previousYearSeasonEconomic = getEconomicBySeasonList(enterprise, previousYearSeasons);
+            //去年数据必须完整,避免因数据缺失异常标记
+            if (previousYearSeasonEconomic.stream().anyMatch(list->list.contains(null))) {
+                continue;
+            }
+            //较新四个季度的税收统计
+            BigDecimal riseRate = checkAllRiseAndGetRiseRate(seasonEconomic, previousYearSeasonEconomic);
+            if (riseRate == null) continue;
+            //当总额上升率超过20%时提交记录
+            if (riseRate.compareTo(BigDecimal.valueOf(12,1)) >= 0) {
+                putResult(enterprise,
+                        HealthType.TAX_RISE.getDefaultName()+simpleDecimalFormat.format(riseRate.subtract(BigDecimal.ONE)),
+                        HealthType.TAX_RISE.getDefaultDescribe(),
+                        HealthType.TAX_RISE,
+                        now, seasons.get(0).getStartTime(), seasons.get(seasons.size() - 1).getEndTime());
+            }
+        }
+    }
+
+    private static BigDecimal checkAllRiseAndGetRiseRate(List<List<EnterpriseEconomic>> seasonEconomic, List<List<EnterpriseEconomic>> previousYearSeasonEconomic) {
+        List<BigDecimal> seasonTax = seasonEconomic.stream().map(
+                l->l.stream()
+                        .filter(Objects::nonNull)
+                        .map(EnterpriseEconomic::getCApprovedTax)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO,BigDecimal::add)
+        ).collect(Collectors.toList());
+        //较旧四个季度的税收统计
+        List<BigDecimal> previousYearSeasonTax = previousYearSeasonEconomic.stream().map(
+                l->l.stream()
+                        .filter(Objects::nonNull)
+                        .map(EnterpriseEconomic::getCApprovedTax)
+                        .filter(Objects::nonNull)
+                        .reduce(BigDecimal.ZERO,BigDecimal::add)
+        ).collect(Collectors.toList());
+        //检查所有季度是否同比上升
+        if (!isAllUpper(seasonTax, previousYearSeasonTax)) {
+            return null;
+        }
+        //计算上升率
+        BigDecimal divide = sumAndDivide(seasonTax, previousYearSeasonTax);
+        if (divide == null) {
+            return null;
+        }
+        return divide;
+    }
+
+
+    /**
+     * 计算产出上升情况
+     *
+     * @param now 当前时间
+     */
+    @SuppressWarnings("DuplicatedCode")
+    public void computeOutputRise(LocalDateTime now) {
+//最近四个季节
+        List<Season> seasons = getLastFourSeason(now);
+        //四个季节的上一年同季节
+        List<Season> previousYearSeasons = seasons.stream().map(s -> s.minusSeasons(4)).collect(Collectors.toList());
+        for (Enterprise enterprise : enterprises) {
+            List<List<EnterpriseEconomic>> seasonEconomic = getEconomicBySeasonList(enterprise, seasons);
+            List<List<EnterpriseEconomic>> previousYearSeasonEconomic = getEconomicBySeasonList(enterprise, previousYearSeasons);
+            //去年数据必须完整,避免因数据缺失异常标记
+            if (previousYearSeasonEconomic.stream().anyMatch(list->list.contains(null))) {
+                continue;
+            }
+            //计算上升率
+            BigDecimal riseRate = checkAllRiseAndGetRiseRate(seasonEconomic, previousYearSeasonEconomic);
+            if (riseRate == null) {
+                continue;
+            }
+            //当总额上升率超过20%时提交记录
+            if (riseRate.compareTo(BigDecimal.valueOf(12,1)) >= 0) {
+                putResult(enterprise,
+                        HealthType.OUTPUT_RISE.getDefaultName()+simpleDecimalFormat.format(riseRate.subtract(BigDecimal.ONE)),
+                        HealthType.OUTPUT_RISE.getDefaultDescribe(),
+                        HealthType.OUTPUT_RISE,
+                        now, seasons.get(0).getStartTime(), seasons.get(seasons.size() - 1).getEndTime());
+            }
+        }
+
+    }
+
+    /**
+     * 计算税收跳水情况
+     *
+     * @param now 当前时间
+     */
+    public void computeTaxDive(LocalDateTime now) {
+
+    }
+
+    // ==================== 私有方法 ====================
+
+    /**
+     * 添加计算结果(自定义标题和描述)
+     *
+     * @param enterprise  企业对象
+     * @param title       健康标题
+     * @param describe    健康描述
+     * @param type        健康类型
+     * @param computeTime 计算时间
+     * @param healthStart 健康开始时间
+     * @param healthEnd   健康结束时间
+     * @return 企业健康对象
+     */
+    private EnterpriseHealth putResult(Enterprise enterprise, String title, String describe, HealthType type, LocalDateTime computeTime,
+                                       LocalDateTime healthStart, LocalDateTime healthEnd) {
+        EnterpriseHealth result = new EnterpriseHealth(title, describe, type.value, computeTime,
+                healthStart, healthEnd, enterprise.getCUnifiedSocialCreditCode());
+        results.add(result);
+        return result;
+    }
+
+    /**
+     * 添加计算结果(使用默认标题和描述)
+     *
+     * @param enterprise  企业对象
+     * @param type        健康类型
+     * @param computeTime 计算时间
+     * @param healthStart 健康开始时间
+     * @param healthEnd   健康结束时间
+     * @return 企业健康对象
+     */
+    private EnterpriseHealth putResult(Enterprise enterprise, HealthType type, LocalDateTime computeTime,
+                                       LocalDateTime healthStart, LocalDateTime healthEnd) {
+        EnterpriseHealth result = new EnterpriseHealth(type.defaultName, type.defaultDescribe, type.value, computeTime,
+                healthStart, healthEnd, enterprise.getCUnifiedSocialCreditCode());
+        results.add(result);
+        return result;
+    }
+
+    /**
+     * 根据季节列表获取企业对应的经济数据
+     * 按季节分组,每个季节包含该季节内各个月份的经济数据列表
+     *
+     * @param enterprise 企业对象,包含企业基本信息
+     * @param seasons 季节列表,每个季节包含对应的年月信息
+     * @return 按季节分组的企业经济数据二维列表
+     *         外层列表对应每个季节,内层列表对应该季节各个月份的经济数据
+     *         如果某个月份没有数据,对应位置可能为null
+     */
+    private List<List<EnterpriseEconomic>> getEconomicBySeasonList(Enterprise enterprise, List<Season> seasons) {
+        List<List<EnterpriseEconomic>> seasonEconomic = new ArrayList<>();
+        for (Season season : seasons) {
+            //企业编码
+            String enterpriseCode = enterprise.getCUnifiedSocialCreditCode();
+            Map<YearMonth, EnterpriseEconomic> yearMonthEnterpriseEconomicMap = enterpriseEconomics.get(enterpriseCode);
+            if (yearMonthEnterpriseEconomicMap == null) {
+                yearMonthEnterpriseEconomicMap = Collections.emptyMap();
+            }
+            seasonEconomic.add(season.getYearMonths().stream()
+                    .map(yearMonthEnterpriseEconomicMap::get)
+                    .collect(Collectors.toList()));
+        }
+        return seasonEconomic;
+    }
+
+
+    /**
+     * 获取以季节结束月为基准的连续月份
+     *
+     * @param now            当前时间
+     * @param numberOfMonths 需要的月份数量
+     * @return 连续的YearMonth列表,从最早到最近排序
+     */
+    private static List<YearMonth> getConsecutiveMonthsFromSeasonEnd(LocalDateTime now, int numberOfMonths) {
+        if (numberOfMonths <= 0) {
+            return Collections.emptyList();
+        }
+
+        LocalDateTime seasonEndTime = checkAndFindSeasonEnd(now);
+        YearMonth endMonth = YearMonth.from(seasonEndTime);
+
+        List<YearMonth> months = new ArrayList<>();
+        // 从最早的月份开始添加,确保时间顺序
+        for (int i = numberOfMonths - 1; i >= 0; i--) {
+            months.add(endMonth.minusMonths(i));
+        }
+
+        return months;
+    }
+
+    /**
+     * 获取季度最后三个月
+     *
+     * @param now 当前时间
+     * @return 以输入点开始的最后一个季度Season
+     */
+    private static Season getLastSeason(LocalDateTime now) {
+        return new Season(getConsecutiveMonthsFromSeasonEnd(now, 3));
+    }
+
+    /**
+     * 获取季度最后十二个月
+     *
+     * @param now 当前时间
+     * @return 以输入点开始的最后四个季度Season
+     */
+    private static List<Season> getLastFourSeason(LocalDateTime now) {
+        List<YearMonth> months = getConsecutiveMonthsFromSeasonEnd(now, 12);
+        List<Season> seasons = new ArrayList<>();
+        for (int i = 0; i < 4; i++) {
+            seasons.add(new Season(months.subList(i * 3, (i + 1) * 3)));
+        }
+        return seasons;
+    }
+
+    /**
+     * 检查并找到最近的季度结束时间
+     *
+     * @param now 当前时间
+     * @return 季度结束时间
+     * @throws IllegalArgumentException 如果在可接受的误差范围(±1天)外
+     */
+    private static LocalDateTime checkAndFindSeasonEnd(LocalDateTime now) {
+        // 检查当前日期
+        if (isSeasonEnd(now)) return now;
+
+        // 检查后一天
+        LocalDateTime nextDay = now.plusDays(1);
+        if (isSeasonEnd(nextDay)) return nextDay;
+
+        // 检查前一天
+        LocalDateTime previousDay = now.minusDays(1);
+        if (isSeasonEnd(previousDay)) return previousDay;
+
+        throw new IllegalArgumentException("在可接受的误差范围(±1天)外");
+    }
+
+    /**
+     * 检查指定日期是否为季度结束日
+     *
+     * @param dateTime 日期时间
+     * @return 如果是季度结束日返回true,否则返回false
+     */
+    private static boolean isSeasonEnd(LocalDateTime dateTime) {
+        MonthDay monthDay = MonthDay.from(dateTime);
+        return SEASON_ENDS.contains(monthDay);
+    }
+
+    /**
+     * 分别计算输入1和输入2的合计值并做除法
+     * @return 除法的结果,当输入2为0时返回空
+     */
+    private static BigDecimal sumAndDivide(List<BigDecimal> valueList1, List<BigDecimal> valueList2) {
+        BigDecimal value1 = valueList1.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal value2 = valueList2.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+        if (value2.equals(BigDecimal.ZERO)) {
+            return null;
+        }
+        return value1.divide(value2, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 检查输入1的所有值是否都大于输入2同位置的值
+     */
+    private static boolean isAllUpper(List<BigDecimal> valueList1, List<BigDecimal> valueList2) {
+        return IntStream.range(0, valueList1.size()).allMatch(index -> valueList1.get(index).compareTo(valueList2.get(index)) > 0
+        );
+    }
+}

+ 1 - 4
src/main/java/com/skyversation/xjcy/counter/InvestmentPreCounter.java → src/main/java/com/skyversation/xjcy/computer/InvestmentPreCounter.java

@@ -1,13 +1,10 @@
-package com.skyversation.xjcy.counter;
+package com.skyversation.xjcy.computer;
 
 import com.alibaba.fastjson.JSONObject;
 import com.skyversation.xjcy.bean.Enterprise;
 import com.skyversation.xjcy.util.JSONDataTool;
-import lombok.AllArgsConstructor;
 import lombok.Getter;
 
-import java.math.BigDecimal;
-import java.time.LocalDate;
 import java.util.*;
 import java.util.stream.Collectors;
 

+ 1 - 1
src/main/java/com/skyversation/xjcy/counter/ParkPreCounter.java → src/main/java/com/skyversation/xjcy/computer/ParkPreCounter.java

@@ -1,4 +1,4 @@
-package com.skyversation.xjcy.counter;
+package com.skyversation.xjcy.computer;
 
 import com.alibaba.fastjson.JSONObject;
 import com.skyversation.xjcy.util.JSONDataTool;

+ 6 - 1
src/main/java/com/skyversation/xjcy/controller/DataExportController.java

@@ -28,9 +28,14 @@ public class DataExportController {
             @RequestParam(required = false) String c_clue_name ,
             @RequestParam(required = false) String c_enterprise_name ,
             @RequestParam(required = false) String construction_method,
+            @RequestParam(required = false) String timeRange ,
             HttpServletRequest request, HttpServletResponse response) {
         try {
-            List<Map<String, Object>> data = dataExportService.exportClue(c_clue_name,c_enterprise_name,construction_method);
+            String[] timeStr = timeRange.split(",");
+            if (timeStr.length != 2) {
+                return MessageManage.getInstance().getResultContent(-1,"timeRange不可用","timeRange不可用");
+            }
+            List<Map<String, Object>> data = dataExportService.exportClue(c_clue_name,c_enterprise_name,construction_method,timeStr[0],timeStr[1]);
             FileIOData.exportExcelWithPreDefinedHeader(
                     "徐泾镇招商项目(拿地)动态汇总表",
                     FileIOData.PreDefinedHeader.CLUE,

+ 3 - 1
src/main/java/com/skyversation/xjcy/dms/DMSColumn.java

@@ -10,7 +10,9 @@ public enum DMSColumn {
     LEASE_DETAIL("1574","1520"),
     INVESTMENT_TARGET("1578","1523"),
     CLUE("1576","1521"),
-    CLUE_FOLLOW("1577","1522");
+    CLUE_FOLLOW("1577","1522"),
+    ENTERPRISE_HEALTH("1643","1643"),
+    WECHAT_ARTICLE("1599","1544");
     @Getter
     private final String id;
     @Getter

+ 47 - 35
src/main/java/com/skyversation/xjcy/dms/DMSService.java

@@ -66,32 +66,6 @@ public class DMSService {
         return jsonObject;
     }
 
-    public void updateToDms(Collection<JSONObject> objs, String token, DMSColumn column) {
-        if (objs == null || objs.isEmpty()) {
-            return;
-        }
-        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
-        params.add("modelId", column.getModelId());
-        params.add("json", JSON.toJSONString(objs, SerializerFeature.WriteMapNullValue));
-        Map<String, String> headers = new HashMap<>();
-        headers.put("token", token);
-        HttpUtil.requestPost(path + "/content/updateContentByJson", params, headers);
-    }
-
-    public String importToDms(Resource resource, String token, DMSImport importType) {
-        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
-        params.add("columnId", importType.getColumn().getId());
-        params.add("contentParam", importType.getContent());
-        params.add("titleParam", importType.getTitle());
-        params.add("parseArray", importType.getRelation());
-        params.add("secretLevel", 0);
-        params.add("file", resource);
-        params.add("update", importType.isUpdate() ? "true" : "false");
-        Map<String, String> headers = new HashMap<>();
-        headers.put("token", token);
-        return HttpUtil.requestPost(path + "/content/importBeautifiedExcel", params, headers);
-    }
-
     private List<JSONObject> queryDmsList(DMSRequest request, String token, String columnId) {
         request.token = token;
         if (request.type == null) request.type = DMSRequest.DMSRequestType.List;
@@ -147,15 +121,6 @@ public class DMSService {
         return new ArrayList<>();
     }
 
-    public List<JSONObject> queryBeautifiedClue(String token, String cClueName, String cEnterpriseName, String constructionMethod) {
-        DMSRequest request = new DMSRequest();
-        request.type = DMSRequest.DMSRequestType.Beautified;
-        if (cClueName != null) request.addWhere("c_clue_name", "2", cClueName);
-        if (cEnterpriseName != null) request.addWhere("c_enterprise_name", "2", cEnterpriseName);
-        if (constructionMethod != null) request.addWhere("construction_method", "2", constructionMethod);
-        return queryDmsList(request, token, DMSColumn.CLUE.getId());
-    }
-
     public int getLargestCode(String token, String columId, String codeColumn, String today) {
         DMSRequest request = new DMSRequest();
         request.addWhere(codeColumn, "2", "%" + today + "%");
@@ -205,6 +170,53 @@ public class DMSService {
         return dmsResult.stream().map(jsonObject -> JSON.toJavaObject(jsonObject, clazz)).collect(Collectors.toList());
     }
 
+    public void updateToDms(Collection<JSONObject> objs, String token, DMSColumn column) {
+        if (objs == null || objs.isEmpty()) {
+            return;
+        }
+        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+        params.add("modelId", column.getModelId());
+        params.add("json", JSON.toJSONString(objs, SerializerFeature.WriteMapNullValue));
+        Map<String, String> headers = new HashMap<>();
+        headers.put("token", token);
+        HttpUtil.requestPost(path + "/content/updateContentByJson", params, headers);
+    }
+
+    public String importToDms(Resource resource, String token, DMSImport importType) {
+        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+        params.add("columnId", importType.getColumn().getId());
+        params.add("contentParam", importType.getContent());
+        params.add("titleParam", importType.getTitle());
+        params.add("parseArray", importType.getRelation());
+        params.add("secretLevel", 0);
+        params.add("file", resource);
+        params.add("update", importType.isUpdate() ? "true" : "false");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("token", token);
+        return HttpUtil.requestPost(path + "/content/importBeautifiedExcel", params, headers);
+    }
+
+    public void insertToDms(JSONObject objs, String token, DMSColumn column) {
+
+        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+        params.add("modelId",column.getModelId());
+        params.add("columnId", column.getId());
+        params.add("content", objs);
+        Map<String, String> headers = new HashMap<>();
+        headers.put("token", token);
+         HttpUtil.requestPost(path + "/content/addContent", params, headers);
+    }
+
+    public List<JSONObject> queryBeautifiedClue(String token, String cClueName, String cEnterpriseName, String constructionMethod, String timeStart, String timeEnd) {
+        DMSRequest request = new DMSRequest();
+        request.type = DMSRequest.DMSRequestType.Beautified;
+        if (cClueName != null) request.addWhere("c_clue_name", "2", cClueName);
+        if (cEnterpriseName != null) request.addWhere("c_enterprise_name", "2", cEnterpriseName);
+        if (constructionMethod != null) request.addWhere("construction_method", "2", constructionMethod);
+        if (timeStart != null&&timeEnd!=null) request.addWhere("create_time", "3", timeStart,timeEnd);
+        return queryDmsList(request, token, DMSColumn.CLUE.getId());
+    }
+
     //下面几个接口是重计算用的,有重新插入的需求,不能放进queryEnum,不能领域化
     public List<JSONObject> getAllParkByLy(String lyCode, String token) {
         DMSRequest requestChildren = new DMSRequest();

+ 2 - 3
src/main/java/com/skyversation/xjcy/service/DataExportService.java

@@ -2,7 +2,6 @@ package com.skyversation.xjcy.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.skyversation.xjcy.bean.ClueFollow;
-import com.skyversation.xjcy.dms.DMSColumn;
 import com.skyversation.xjcy.dms.DMSQuery;
 import com.skyversation.xjcy.dms.DMSService;
 import com.skyversation.xjcy.oauth.AuthService;
@@ -30,10 +29,10 @@ public class DataExportService {
         c_intended_parcel_code,c_intended_building_code,c_clue_status,c_economic_zone_id,c_economic_zone_name,
         c_responsible_person_id,c_responsible_person_name,create_time,author_id,update_time,c_updater
     }
-    public List<Map<String, Object>> exportClue(String c_clue_name, String c_enterprise_name, String construction_method) {
+    public List<Map<String, Object>> exportClue(String c_clue_name, String c_enterprise_name, String construction_method, String timeStart, String timeEnd) {
         List<Map<String,Object>> result = new ArrayList<>();
         LocalDate now = LocalDate.now();
-        List<JSONObject> clues = dmsService.queryBeautifiedClue(authService.getToken(), c_clue_name,c_enterprise_name, construction_method);
+        List<JSONObject> clues = dmsService.queryBeautifiedClue(authService.getToken(), c_clue_name,c_enterprise_name, construction_method,timeStart,timeEnd);
         List<ClueFollow> clueFollows = dmsService.query(authService.getToken(), DMSQuery.CLUE_FOLLOW, ClueFollow.class,now);
         //做map,仅留最近
         Map<String,ClueFollow> newestClueFollows = clueFollows.stream()

+ 1 - 1
src/main/java/com/skyversation/xjcy/service/InvestmentPreCountService.java

@@ -2,7 +2,7 @@ package com.skyversation.xjcy.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.skyversation.xjcy.bean.Enterprise;
-import com.skyversation.xjcy.counter.InvestmentPreCounter;
+import com.skyversation.xjcy.computer.InvestmentPreCounter;
 import com.skyversation.xjcy.dms.DMSColumn;
 import com.skyversation.xjcy.dms.DMSQuery;
 import com.skyversation.xjcy.dms.DMSService;

+ 1 - 1
src/main/java/com/skyversation/xjcy/service/ParkPreCountService.java

@@ -1,7 +1,7 @@
 package com.skyversation.xjcy.service;
 
 import com.alibaba.fastjson.JSONObject;
-import com.skyversation.xjcy.counter.ParkPreCounter;
+import com.skyversation.xjcy.computer.ParkPreCounter;
 import com.skyversation.xjcy.dms.DMSColumn;
 import com.skyversation.xjcy.dms.DMSService;
 import com.skyversation.xjcy.oauth.AuthService;