|
@@ -2,12 +2,12 @@ package org.springblade.business.service.impl;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.hankcs.hanlp.dictionary.py.Pinyin;
|
|
|
import com.hankcs.hanlp.dictionary.py.PinyinDictionary;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
import org.jsoup.Connection;
|
|
|
import org.jsoup.Jsoup;
|
|
|
import org.jsoup.nodes.Document;
|
|
@@ -20,22 +20,23 @@ import org.springblade.business.mapper.WeatherInfoMapper;
|
|
|
import org.springblade.business.service.WeatherInfoService;
|
|
|
//import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springblade.core.tool.utils.Func;
|
|
|
+import org.springblade.manager.entity.ContractInfo;
|
|
|
import org.springblade.manager.entity.ProjectContractArea;
|
|
|
import org.springblade.manager.entity.ProjectInfo;
|
|
|
import org.springblade.manager.feign.ProjectClient;
|
|
|
import org.springblade.manager.feign.ProjectContractAreaClient;
|
|
|
+import org.springblade.manager.vo.ContractInfoVO;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springblade.core.mp.support.Condition;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.time.Duration;
|
|
|
-import java.time.Instant;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.time.ZoneId;
|
|
|
+import java.time.*;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
@@ -232,6 +233,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
|
|
|
weatherMap = this.getWeather(county.toString(), plainTime.format(DateTimeFormatter.ofPattern("yyyyMM")));
|
|
|
if (weatherMap == null || weatherMap.get(plainTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))) == null) {
|
|
|
weatherMap = this.getWeather(city.toString(), plainTime.format(DateTimeFormatter.ofPattern("yyyyMM")));
|
|
|
+ county = city;
|
|
|
if (weatherMap == null || weatherMap.get(plainTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))) == null) {
|
|
|
log.info("获取历史天气失败!contractAreaId:" + projectContractArea.getId() + ",syncTime:" + plainTime);
|
|
|
break;
|
|
@@ -254,6 +256,133 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
|
|
|
|
|
|
}
|
|
|
|
|
|
+ //去除重复天气,并填充每个合同段缺失的天气
|
|
|
+ @Scheduled(cron = "0 0 9 * * ?")
|
|
|
+ public void scanMissWeather(){
|
|
|
+ //获取所有项目的合同段
|
|
|
+ List<ContractInfoVO> contractInfos = baseMapper.getAllContract();
|
|
|
+ for (ContractInfoVO contract : contractInfos) {
|
|
|
+ //获取合同段的区域信息
|
|
|
+ ProjectContractArea area = baseMapper.selectAreaIdByContractId(contract.getId());
|
|
|
+ if (area == null || StringUtils.isBlank(area.getCounty()) || StringUtils.isBlank(area.getCity())){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<Pinyin> py = PinyinDictionary.convertToPinyin(area.getCounty().substring(0, area.getCounty().length() - 1));
|
|
|
+ StringBuilder county = new StringBuilder();
|
|
|
+ for (int i = 0; i < py.size(); i++) {
|
|
|
+ county.append(py.get(i).getPinyinWithoutTone());
|
|
|
+ }
|
|
|
+ List<Pinyin> py2 = PinyinDictionary.convertToPinyin(area.getCity().substring(0, area.getCity().length() - 1));
|
|
|
+ StringBuilder city = new StringBuilder();
|
|
|
+ for (int i = 0; i < py2.size(); i++) {
|
|
|
+ city.append(py2.get(i).getPinyinWithoutTone());
|
|
|
+ }
|
|
|
+ //获取当前合同下所有重复的天气id,根据区域id
|
|
|
+ List<Long> ids = new ArrayList<>();
|
|
|
+ ids = baseMapper.getRepetitionId(area.getId());
|
|
|
+ while (ids.size() > 0){
|
|
|
+ //为单个合同段去除重复天气,根据天气id集合
|
|
|
+ System.out.println(contract.getProjectName()+":"+contract.getContractName()+"重复日期:"+ids.size()+"条");
|
|
|
+ Integer total = baseMapper.deWeightWeather(ids);
|
|
|
+ System.out.println(contract.getProjectName()+":"+contract.getContractName()+"删除重复日期:"+total+"条");
|
|
|
+ ids = baseMapper.getRepetitionId(area.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ //补全缺失的天气
|
|
|
+ List<LocalDate> missDate = new ArrayList<>();
|
|
|
+ //获取当前合同段所有天气,并且按照日期排序
|
|
|
+ List<LocalDate> allDate = baseMapper.getAllWeatherByAreaId(area.getId());
|
|
|
+ //如果没有获取到天气则直接跳过
|
|
|
+ if (allDate.size() == 0){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //判断最小日期是否小于当前日期
|
|
|
+ if (LocalDate.now().compareTo(allDate.get(0)) < 1){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //循环结合,遗漏日期添加进集合
|
|
|
+ for (int i = 0; i < allDate.size()-1; i++) {
|
|
|
+ LocalDate today = allDate.get(i);
|
|
|
+ LocalDate tomorrow = allDate.get(i+1);
|
|
|
+ while (!today.plusDays(1).equals(tomorrow)){
|
|
|
+ missDate.add(today.plusDays(1));
|
|
|
+ today = today.plusDays(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //判断是否有遗漏
|
|
|
+ if (missDate.size() == 0){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Map<String, Map<String, String>> weatherMap = null;
|
|
|
+ List<WeatherInfo> list = new ArrayList<>();
|
|
|
+ ZoneId zone = ZoneId.systemDefault();
|
|
|
+ //遗漏日期根据年月分组
|
|
|
+ Map<String, List<LocalDate>> map = missDate.stream().collect(Collectors.groupingBy(l -> l.format(DateTimeFormatter.ofPattern("yyyyMM"))));
|
|
|
+ for (String s : map.keySet()) {
|
|
|
+ //获取整月天气
|
|
|
+ weatherMap = this.getWeather(county.toString(), s);
|
|
|
+ if (weatherMap == null || weatherMap.size() == 0) {
|
|
|
+ weatherMap = this.getWeather(city.toString(), s);
|
|
|
+ county = city;
|
|
|
+ if (weatherMap == null || weatherMap.size() == 0) {
|
|
|
+ log.info("获取历史天气失败:" + area.getCity()+"-"+area.getCounty() + ",syncTime:" + s);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //为遗漏日期设置天气
|
|
|
+ List<LocalDate> dates = map.get(s);
|
|
|
+ for (LocalDate date : dates) {
|
|
|
+ Map<String, String> day = weatherMap.get(date.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
|
|
|
+ if (day == null || day.size() == 0){
|
|
|
+ log.info("从整月天气中获取当天失败:" + area.getCity()+"-"+area.getCounty() + ",syncTime:" + date);
|
|
|
+ }
|
|
|
+ //计算平均气温
|
|
|
+ BigDecimal aver = (new BigDecimal(day.get("high")).add(new BigDecimal(day.get("low")))).divide(new BigDecimal("2"), 1, BigDecimal.ROUND_HALF_UP);
|
|
|
+ WeatherInfo newWeather = new WeatherInfo(String.valueOf(area.getId()), day.get("weather"), aver.toString(), day.get("high"), day.get("low"), day.get("windLevel"));
|
|
|
+ newWeather.setRecordTime(Date.from(date.atStartOfDay().atZone(zone).toInstant()));
|
|
|
+ list.add(newWeather);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ //保存进天气表
|
|
|
+ this.saveBatch(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("同步天气完成");
|
|
|
+
|
|
|
+ }
|
|
|
+ //测试循环
|
|
|
+ public void test7(){
|
|
|
+ List<LocalDate> missDate = new ArrayList<>();
|
|
|
+ //获取当前合同段所有天气,并且按照日期排序
|
|
|
+ List<LocalDate> allDate = baseMapper.getAllWeatherByAreaId(1697501022614122498L);
|
|
|
+ //如果没有获取到天气则直接跳过
|
|
|
+ if (allDate.size() == 0){
|
|
|
+ System.out.println("111");
|
|
|
+ }
|
|
|
+ //判断最小日期是否小于当前日期
|
|
|
+ if (LocalDate.now().compareTo(allDate.get(0)) < 1){
|
|
|
+ System.out.println(222);
|
|
|
+ }
|
|
|
+ //循环结合,遗漏日期添加进集合
|
|
|
+ for (int i = 0; i < allDate.size()-1; i++) {
|
|
|
+ LocalDate today = allDate.get(i).plusDays(1);
|
|
|
+ LocalDate tomorrow = allDate.get(i+1);
|
|
|
+ while (!today.equals(tomorrow)){
|
|
|
+ if (today.compareTo(tomorrow) == 1){
|
|
|
+ System.out.println(today);
|
|
|
+ }
|
|
|
+ missDate.add(today);
|
|
|
+ today = today.plusDays(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //判断是否有遗漏
|
|
|
+ if (missDate.size() == 0){
|
|
|
+ System.out.println(88888);
|
|
|
+ }
|
|
|
+ System.out.println("9999");
|
|
|
+ }
|
|
|
+
|
|
|
public Map<String, Map<String, String>> getWeather(String city, String month) {
|
|
|
String html = "http://www.tianqihoubao.com/lishi/" + city + "/month/" + month + ".html";
|
|
|
Map<String, Map<String, String>> map = new HashMap<>();
|
|
@@ -261,7 +390,8 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
|
|
|
try {
|
|
|
System.out.println(html);
|
|
|
Connection connect = Jsoup.connect(html);
|
|
|
- connect.timeout(20000);
|
|
|
+ connect.timeout(10000);
|
|
|
+ connect.userAgent("Chrome");
|
|
|
document = connect.get();
|
|
|
Element body = document.body();
|
|
|
Elements table = body.getElementsByTag("table");
|
|
@@ -285,6 +415,8 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+
|
|
|
}
|
|
|
return map;
|
|
|
}
|