PublicGetRealFreeBerthsJob.java 9.49 KB
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;

/**
 * 调用道闸接口,获取真实的空闲车位数
 * .<br/>
 *
 * 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<String,CallThirdQueryFreeBerthService> thirdBerthServiceMap;
	/**
	 * 间隔10秒执行一次
	 *
	 * 2018年5月4日 zhaowg
	 */
	@Scheduled(fixedDelay=10000)
	public void execute(){
		logger.info("查询道闸的停车场");
		//数据来源类型:1-艾润;2-路测;3-捷商;4-南泽 ;5-共享车位,6:青岛 7:红门道闸  99:北京诱导bjpgis
		List<Integer> 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<ParkingLot> parkingLots = parkingLotDao.selectByExample(example);
		if(CollectionUtil.isEmpty(parkingLots)){
			logger.info("没有满足条件的停车场");
			return;
		}

		//北京诱导bjpgis单独处理
		List<ParkingLot> 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<ParkingLot> 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<String,ParkingLot> map = bjpgisParks.stream().collect(Collectors.toMap(ParkingLot::getPlOutNo, Function.identity(),(key1,key2)->key1));
		List<FreeBerthsChangeMsgVO> 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<ParkingLot> parkingLots) {
		List<FreeBerthsChangeMsgVO> 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;
	}

}