ParkingLotServiceImpl.java 16.7 KB
package com.zteits.park.biz;

import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.clouds.common.cache.park.ParkFreeBerthsCacheUtil;
import com.clouds.common.cache.park.ParkingLotCacheUtil;
import com.clouds.common.cache.park.ParkingLotGeoCacheUtil;
import com.clouds.common.cache.sys.TbAreaCacheUtil;
import com.clouds.common.utils.*;
import com.github.pagehelper.PageInfo;
import com.zteits.clouds.api.apibase.bean.BizResult;
import com.zteits.clouds.api.apibase.bean.PageBean;
import com.zteits.clouds.api.apibase.constants.BasicEnum;
import com.zteits.clouds.api.apibase.constants.DataStatusEnum;
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.order.parkorder.param.pushfreeberths.PushFreeBerthsChangeRequest;
import com.zteits.clouds.api.dto.park.dto.ParkingLotDTO;
import com.zteits.clouds.api.dto.park.param.*;
import com.zteits.clouds.api.dto.pay.PlNameDTO;
import com.zteits.clouds.api.dto.pay.TdBTempParklotDTO;
import com.zteits.clouds.api.dto.pay.param.ChangeBlockForParkLotRequest;
import com.zteits.clouds.api.dto.pay.param.CheckUniqueForPlNameRequest;
import com.zteits.clouds.api.dto.pay.param.ParkTempInfoPageQueryRequest;
import com.zteits.clouds.api.dto.rocketmq.constants.MQTopicConstants;
import com.zteits.clouds.api.dto.rocketmq.constants.tags.DataCollectionTags;
import com.zteits.clouds.api.dto.rocketmq.constants.tags.ParkTags;
import com.zteits.clouds.api.dto.rocketmq.datacollection.freeberths.FreeBerthsChangeMsgVO;
import com.zteits.clouds.api.dto.rocketmq.park.parklot.ParkingLotSuccessMsgVO;
import com.zteits.clouds.api.dto.syncdata.dto.GetParkingLotsDTO;
import com.zteits.clouds.api.dto.sys.AreaTreeDTO;
import com.zteits.clouds.api.dto.sys.TbAreaDTO;
import com.zteits.clouds.api.service.order.parkorder.oper.FreeBerthsPushOperService;
import com.zteits.clouds.api.service.park.ParkingLotQueryService;
import com.zteits.clouds.api.service.park.ParkingLotService;
import com.zteits.park.constant.ParkConstant;
import com.zteits.park.dao.ParkingLotDao;
import com.zteits.park.dao.ParkingLotGeoDao;
import com.zteits.park.domain.AreaTreeDO;
import com.zteits.park.domain.ParkingLot;
import com.zteits.park.domain.ParkingLotGeo;
import com.zteits.park.pagepager.PageBeanUtil;
import com.zteits.park.service.berths.oper.ParkFreeBerthOperInnerService;
import com.zteits.park.service.syncdata.oper.ParkBaseDataSyncInnerService;
import zteits.rocketmq.spring.starter.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class ParkingLotServiceImpl implements ParkingLotService {
    private static final Logger logger = LoggerFactory.getLogger(ParkingLotServiceImpl.class);
    //单次同步最大条数
    @Value("${sync.parkinglot.maxnum}")
    private Integer syncMaxNum;
    @Autowired
    private ParkingLotDao parkingLotDao;
    @Autowired
    private ParkingLotGeoDao parkingLotGeoDao;
    @Autowired
    private ParkingLotQueryService parkingLotQueryService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ParkFreeBerthOperInnerService parkFreeBerthBizService;
    @Autowired
    private FreeBerthsPushOperService freeBerthsPushOperService;
    @Autowired
    private ParkFreeBerthOperInnerService freeBerthOperInnerService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BizResult<ParkingLotDTO> SaveParkingLotInfo(ParkingLotInfoSaveRequest request) {
        ParkingLotDTO dto = new ParkingLotDTO();
        BeanValidatorsUtils.validateWithException(request);
        //生成停车场编码
//        TbAreaDTO areaDTO = TbAreaCacheUtil.getTbAreaById(request.getPlCountryId());
        String parkCode = this.generatorParkNo(request.getState());

        //插入停车场信息表
        ParkingLot parkingLot = new ParkingLot();
        BeanUtils.copyProperties(request, parkingLot);
        parkingLot.setPlNo(parkCode);
        parkingLot.setDataStatus(DataStatusEnum.DATA_STATUS_VALID.value());
        parkingLot.setCreateTime(new Date());
        int flag = parkingLotDao.insertSelective(parkingLot);
        /**加入缓存.*/
        if(flag >0){
        	ParkingLotDTO parkingLotDTO = new ParkingLotDTO();
        	BeanUtils.copyProperties(parkingLot, parkingLotDTO);
        	if(parkingLotDTO != null){
        		ParkingLotCacheUtil.setParkLotByPlNo(parkCode, parkingLotDTO);
        	}
        }
        /**添加经纬度.*/
        this.saveParkGeo(request, parkingLot.getPlId(), parkCode);
        BeanUtils.copyProperties(parkingLot, dto);
        if (flag < 1) {
            throw new BizException(ErrorType.SAVE_PARK_ERROR, ErrorType.SAVE_PARK_ERROR.getMsg());
        }
        //更新空闲车位数
        updateFreeBerthsNum(parkCode, parkingLot.getPlBerthNum(),parkingLot.getPlName());


        //给青岛同步
        ParkingLotSuccessMsgVO getparkinglotsDTO = new ParkingLotSuccessMsgVO();
        BeanUtils.copyProperties(parkingLot,getparkinglotsDTO);
        getparkinglotsDTO.setLonId(request.getLonId());
        getparkinglotsDTO.setLatId(request.getLatId());
        getparkinglotsDTO.setParkDealState(1);
        rocketMQTemplate.syncSend(MQTopicConstants.ZTEITS_RNT_CLOUD, ParkTags.PARK_BASE_MSG, getparkinglotsDTO);
        return new BizResult<ParkingLotDTO>(dto);
    }

    private void updateFreeBerthsNum(String parkCode, Integer plBerthNum,String plName) {
        //更新缓存
        ParkFreeBerthsCacheUtil.setFreeBerthsByPlNo(parkCode, plBerthNum);
        FreeBerthsChangeMsgVO berthsChangeMsgVO = new FreeBerthsChangeMsgVO(parkCode, plName,plBerthNum);
        //rocketMQTemplate.sendOneWay(MQTopicConstants.ZTEITS_RNT_CLOUD,DataCollectionTags.FREE_BERTHS_CHANGE, berthsChangeMsgVO);
        freeBerthOperInnerService.updateFreeBerthsNumByPlNo(berthsChangeMsgVO.getPlNo(), berthsChangeMsgVO.getFreeBerths(),berthsChangeMsgVO.getRealFreeBerths());
        PushFreeBerthsChangeRequest freeBerthsChangeMsgVO = new PushFreeBerthsChangeRequest();
        freeBerthsChangeMsgVO.setSysCode(BasicEnum.SYS_CODE.getValue());
        List<FreeBerthsChangeMsgVO> berthsChangeMsgVOs = new ArrayList<>();
        berthsChangeMsgVOs.add(berthsChangeMsgVO);
        freeBerthsChangeMsgVO.setBerthsChangeMsgVOs(berthsChangeMsgVOs );
        BizResult<Boolean> bizResult = freeBerthsPushOperService.pushFreeBerthsToScreen(freeBerthsChangeMsgVO );
        if(!ResultUtils.isSuccess(bizResult)){
            logger.info("诱导推送失败:"+bizResult.getErrMsg());
        }
    }

    /**
     * 保存经纬度信息
     *
     * @param request
     * @param plNo
     */
    private void saveParkGeo(ParkingLotInfoSaveRequest request, Long plNo, String parkCode) {
        ParkingLotGeo lotGeo = new ParkingLotGeo();
        BeanUtils.copyProperties(request, lotGeo);
        lotGeo.setLonLatType(LonLatTypeEnum.LON_LAT_TYPE_1.value());
        lotGeo.setPlId(plNo);
        lotGeo.setPlNo(parkCode);
        lotGeo.setGeoType(1);
        /**保存百度坐标.*/
        Long flg = parkingLotGeoDao.saveOrModifyParkingLotGeo(lotGeo);
        /**加入停车场经纬度缓存.*/
        if(flg != null && flg >0){
        	ParkingLotGeoCacheUtil.setPointByPlNo(LonLatTypeEnum.LON_LAT_TYPE_1, parkCode, lotGeo.getLonId().doubleValue(), lotGeo.getLatId().doubleValue());
        }

        //百度转高德
        Double lon = lotGeo.getLonId().doubleValue();
        Double lat = lotGeo.getLatId().doubleValue();
        Map<String, Double> map = GPSConvert.bd_decrypt(lat, lon);
        //保存转换后的经纬度
        lotGeo.setLonId(new BigDecimal(map.get("lon")));
        lotGeo.setLatId(new BigDecimal(map.get("lat")));
        lotGeo.setLonLatType(LonLatTypeEnum.LON_LAT_TYPE_3.value());
        Long flgSave = parkingLotGeoDao.saveOrModifyParkingLotGeo(lotGeo);
        logger.info("flgSave的值={}",flgSave);
        /**加入停车场经纬度缓存.*/
        if(flgSave != null && flgSave >0){
            logger.info("----------------写入缓存数据 火星;field="+parkCode+";value="+JSON.toJSONString(map)+"----------------");
            ParkingLotGeoCacheUtil.setPointByPlNo(LonLatTypeEnum.LON_LAT_TYPE_3, parkCode, map.get("lon"),map.get("lat"));
        }
    }

    /**
     * 生成停车场编码
     *    1.停车场最大编码获取:以 PKL 或者 TKL 开头的
     * @param state
     * @return 2020-07-03 wanfs
     */
    private String generatorParkNo(Integer state) {
        logger.info("生成停车场编码,入参={}",state);
        String generatorParkNo = "";
        String maxPlNo = parkingLotDao.selectMaxPlNO(ParkConstant.state.USED.equals(state) ? "P15040" : "TKL");
        logger.info("数据库中最大的停车编码={}", maxPlNo);
        if (org.springframework.util.StringUtils.isEmpty(maxPlNo)) {
            generatorParkNo = ParkConstant.state.USED.equals(state) ? "P15040000000001" : "TKL000000001";
        } else {
            Long newMaxValue = Long.valueOf(maxPlNo.substring(3)) + 1L;
            generatorParkNo = maxPlNo.substring(0, maxPlNo.length() - newMaxValue.toString().length()) + newMaxValue;
        }
        logger.info("生成的停车场编码为:" + generatorParkNo);
        return generatorParkNo;
    }


    @Transactional
    @Override
    public BizResult<Boolean> UpdateParkingLotInfo(ParkingLotInfoSaveRequest request) {
        //更新停车场信息表
        ParkingLot parkingLot = new ParkingLot();
        BeanUtils.copyProperties(request, parkingLot);
        parkingLot.setModifyTime(new Date());
        int flag = parkingLotDao.updateByPrimaryKeySelective(parkingLot);
        /**将停车场加入缓存.*/
        ParkingLot parkingLot2 = null;
        if(flag>0){
        	ParkingLotDTO parkingLotDTO = new ParkingLotDTO();
        	parkingLot2 = parkingLotDao.selectByPrimaryKey(request.getPlId());
        	BeanUtils.copyProperties(parkingLot2, parkingLotDTO);
        	if(parkingLotDTO != null && StringUtils.isNotEmpty(parkingLotDTO.getPlNo())){
        		ParkingLotCacheUtil.setParkLotByPlNo(parkingLotDTO.getPlNo(), parkingLotDTO);
        	}
        }
        if(request.getLonId()!=null && request.getLatId()!=null){
        	//删除经纬度信息
        	List<String> plNos = new ArrayList<>();
        	plNos.add(parkingLot.getPlNo());
        	parkingLotGeoDao.deleteParkingLotGeoByPlNos(plNos,request.getCreateOp());
        	//保存经纬度信息
        	saveParkGeo(request, request.getPlId(), request.getPlNo());
        }
        //更新缓存
        updateFreeBerthsNum(parkingLot2.getPlNo(),parkingLot2.getPlBerthNum(),parkingLot2.getPlName());
        //更新对应的空闲车位数
        parkFreeBerthBizService.updateFreeBerthNumByPlNo(parkingLot2.getPlNo());
        //给青岛同步
        ParkingLotSuccessMsgVO getparkinglotsDTO = new ParkingLotSuccessMsgVO();
        BeanUtils.copyProperties(parkingLot2,getparkinglotsDTO);
        getparkinglotsDTO.setLonId(request.getLonId());
        getparkinglotsDTO.setLatId(request.getLatId());
        getparkinglotsDTO.setParkDealState(2);
        rocketMQTemplate.syncSend(MQTopicConstants.ZTEITS_RNT_CLOUD, ParkTags.PARK_BASE_MSG, getparkinglotsDTO);
        return new BizResult<Boolean>(flag > 0);
    }

    @Transactional
    @Override
    public BizResult<Boolean> DeleteParkingLotInfoByPlNos(ParkingLotInfoDeleteRequest request) {
        logger.info("---begin通过plNos删除停车信息,入参={}", JSONObject.toJSON(request));
        Boolean result = parkingLotDao.deleteParkingLotByPlNos(request.getPlNos(),request.getOpId());

        //给青岛同步
        for (String plno:request.getPlNos()){
            ParkingLotSuccessMsgVO getparkinglotsDTO = new ParkingLotSuccessMsgVO();
            getparkinglotsDTO.setPlNo(plno);
            getparkinglotsDTO.setDataStatus(DataStatusEnum.DATA_STATUS_NO_VALID.value());
            getparkinglotsDTO.setModifyTime(new Date());
            getparkinglotsDTO.setParkDealState(3);
            rocketMQTemplate.syncSend(MQTopicConstants.ZTEITS_RNT_CLOUD, ParkTags.PARK_BASE_MSG, getparkinglotsDTO);

        }
        return new BizResult<Boolean>(result);
    }


    @Override
    public BizResult<List<AreaTreeDTO>> queryParkInfoByAreaBlockIds(
        ParkInfoByAreaBlockIdsRequest parkInfoByAreaBlockIdsRequest) {
        logger.info("---begin通过块ids查询停车信息,入参={}", JSONObject.toJSON(parkInfoByAreaBlockIdsRequest));
        List<AreaTreeDTO> list = new ArrayList<AreaTreeDTO>();
        if (parkInfoByAreaBlockIdsRequest == null) {
            throw new BizException(ErrorType.PARAMM_NULL, "区域块ids为空!");
        } else {
            List<AreaTreeDO> listDO = parkingLotDao.queryParkInfoByAreaBlockIds(parkInfoByAreaBlockIdsRequest);
            ListCopyUtil.listCopyProperties(listDO, list, AreaTreeDTO.class);
        }
        logger.info("---end通过块ids查询停车信息");
        return new BizResult<List<AreaTreeDTO>>(list);
    }

    @Override
    public BizResult<PageBean<TdBTempParklotDTO>> queryParkTempInfoPage(ParkTempInfoPageQueryRequest request) {
        //最大数据量
        int maxPageSize = 200;
        if (request.getBaseRequest().getPageSize() <= 0 || request.getBaseRequest().getPageNum() > maxPageSize) {
            request.getBaseRequest().setPageSize(maxPageSize);
        }

        PageInfo<TdBTempParklotDTO> pageInfo = parkingLotDao.queryParkTempInfoPage(request);
        PageBean<TdBTempParklotDTO> pageBean = new PageBean<>();
        PageBeanUtil.copyProperties(pageInfo, pageBean, TdBTempParklotDTO.class);
        return new BizResult<>(pageBean);
    }

    /**
	 * 校验停车场名称唯一性.<br/>
	 * @param request
	 * @return
	 * 2018年1月4日  wangfs.<br/>
	 */
	@Override
	public BizResult<Boolean> checkUniqueForPlName(CheckUniqueForPlNameRequest request) {
		logger.info("begin校验停车场名称唯一性,入参={}",JSONObject.toJSON(request));
		if (request == null || StringUtils.isEmpty(request.getPlName())) {
            throw new BizException(ErrorType.PARAMM_NULL, "校验停车场名称唯一性");
        }
		Boolean flg = parkingLotDao.checkUniqueForPlName(request);
		logger.info("begin校验停车场名称唯一性,结果={}",flg);
		return new BizResult<Boolean>(flg);
	}

	/**
	 * 更新停车场块信息.<br/>
	 * @param request
	 * @return
	 * 2018年1月4日  wangfs.<br/>
	 */
	@Override
	public BizResult<Boolean> updateBlockForParkLot(ChangeBlockForParkLotRequest request) {
		logger.info("begin更新停车场块信息,入参={}",JSONObject.toJSON(request));
		BeanValidatorsUtils.validateWithException(request);
		Boolean flg = parkingLotDao.updateAreaBlockForParkLot(request);
		logger.info("end更新停车场块信息,结果={}",flg);
		return new BizResult<Boolean>(flg);
	}

	/**
	 * 通过办事处id更新停车场块信息.<br/>
	 * @param request
	 * @return
	 * 2018年1月4日  wangfs.<br/>
	 */
	@Override
	public BizResult<Boolean> updateParkLotBlockNameByBlockId(ChangeBlockForParkLotRequest request) {
		logger.info("begin通过办事处id更新停车场块信息,入参={}",JSONObject.toJSON(request));
		Boolean flg = parkingLotDao.updateParkLotBlockNameByBlockId(request);
		logger.info("end通过办事处id更新停车场块信息,结果={}",flg);
		return new BizResult<Boolean>(flg);
	}

	@Override
	public BizResult<Boolean> isAllowDeleteAreaBlock(IsAllowDelAreaBlockRequest request) {
		//有停车场不允许删除
		QueryParkingLotByAreaBlockRequest queryParkLotForPageReq = new QueryParkingLotByAreaBlockRequest();
        queryParkLotForPageReq.setSysCode(request.getSysCode());
		queryParkLotForPageReq.setBlockIds(request.getPlAreaBlockId());
		queryParkLotForPageReq.getBaseRequest().setPageNum(1);
		queryParkLotForPageReq.getBaseRequest().setPageSize(1);
        BizResult<PageBean<ParkingLotDTO>> result = parkingLotQueryService.queryParkingLotForPageByAreaBlockId(queryParkLotForPageReq);
        PageBean<ParkingLotDTO> pageBean = ResultUtils.getBizResultData(result);
        if(pageBean!=null && pageBean.getPageTotals()!=null && pageBean.getPageTotals()>=1){
        	throw new BizException(ErrorType.NOT_ALLOW_DEL_AREA_BLOCK);
        }
		return new BizResult<Boolean>(true);
	}

    @Override
    public BizResult<List<PlNameDTO>> queryPlNameByPlNo(QueryPlNameRequest request) {
        List<PlNameDTO> list = parkingLotDao.queryPlNameByPlNo(request);
        return new BizResult<>(list);
    }

}