package com.zteits.job.task.getfreeberths; import java.io.IOException; import java.time.Duration; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import com.alibaba.fastjson.JSON; import com.clouds.common.cache.park.ParkingLotCacheUtil; import com.zteits.clouds.api.apibase.constants.DataStatusEnum; import com.zteits.job.task.getfreeberths.base.ThirdFreeBerthServiceRoute; import com.zteits.job.task.getfreeberths.param.IarinParkInfo; import com.zteits.job.task.getfreeberths.param.UpdateFreeByIrainRes; import com.zteits.job.util.HttpClientTutorial; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import com.clouds.common.cache.park.ParkFreeBerthsCacheUtil; import com.xiaoleilu.hutool.util.CollectionUtil; import com.zteits.clouds.api.apibase.constants.SourceTypeEnum; import com.zteits.clouds.api.dto.order.parkorder.param.pushfreeberths.PushFreeBerthsChangeRequest; import com.zteits.clouds.api.dto.rocketmq.datacollection.freeberths.FreeBerthsChangeMsgVO; import com.zteits.job.dao.park.ParkFreeBerthDao; import com.zteits.job.dao.park.ParkingLotDao; import com.zteits.job.domain.ParkingLot; import com.zteits.job.domain.ParkingLotExample; import com.zteits.job.task.getfreeberths.param.GetRealFreeBerthsDO; import org.springframework.util.CollectionUtils; /** * 调用道闸接口,获取真实的空闲车位数 * .
* * Copyright: Copyright (c) 2017 zteits * * @ClassName: GetRealFreeBerthsJob * @Description: * @version: v1.0.0 * @author: zhaowg * @date: 2018年5月11日 下午5:47:42 * Modification History: * Date Author Version Description *---------------------------------------------------------* * 2018年5月11日 zhaowg v1.0.0 创建 */ @Component public class PublicGetRealFreeBerthsJob{ private static final Logger logger = LoggerFactory.getLogger(PublicGetRealFreeBerthsJob.class); //艾润北京西城空闲车位接口地址 @Value("${irain.bjxc.getfreeberthNum}") private String irainBjxcGetfreeberthNumUrl; @Autowired private ParkingLotDao parkingLotDao; @Autowired private ParkFreeBerthDao parkFreeBerthDao; @Autowired private Map thirdBerthServiceMap; /** * 间隔10秒执行一次 * * 2018年5月4日 zhaowg */ @Scheduled(fixedDelay=10000) public void execute(){ logger.info("查询道闸的停车场"); //数据来源类型:1-艾润;2-路测;3-捷商;4-南泽 ;5-共享车位,6:青岛 7:红门道闸 99:北京诱导bjpgis List sourceTypes = Stream.of(1,4,6,7,99).collect(Collectors.toList()); ParkingLotExample example = new ParkingLotExample(); example.createCriteria().andSourceTypeIn(sourceTypes).andDataStatusEqualTo(DataStatusEnum.DATA_STATUS_VALID.value()); List parkingLots = parkingLotDao.selectByExample(example); if(CollectionUtil.isEmpty(parkingLots)){ logger.info("没有满足条件的停车场"); return; } //北京诱导bjpgis单独处理 List bjpgisParks = parkingLots.stream().filter(item->item.getSourceType().intValue()==99).collect(Collectors.toList()); this.dealFreeBerthsForBjpgis(bjpgisParks); //其他道闸诱导处理 this.dealFreeBerths(parkingLots); } /** * 北京诱导bjpgis单独处理 * @param bjpgisParks */ private void dealFreeBerthsForBjpgis(List bjpgisParks) { if(CollectionUtil.isEmpty(bjpgisParks)){ return; } if(StringUtils.isBlank(irainBjxcGetfreeberthNumUrl)){ logger.error("北京西城获取空闲车位地址为空"); return; } LocalTime beginTime = LocalTime.now(); logger.info("开始调用北京西城艾润空闲车位接口更新空闲车位数。"+beginTime); String response = HttpClientTutorial.httpGetRequest(irainBjxcGetfreeberthNumUrl); logger.info("响应信息为:"+response); if(com.alibaba.dubbo.common.utils.StringUtils.isBlank(response)){ return; } UpdateFreeByIrainRes byIrainRes= JSON.parseObject(response, UpdateFreeByIrainRes.class); if(byIrainRes==null){ return; } if(!byIrainRes.getCode().equals("0") || CollectionUtils.isEmpty(byIrainRes.getList())){ return; } Map map = bjpgisParks.stream().collect(Collectors.toMap(ParkingLot::getPlOutNo, Function.identity(),(key1,key2)->key1)); List berthsChangeMsgVOs = new ArrayList<>(); for (IarinParkInfo iarinParkInfo : byIrainRes.getList()) { String plOutNo = "bjpgis_"+iarinParkInfo.getId(); if(!map.containsKey(plOutNo)){ continue; } String plNo = map.get(plOutNo).getPlNo(); Integer freeBerths = iarinParkInfo.getRemaind(); if(com.alibaba.dubbo.common.utils.StringUtils.isBlank(plNo)){ continue; } //判断空闲车位数是否发生变化了 Integer oldFreeBerths = ParkFreeBerthsCacheUtil.getFreeBerthsByPlNo(plNo); if(oldFreeBerths.intValue() == freeBerths.intValue()){ logger.info(plNo+"-原来空闲车位数:"+oldFreeBerths+"和新空闲车位数相等,无需处理"); continue; } //发生空闲车位变化消息 //更新缓存 FreeBerthsChangeMsgVO berthsChangeMsgVO = ParkFreeBerthsCacheUtil.setFreeBerthsByPlNo(plNo, freeBerths,freeBerths); berthsChangeMsgVOs.add(berthsChangeMsgVO); } PushFreeBerthsChangeRequest freeBerthsChangeMsgVO = new PushFreeBerthsChangeRequest(); freeBerthsChangeMsgVO.setBerthsChangeMsgVOs(berthsChangeMsgVOs ); freeBerthsChangeMsgVO.setSysCode("DATA-COLLECT"); //更新空闲车位数 parkFreeBerthDao.updateFreeBerthsByPlNo(freeBerthsChangeMsgVO); LocalTime endTime = LocalTime.now(); logger.info("调用北京西城艾润空闲车位接口结束,共耗时" + Duration.between(beginTime, endTime).getSeconds()); } private void dealFreeBerths(List parkingLots) { List berthsChangeMsgVOs = new ArrayList<>(); for (ParkingLot parkingLotDTO : parkingLots) { if(99 == parkingLotDTO.getSourceType().intValue()){ continue; } logger.info("开始查询停车场"+parkingLotDTO.getPlName()+"["+parkingLotDTO.getPlNo()+"]"); String plNo = parkingLotDTO.getPlNo(); GetRealFreeBerthsDO getRealFreeBerthsDO = queryFreeBerths(parkingLotDTO); if(getRealFreeBerthsDO == null){ continue; } //调用接口返回的真实空闲车位数,可能为负数或者超过总车位数 Integer realFreeBerths = StringUtils.isBlank(getRealFreeBerthsDO.getFreeParkingSpace())?0:Integer.valueOf(getRealFreeBerthsDO.getFreeParkingSpace()); //修改后的空闲车位数,最小0,最大不超过总车位数 Integer freeBerths = realFreeBerths; //判断数据有效性 if(freeBerths<0){ logger.info("返回的空闲车位数小于0,修改为0"); freeBerths = 0; }else if(freeBerths>parkingLotDTO.getPlBerthNum()){ logger.info("返回的空闲车位数大于总车位数"+parkingLotDTO.getPlBerthNum()+",修改为总车位数"); freeBerths = parkingLotDTO.getPlBerthNum(); } //判断缓存中空闲车位数是否发生变化了 FreeBerthsChangeMsgVO freeBerthsChangeMsgVO = ParkFreeBerthsCacheUtil.getFreeBerthsObjectByPlNo(plNo); if(freeBerthsChangeMsgVO==null){ continue; } if(freeBerthsChangeMsgVO.getRealFreeBerths() != realFreeBerths){ logger.info(plNo+"-原来真实空闲车位数:"+freeBerthsChangeMsgVO.getRealFreeBerths()+",新真实空闲车位数:"+realFreeBerths+",新空闲车位数:"+freeBerths); //更新缓存 freeBerthsChangeMsgVO = ParkFreeBerthsCacheUtil.setFreeBerthsByPlNo(plNo, freeBerths,realFreeBerths); } berthsChangeMsgVOs.add(freeBerthsChangeMsgVO); if(SourceTypeEnum.NAN_ZHE.getValue().equals(parkingLotDTO.getSourceType())){ //南泽的总车位数不正确 continue; } //判断总车位数是否一致 Integer plBerthNum = StringUtils.isBlank(getRealFreeBerthsDO.getTotalParkingSpace())?0:Integer.valueOf(getRealFreeBerthsDO.getTotalParkingSpace()); if(!plBerthNum.equals(parkingLotDTO.getPlBerthNum()) && plBerthNum.intValue()>0){ logger.debug(parkingLotDTO.getPlName()+",总车位数:"+parkingLotDTO.getPlBerthNum()+"与接口返回的不一致,更新总车位数为"+plBerthNum); parkingLotDao.updateTotalBerths(plNo,plBerthNum); } } if(CollectionUtil.isEmpty(berthsChangeMsgVOs)){ return; } PushFreeBerthsChangeRequest freeBerthsChangeMsgVO = new PushFreeBerthsChangeRequest(); freeBerthsChangeMsgVO.setBerthsChangeMsgVOs(berthsChangeMsgVOs ); freeBerthsChangeMsgVO.setSysCode("XXL-JOB"); //更新空闲车位数 parkFreeBerthDao.updateFreeBerthsByPlNo(freeBerthsChangeMsgVO); } /** * 调用第三方接口查询空闲车位数 * @throws IOException * 2018年5月11日 zhaowg */ private GetRealFreeBerthsDO queryFreeBerths(ParkingLot parkingLot){ try{ /**根据数据来源路由具体的通知服务*/ CallThirdQueryFreeBerthService queryThirdBerthInfoService = ThirdFreeBerthServiceRoute .selectThirdBerthService(SourceTypeEnum.getEnumByValue(parkingLot.getSourceType()), thirdBerthServiceMap); /**根据数据来源类型,查询第三方空闲车位数*/ return queryThirdBerthInfoService.queryFreeBerths(parkingLot); }catch (Exception e){ logger.error("处理错误",e); } return null; } }