package com.zteits.park.biz;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.clouds.common.constants.ParkLotEnum;
import com.clouds.common.utils.ListPageHelper;
import com.zteits.clouds.api.apibase.bean.BizResult;
import com.zteits.clouds.api.apibase.constants.ErrorType;
import com.zteits.clouds.api.apibase.constants.LonLatTypeEnum;
import com.zteits.clouds.api.apibase.exception.BizException;
import com.zteits.clouds.api.dto.govclouds.dto.ParkingCountForTypeDTO;
import com.zteits.clouds.api.dto.govclouds.dto.ParkingTrack;
import com.zteits.clouds.api.dto.govclouds.dto.ParkingTrackDTO;
import com.zteits.clouds.api.dto.govclouds.param.QueryParkingCountRequest;
import com.zteits.clouds.api.dto.govclouds.param.QueryParkingTrackRequest;
import com.zteits.clouds.api.service.govclouds.ParkPreferenceService;
import com.zteits.park.constant.ParkConstant;
import com.zteits.park.dao.InParkLogDao;
import com.zteits.park.dao.ParkingLotDao;
import com.zteits.park.dao.ParkingLotGeoDao;
import com.zteits.park.domain.InparkLogCountDO;
import com.zteits.park.domain.InparkLogVplNumberDO;
import com.zteits.park.domain.ParkingLot;
import com.zteits.park.domain.ParkingLotAndGeoDO;
import com.zteits.park.domain.ParkingLotGeo;
import com.zteits.park.domain.ParkinglotHeatmapHour;
@Service("com.zteits.park.biz.ParkPreferenceServiceImpl")
public class ParkPreferenceServiceImpl implements ParkPreferenceService {
private static final Logger logger = LoggerFactory.getLogger(ParkPreferenceServiceImpl.class);
@Autowired
private InParkLogDao inParkLogDao;
@Autowired
private ParkingLotDao parkingLotDao;
@Autowired
private ParkingLotGeoDao parkingLotGeoDao;
/**
* 通过停车场类型(1:路内(占用道路停车位),2-路外) 查询某个时间段停车次数(饼图).
* 步骤:1.查询停车场基本信息.
* 2:查询各个停车场进场次数.
* 3.根据类型组合数据.
* @param queryParkingCountRequest
* @throws Exception
*/
@Override
public BizResult> queryParkingCountForPlType(QueryParkingCountRequest queryParkingCountRequest)
throws Exception {
List list = new ArrayList();
List resultList = new ArrayList();
if(queryParkingCountRequest != null ){
/**1.通过省份,城市ID获取停车场信息.*/
list = parkingLotDao.queryParkLotByProvAndCity(queryParkingCountRequest.getProvId(),queryParkingCountRequest.getCityId(),ParkConstant.state.USED);
//获取list中的停车场编码
List plNos = this.getplNos(list);
/**2.查询某个时间段停车场进场车辆数.*/
List InparkList = this.queryParklotInCarCount(queryParkingCountRequest.getBeginTime(), queryParkingCountRequest.getEndTime(), plNos);
//合并list
resultList = this.megerList(list, InparkList);
//获取最终结果
this.sum(resultList);
}else{
logger.info("入参不能为空!");
throw new BizException(ErrorType.PARAMM_NULL, "入参不能为空!");
}
return new BizResult>(resultList);
}
/**
* 获取最终结果.
* @param resultList
*/
private void sum(List resultList){
logger.info("---begin开始获取最终结果...");
//路内停车场停车次数
int sumPltype1 = 0;
//路外停车场停车次数
int sumPltype2 = 0;
ParkingCountForTypeDTO[] inparkingCountForTypeDTO = new ParkingCountForTypeDTO[2];
if(!CollectionUtils.isEmpty(resultList)){
inparkingCountForTypeDTO[0] = new ParkingCountForTypeDTO();
inparkingCountForTypeDTO[0].setPlProvinceId(resultList.get(0).getPlProvinceId());
inparkingCountForTypeDTO[0].setPlProvinceName(resultList.get(0).getPlProvinceName());
inparkingCountForTypeDTO[0].setPlCityId(resultList.get(0).getPlCityId());
inparkingCountForTypeDTO[0].setPlCityName(resultList.get(0).getPlCityName());
inparkingCountForTypeDTO[0].setPlType(ParkLotEnum.PL_TYPE_1.getValue());
inparkingCountForTypeDTO[0].setPlTypeName(ParkLotEnum.PL_TYPE_1.getDesc());
inparkingCountForTypeDTO[1] = new ParkingCountForTypeDTO();
inparkingCountForTypeDTO[1].setPlProvinceId(resultList.get(0).getPlProvinceId());
inparkingCountForTypeDTO[1].setPlProvinceName(resultList.get(0).getPlProvinceName());
inparkingCountForTypeDTO[1].setPlCityId(resultList.get(0).getPlCityId());
inparkingCountForTypeDTO[1].setPlCityName(resultList.get(0).getPlCityName());
inparkingCountForTypeDTO[1].setPlType(ParkLotEnum.PL_TYPE_2.getValue());
inparkingCountForTypeDTO[1].setPlTypeName(ParkLotEnum.PL_TYPE_2.getDesc());
//sum
for(ParkingCountForTypeDTO parkingCountForTypeDTO:resultList){
if(parkingCountForTypeDTO != null){
if(ParkLotEnum.PL_TYPE_1.getValue() == parkingCountForTypeDTO.getPlType()){
sumPltype1 +=parkingCountForTypeDTO.getCurrentParkCount();
}
if(ParkLotEnum.PL_TYPE_2.getValue() == parkingCountForTypeDTO.getPlType()){
sumPltype2 +=parkingCountForTypeDTO.getCurrentParkCount();
}
}
}
logger.info("路内停车场停车次数="+sumPltype1);
logger.info("路外停车场停车次数="+sumPltype2);
//放入停车次数
inparkingCountForTypeDTO[0].setCurrentParkCount(sumPltype1);
inparkingCountForTypeDTO[1].setCurrentParkCount(sumPltype2);
resultList.clear();
logger.info("清空resultList");
for(ParkingCountForTypeDTO dto:inparkingCountForTypeDTO){
resultList.add(dto);
}
}
logger.info("---end开始获取最终结果...,结果="+JSONObject.toJSONString(resultList));
}
/**
* 合并list.
* @param list
* @param InparkList
* @return
*/
private List megerList(List list,List InparkList){
logger.info("---begin开始合并list...");
List returnList = new ArrayList();
Map busiCircle = this.getBusiCircle();
if(!CollectionUtils.isEmpty(list)){
for(ParkingLot parkingLot :list){
if(parkingLot != null){
ParkingCountForTypeDTO parkCountForTypeDTO = new ParkingCountForTypeDTO();
parkCountForTypeDTO.setPlProvinceId(parkingLot.getPlProvinceId());
parkCountForTypeDTO.setPlProvinceName(parkingLot.getPlProvinceName());
parkCountForTypeDTO.setPlCityId(parkingLot.getPlCityId());
parkCountForTypeDTO.setPlCityName(parkingLot.getPlCityName());
parkCountForTypeDTO.setPlType(parkingLot.getPlType());
if(parkingLot.getPlType() != null && ParkLotEnum.PL_TYPE_1.getValue() == parkingLot.getPlType()){
parkCountForTypeDTO.setPlTypeName(ParkLotEnum.PL_TYPE_1.getDesc());
}else{
parkCountForTypeDTO.setPlTypeName(ParkLotEnum.PL_TYPE_2.getDesc());
}
parkCountForTypeDTO.setBusiCircle(parkingLot.getBusiCircle());
if(parkingLot.getBusiCircle() != null){
parkCountForTypeDTO.setBusiCircleName(busiCircle.get(parkingLot.getBusiCircle()));
}
parkCountForTypeDTO.setPlNo(parkingLot.getPlNo());
parkCountForTypeDTO.setPlName(parkingLot.getPlName());
parkCountForTypeDTO.setCurrentParkCount(0);
if(!CollectionUtils.isEmpty(InparkList)){
for(InparkLogCountDO inparkLogCountDO :InparkList){
if(inparkLogCountDO != null && inparkLogCountDO.getPlNo().equals(parkingLot.getPlNo())){
parkCountForTypeDTO.setCurrentParkCount(inparkLogCountDO.getCurrentParkCount());
}
}
}
returnList.add(parkCountForTypeDTO);
}
}//for
}
logger.info("---end开始合并list...,结果="+JSONObject.toJSON(returnList));
return returnList;
}
/**
* 查询进场车辆数.
* @param beginTime
* @param endTime
* @param plNos
* @return
*/
private List queryParklotInCarCount(Date beginTime, Date endTime,List plNos){
SimpleDateFormat formart = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
logger.info("---begin查询进场车辆数,入参={beginTime="+formart.format(beginTime)+",endTime="+formart.format(endTime)+",plNos="+plNos+"}");
List inparkList = new ArrayList();
if(!CollectionUtils.isEmpty(plNos)){
ListPageHelper pageInfo = new ListPageHelper(plNos,500);
for(int i=1;i<=pageInfo.getTotalPages();i++){
System.out.println(JSONObject.toJSON(pageInfo.getPagedList(i)));
List list = inParkLogDao.queryParklotInCar(beginTime, endTime, pageInfo.getPagedList(i));
if(!CollectionUtils.isEmpty(list)){
inparkList.addAll(list);
}
}
}
logger.info("---end查询进场车辆数,结果 inparkList="+JSONObject.toJSONString(inparkList));
return inparkList;
}
/**
* 获取list中的停车场编码.
* @param list
* @return
*/
private List getplNos(List list){
List plNoList = new ArrayList();
if(!CollectionUtils.isEmpty(list)){
for(ParkingLot parkingLot :list){
if(parkingLot != null && StringUtils.isNotEmpty(parkingLot.getPlNo())){
plNoList.add(parkingLot.getPlNo());
}
}
}
logger.info("获取停车场编码list="+JSONObject.toJSONString(plNoList));
return plNoList;
}
//获取商圈属性类型
public Map getBusiCircle(){
String busiCircle = ParkLotEnum.BUSI_CIRCLE.getDesc();
Map map = new HashMap();
String[] arr = busiCircle.split(",");
for(String str :arr){
String[] stri = str.split(":");
map.put(Integer.valueOf(stri[0]), stri[1]);
}
return map;
}
@Override
public BizResult> queryParkingBusiCircleForPlType(
QueryParkingCountRequest queryParkingCountRequest) throws Exception {
List list = new ArrayList();
List resultList = new ArrayList();
if(queryParkingCountRequest != null ){
/**1.通过省份,城市ID获取停车场信息.*/
list = parkingLotDao.queryParkLotByProvAndCity(queryParkingCountRequest.getProvId(),queryParkingCountRequest.getCityId(),ParkConstant.state.USED);
//获取list中的停车场编码
List plNos = this.getplNos(list);
/**2.查询某个时间段停车场进场车辆数.*/
List InparkList = this.queryParklotInCarCount(queryParkingCountRequest.getBeginTime(), queryParkingCountRequest.getEndTime(), plNos);
//合并list
resultList = this.megerList(list, InparkList);
//获取最终结果
this.sumAndBate(resultList);
}else{
logger.info("入参不能为空!");
throw new BizException(ErrorType.PARAMM_NULL, "入参不能为空!");
}
return new BizResult>(resultList);
}
/**
* 获取最终结果.
* @param resultList
*/
private void sumAndBate(List resultList){
logger.info("---begin开始获取最终结果...");
//总数
Integer busiCircleSum = 0;
List countList = new ArrayList();
Map busiCircle = this.getBusiCircle(); //商圈属性
for (Map.Entry entry : busiCircle.entrySet()) {
ParkingCountForTypeDTO parkingCountDTO = new ParkingCountForTypeDTO();
parkingCountDTO.setBusiCircle(entry.getKey());
parkingCountDTO.setBusiCircleName(entry.getValue());
countList.add(parkingCountDTO);
}
//初始化属性对应的停车数量
Map busiCircleCount = new HashMap();
for (Map.Entry entry : busiCircle.entrySet()) {
busiCircleCount.put(entry.getKey(), 0);
}
if(!CollectionUtils.isEmpty(resultList)){
for (Map.Entry entry : busiCircle.entrySet()) {
for(ParkingCountForTypeDTO parkingCountForTypeDTO:resultList){
if(parkingCountForTypeDTO != null){
if(entry.getKey() == parkingCountForTypeDTO.getBusiCircle()){
busiCircleCount.put(entry.getKey(), busiCircleCount.get(entry.getKey())
+parkingCountForTypeDTO.getCurrentParkCount());
busiCircleSum += parkingCountForTypeDTO.getCurrentParkCount(); //总数
}
}
}
}
//放入停车场商圈属性对应的停车数量和比例
for(ParkingCountForTypeDTO parkDTO :countList){
for (Map.Entry entry : busiCircleCount.entrySet()) {
if(parkDTO.getBusiCircle() == entry.getKey()){
parkDTO.setCurrentParkCount(entry.getValue());
if(0 == busiCircleSum){
parkDTO.setCurrentParkBate(new BigDecimal("0"));
}else{
parkDTO.setCurrentParkBate(new BigDecimal(entry.getValue()).divide(new BigDecimal(busiCircleSum), 2, 4));
}
}
}
}
}
resultList.removeAll(resultList);
resultList.addAll(countList);
logger.info("---end开始获取最终结果...,结果="+JSONObject.toJSONString(resultList));
}
@Override
public BizResult queryParkingTrack(QueryParkingTrackRequest request) {
ParkingTrackDTO parkingTrackDTO = new ParkingTrackDTO();
List list = new ArrayList();
if(request != null ){
/**1.通过省份,城市ID获取停车场信息.*/
ParkingLotAndGeoDO parkingLotAndGeoDO = new ParkingLotAndGeoDO();
parkingLotAndGeoDO.setPlProvinceId(request.getProvId());
parkingLotAndGeoDO.setPlCityId(request.getCityId());
logger.info("---begin查询停车场信息,入参={}",JSONObject.toJSON(parkingLotAndGeoDO));
list = parkingLotDao.queryParkingLotAndGeoInfo(parkingLotAndGeoDO);
logger.info("---end查询停车场信息,结果list.size()={}",(list != null && list.size() >0) ? list.size() :0);
//获取list中的停车场编码
List plNos = this.getParkNos(list);
logger.info("---begin查询停车场经纬度list={}",(plNos != null ? plNos.size() :0));
/**根据停车场编码查询停车场经纬度-list.*/
Map> lotlatList = parkingLotGeoDao.queryParkingLotGeoListByParkNos(plNos,1,LonLatTypeEnum.LON_LAT_TYPE_1.value());
logger.info("---end结束查询停车场经纬度信息...结果="+JSONObject.toJSONString(lotlatList));
/**查询车牌号对应记录的最大值.*/
Integer num = inParkLogDao.queryMaxNum(request.getBeginTime(),request.getEndTime(),request.getVplNumber(),plNos);
logger.info("---停车最大次数={}",(num != null ? num :0));
logger.info("---begin开始查询各个车牌入场时间...");
/**2.查询车牌号对应的停车场和入场时间信息*/
List inparkList = inParkLogDao.queryParklotInCarTime(request.getBeginTime(),request.getEndTime(),request.getVplNumber(),plNos);
logger.info("---end开始查询各个车牌入场时间...,结果={}",JSONObject.toJSON(inparkList));
//合并list
Map> map = mergeLotLatToinParkLogList(lotlatList, inparkList);
parkingTrackDTO.setMaxColumn(num);
parkingTrackDTO.setParkingTrackMap(map);
}else{
logger.info("入参不能为空!");
throw new BizException(ErrorType.PARAMM_NULL, "入参不能为空!");
}
return new BizResult(parkingTrackDTO);
}
/**
* 将经纬度list和进车上报list合并map.
* @param lotlatList
* @param inparkList
* @return
*/
private Map> mergeLotLatToinParkLogList(Map> lotlatList,List inparkList){
Map> map = new HashMap>();
List list = new ArrayList();
logger.info("---begin合并list形成map...");
if(!CollectionUtils.isEmpty(lotlatList) && !CollectionUtils.isEmpty(inparkList)){
for(InparkLogVplNumberDO inparkLogVplNumberDO :inparkList){
if(inparkLogVplNumberDO != null){
ParkingTrack parkingTrack = new ParkingTrack();
if(inparkLogVplNumberDO.getInTime() != null){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
parkingTrack.setInTime(format.format(inparkLogVplNumberDO.getInTime()));
}else{
parkingTrack.setInTime(null);
}
/** irain有虚拟车牌 如果车牌长度大于10 则截取前面10位*/
parkingTrack.setVplNumber(inparkLogVplNumberDO.getVplNumber().length()<=10?inparkLogVplNumberDO.getVplNumber():(inparkLogVplNumberDO.getVplNumber().substring(0,10)));
List parkingLotGeos = lotlatList.get(inparkLogVplNumberDO.getPlNo());
Optional.ofNullable(parkingLotGeos).ifPresent(geos->{
if(geos.size()==0){
return;
}
parkingTrack.setLat(geos.get(0).getLatId());
parkingTrack.setLon(geos.get(0).getLonId());
list.add(parkingTrack);
});
}
}
}
//放入map key=vplNumber
if(!CollectionUtils.isEmpty(list)){
for(ParkingTrack parkingTrack:list){
if(parkingTrack != null){
if(map.containsKey(parkingTrack.getVplNumber())){
map.get(parkingTrack.getVplNumber()).add(parkingTrack);
}else{
List listToMap = new ArrayList();
listToMap.add(parkingTrack);
map.put(parkingTrack.getVplNumber(),listToMap );
}
}
}
}
logger.info("---end合并list形成map,结果={}",JSONObject.toJSON(map));
logger.info("---end合并list形成map.size(),结果={}",map.size());
return map;
}
/**
* 获取list中的停车场编码.
* @param list
* @return
*/
private List getParkNos(List list){
List plNoList = new ArrayList();
if(!CollectionUtils.isEmpty(list)){
for(ParkinglotHeatmapHour parkingLot :list){
if(parkingLot != null && StringUtils.isNotEmpty(parkingLot.getPlNo())){
plNoList.add(parkingLot.getPlNo());
}
}
}
logger.info("获取停车场编码list="+JSONObject.toJSONString(plNoList));
return plNoList;
}
}