| | |
| | | */ |
| | | public String infer() { |
| | | try { |
| | | if (CollectionUtils.isEmpty(rules.getClientConfigs())) { |
| | | return null; |
| | | } |
| | | for (ClientConfig rule : rules.getClientConfigs()) { |
| | | if (rule == null || rule.getTimeValue() == null || StringUtils.isBlank(rule.getTimeUnit())) { |
| | | return null; |
| | | } |
| | | ChronoUnit unit = ChronoUnit.valueOf(rule.getTimeUnit().toUpperCase()); |
| | | LocalDate timeLimit = LocalDate.now().minus(rule.getTimeValue(), unit); |
| | | switch(unit) { |
| | |
| | | } |
| | | LocalDate finalTimeLimit = timeLimit; |
| | | List<T> filterData = dataList.stream().filter(t -> !timeVal.apply(t).isBefore(finalTimeLimit)).collect(Collectors.toList()); |
| | | |
| | | // 根据规则类型选择判断逻辑 |
| | | Byte ruleType = rule.getRuleType(); |
| | | if (ruleType == null) { |
| | | return null; |
| | | } |
| | | if (ruleType == 1) { |
| | | if (rule.getCountType() == null || rule.getCountRef() == null || rule.getCountNum() == null) { |
| | | return null; |
| | | } |
| | | // 加油频次(原有逻辑) |
| | | int limit = rule.getCountNum(); |
| | | int ref = rule.getCountRef(); |
| | | if (rule.getCountType() == 1) { |
| | |
| | | if (countNums.stream().anyMatch(n -> Integer.compare(n, limit) != ref)) { |
| | | return null; |
| | | } |
| | | ///////////////////////////// |
| | | } else { |
| | | return null; |
| | | } |
| | | } else if (ruleType == 2) { |
| | | // 加油趋势(新逻辑) |
| | | if (rule.getCountTrend() == null || rule.getCountNum() == null || rule.getHistoryMonths() == null || rule.getRecentMonths() == null) { |
| | | return null; |
| | | } |
| | | if (!checkTrend(rule, filterData)) { |
| | | return null; |
| | | } |
| | | } else { |
| | | return null; |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | |
| | | return rules.getClientName(); |
| | | } |
| | | |
| | | /** |
| | | * 趋势判断(使用配置的月数) |
| | | * @param rule 规则 |
| | | * @param dataList 数据列表 |
| | | * @return |
| | | */ |
| | | private boolean checkTrend(ClientConfig rule, List<T> dataList) { |
| | | if (dataList == null || dataList.isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | Byte countTrend = rule.getCountTrend(); |
| | | Integer countNum = rule.getCountNum(); |
| | | Integer historyMonths = rule.getHistoryMonths(); |
| | | Integer recentMonths = rule.getRecentMonths(); |
| | | if (countTrend == null || countNum == null || historyMonths == null || recentMonths == null) { |
| | | return false; |
| | | } |
| | | if (historyMonths <= 0 || recentMonths <= 0 || countNum <= 0) { |
| | | return false; |
| | | } |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate currentMonth = now.withDayOfMonth(1); |
| | | LocalDate recentStart = currentMonth.minusMonths(recentMonths - 1L); |
| | | LocalDate historyStart = recentStart.minusMonths(historyMonths); |
| | | LocalDate historyEnd = recentStart; |
| | | |
| | | Map<LocalDate, Integer> recentMonthCount = new LinkedHashMap<>(); |
| | | for (int i = 0; i < recentMonths; i++) { |
| | | LocalDate month = recentStart.plusMonths(i); |
| | | recentMonthCount.put(month, 0); |
| | | } |
| | | |
| | | Map<LocalDate, Integer> historyMonthCount = new LinkedHashMap<>(); |
| | | for (int i = 0; i < historyMonths; i++) { |
| | | LocalDate month = historyStart.plusMonths(i); |
| | | historyMonthCount.put(month, 0); |
| | | } |
| | | |
| | | for (T tmp : dataList) { |
| | | LocalDate month = timeVal.apply(tmp).withDayOfMonth(1); |
| | | if (recentMonthCount.containsKey(month)) { |
| | | recentMonthCount.put(month, recentMonthCount.get(month) + 1); |
| | | } |
| | | if (historyMonthCount.containsKey(month) && !month.isBefore(historyStart) && month.isBefore(historyEnd)) { |
| | | historyMonthCount.put(month, historyMonthCount.get(month) + 1); |
| | | } |
| | | } |
| | | |
| | | if (countTrend == 1) { |
| | | boolean historyStable = historyMonthCount.values().stream().allMatch(n -> n >= countNum); |
| | | boolean recentStable = recentMonthCount.values().stream().allMatch(n -> n >= countNum); |
| | | return historyStable && recentStable; |
| | | } else if (countTrend == 2) { |
| | | boolean historyStable = historyMonthCount.values().stream().allMatch(n -> n >= countNum); |
| | | boolean recentDecrease = recentMonthCount.values().stream().allMatch(n -> n < countNum); |
| | | return historyStable && recentDecrease; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |