package com.doumee.jtt808.web.service; 
 | 
  
 | 
import com.alibaba.fastjson.JSONArray; 
 | 
import com.alibaba.fastjson.JSONObject; 
 | 
import com.alibaba.fastjson.TypeReference; 
 | 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 
 | 
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 
 | 
import com.doumee.biz.system.SystemDictDataBiz; 
 | 
import com.doumee.core.constants.Constants; 
 | 
import com.doumee.core.constants.ResponseStatus; 
 | 
import com.doumee.core.dingding.DingDingNotice; 
 | 
import com.doumee.core.exception.BusinessException; 
 | 
import com.doumee.core.utils.DateUtil; 
 | 
import com.doumee.core.utils.PositionUtil; 
 | 
import com.doumee.core.utils.StringTools; 
 | 
import com.doumee.core.wx.SendWxMessage; 
 | 
import com.doumee.core.wx.WxMiniConfig; 
 | 
import com.doumee.core.wx.WxMiniUtilService; 
 | 
import com.doumee.dao.business.*; 
 | 
import com.doumee.dao.business.join.BikesJoinMapper; 
 | 
import com.doumee.dao.business.join.GoodsorderJoinMapper; 
 | 
import com.doumee.dao.business.join.MemberRidesJoinMapper; 
 | 
import com.doumee.dao.business.join.RefundJoinMapper; 
 | 
import com.doumee.dao.business.model.*; 
 | 
import com.doumee.dao.business.web.request.BackElecBikeRequest; 
 | 
import com.doumee.dao.business.web.request.LocaltionDTO; 
 | 
import com.doumee.dao.business.web.request.OpenElecBikeRequest; 
 | 
import com.doumee.dao.business.web.response.MemberRidesDetailResponse; 
 | 
import com.doumee.jtt808.web.endpoint.MessageManager; 
 | 
import com.doumee.service.business.GoodsorderService; 
 | 
import com.doumee.service.business.PricingRuleService; 
 | 
import com.github.yulichang.wrapper.MPJLambdaWrapper; 
 | 
import me.chanjar.weixin.common.error.WxErrorException; 
 | 
import org.apache.commons.lang3.StringUtils; 
 | 
import org.springframework.beans.BeanUtils; 
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.beans.factory.annotation.Value; 
 | 
import org.springframework.stereotype.Service; 
 | 
import org.springframework.transaction.annotation.Transactional; 
 | 
import org.springframework.util.ConcurrentReferenceHashMap; 
 | 
import org.springframework.web.bind.annotation.RequestBody; 
 | 
import org.yzh.commons.model.APIResult; 
 | 
import org.yzh.protocol.commons.transform.AttributeKey; 
 | 
import org.yzh.protocol.commons.transform.attribute.Battery; 
 | 
import org.yzh.protocol.t808.T0200; 
 | 
import org.yzh.protocol.t808.T0201_0500; 
 | 
import org.yzh.protocol.t808.T8500; 
 | 
import reactor.core.publisher.Mono; 
 | 
  
 | 
import java.math.BigDecimal; 
 | 
import java.util.ArrayList; 
 | 
import java.util.Date; 
 | 
import java.util.List; 
 | 
import java.util.Objects; 
 | 
import java.util.concurrent.ConcurrentMap; 
 | 
  
 | 
@Service 
 | 
public class Jtt808Service { 
 | 
    @Value("${tencent.map.remoteHost}") 
 | 
    private String mapHost; 
 | 
    @Value("${tencent.map.appKey}") 
 | 
    private String mapKey; 
 | 
    @Autowired 
 | 
    private MessageManager messageManager; 
 | 
    @Autowired 
 | 
    private GoodsorderService goodsorderService; 
 | 
    @Autowired 
 | 
    private BikesMapper bikesMapper; 
 | 
    @Autowired 
 | 
    private BikesJoinMapper bikesJoinMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private SystemDictDataBiz systemDictDataBiz; 
 | 
  
 | 
    @Autowired 
 | 
    private MemberMapper memberMapper; 
 | 
    @Autowired 
 | 
    private SitesMapper sitesMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private MemberRidesJoinMapper memberRidesJoinMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private PricingParamMapper pricingParamMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private PricingDetailMapper pricingDetailMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private HolidaysMapper holidaysMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private SendWxMessage sendWxMessage; 
 | 
  
 | 
  
 | 
    @Autowired 
 | 
    PricingRuleService pricingRuleService; 
 | 
    public  APIResult<T0201_0500>  bikeControl(@RequestBody T8500 request) { 
 | 
        Mono<APIResult<T0201_0500>>  result = messageManager.requestR(request, T0201_0500.class); 
 | 
        APIResult<T0201_0500> data = result.block(); 
 | 
        return  data; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 手动还车 
 | 
     * @param param 
 | 
     */ 
 | 
    @Transactional(rollbackFor = {BusinessException.class}) 
 | 
    public   void backElecBike(BackElecBikeRequest param) { 
 | 
        Member member = memberMapper.selectById(param.getMemberId()); 
 | 
        if (member == null) { 
 | 
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,您的账号信息查询失败,请返回重新进入小程序再试!"); 
 | 
        } 
 | 
        Goodsorder gparam = new Goodsorder(); 
 | 
        gparam.setMemberId(param.getMemberId()); 
 | 
        gparam.setStatus(Constants.goodsorderStatus.pay); 
 | 
        gparam.setType(Constants.ZERO); 
 | 
        Goodsorder goodsorder =  goodsorderService.findOne(gparam); 
 | 
        this.backBike(goodsorder); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 自动还车 
 | 
     * @param id 
 | 
     */ 
 | 
    @Transactional 
 | 
    public void forceBack(String id){ 
 | 
        Goodsorder goodsorder =  goodsorderService.findById(id); 
 | 
        this.backBike(goodsorder); 
 | 
    } 
 | 
  
 | 
  
 | 
    @Transactional(rollbackFor = {BusinessException.class}) 
 | 
    public void backBike(Goodsorder goodsorder){ 
 | 
        if(Objects.isNull(goodsorder)){ 
 | 
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"无骑行订单记录"); 
 | 
        } 
 | 
        if(Constants.formatIntegerNum(goodsorder.getStatus()) != Constants.GOODSORDER_STATUS.HAVING_PAY.getKey() ){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该订单当前状态不支持结算操作,请尝试刷新列表重试!" ); 
 | 
        } 
 | 
        //查询骑行记录 
 | 
        List<MemberRides>  memberRides = goodsorderService.getMemberRidesForClose(goodsorder.getId()); 
 | 
        List<String> backIds = new ArrayList<>(); 
 | 
        if(memberRides!=null && memberRides.size()>0){ 
 | 
            for (MemberRides  rides : memberRides){ 
 | 
                if(Constants.equalsInteger(rides.getStatus(),Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey()) 
 | 
                        &&Constants.equalsInteger(rides.getType(),Constants.ONE)){ 
 | 
                    //如果是电车并且是骑行中 进行关锁处理 
 | 
                    Bikes  bike = getElecBikeByCode(rides.getBikeCode()); 
 | 
                    //查询停车站点信息 
 | 
                    if(bike.getSiteId() ==null){ 
 | 
                        throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按要求前往停车点停车!"); 
 | 
                    } 
 | 
                    lockBikes(bike.getDeviceSn(),Constants.ONE);//发起关锁指令请求 
 | 
                    backIds.add(rides.getId()); 
 | 
                    rides.setStatus(Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey());//已还车 
 | 
                    rides.setBackSiteId(bike.getSiteId());//还车站点 
 | 
  
 | 
                    rides.setBackDate(new Date()); 
 | 
                    Integer freeRentTime = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode()); 
 | 
                    Integer rideTime = DateUtil.betweenMin(rides.getRentDate(), rides.getBackDate()); 
 | 
                    //计算骑行计费时长 
 | 
                    rides.setDuration( rideTime > freeRentTime  ? rideTime : 0 ); 
 | 
                    rides.setEditDate(rides.getBackDate()); 
 | 
                    memberRidesJoinMapper.updateById(rides);//更新骑行状态为已还车 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        //订单结算 
 | 
        Date date = new Date(); 
 | 
        goodsorder.setEditDate(date); 
 | 
        goodsorder.setEditor(null); 
 | 
        goodsorderService.dealCloseGoodsorderBiz( goodsorder,Constants.REFUND_TYPE.NORMAL.getKey(),memberRides); 
 | 
        //更新电动车车辆状态 
 | 
        bikesMapper.update(null,new UpdateWrapper<Bikes>().lambda().set(Bikes::getStatus,Constants.ZERO).eq(Bikes::getType,Constants.ONE) 
 | 
                .apply(" code in ( select m.bike_code from member_rides m where m.ordre_id = '"+goodsorder.getId()+"' ) ") 
 | 
        ); 
 | 
    } 
 | 
  
 | 
    private Bikes getElecBikeByCode(String bikeCode) { 
 | 
        Bikes  bike = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda() 
 | 
                .eq(Bikes::getType,Constants.ONE) 
 | 
                .eq(Bikes::getIsdeleted,Constants.ZERO) 
 | 
                .eq(Bikes::getCode,bikeCode) 
 | 
        ); 
 | 
        if(bike==null){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"车辆信息查询失败,请稍后重试或联系园区管理员处理!" ); 
 | 
        } 
 | 
        if(StringUtils.isBlank(bike.getDeviceSn()) || bike.getLongitude()==null ||bike.getLatitude() ==null){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"车辆位置信息查询失败,请稍后重试或联系园区管理员处理!" ); 
 | 
        } 
 | 
        if(StringUtils.isBlank(bike.getDeviceSn()) ){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"车辆控制器故障,请稍后重试或联系园区管理员处理!" ); 
 | 
        } 
 | 
        int expireTime = 10*1000;//默认10秒 
 | 
        try { 
 | 
            expireTime = Integer.parseInt(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME,Constants.HEART_TIME_EXPIRE_TIME).getCode())*1000; 
 | 
        }catch (Exception e){ 
 | 
        } 
 | 
        if(bike.getHeartDate() == null || System.currentTimeMillis() - bike.getHeartDate().getTime() >expireTime){ 
 | 
            //如果车辆上报时间超过30秒,则表示车辆控制器失效 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"车辆控制器故障,获取定位信息失败,请稍后重试或联系园区管理员处理!" ); 
 | 
        } 
 | 
        return  bike; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 发起关锁、开锁指令请求 
 | 
     * @param clientId 
 | 
     * @param type 控制标志:0.车门解锁 1.车门加锁 
 | 
     */ 
 | 
    private void lockBikes(String clientId,int type) { 
 | 
        T8500 request = new T8500(); 
 | 
        request.setType(type);//关锁 
 | 
        request.setClientId(StringTools.leftTrip(clientId,'0')); 
 | 
        Mono<APIResult<T0201_0500>>  result = messageManager.requestR(request, T0201_0500.class); 
 | 
        APIResult<T0201_0500> data = result.block(); 
 | 
        if(!data.isSuccess()){ 
 | 
            //如果开锁失败,则返回异常 
 | 
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,"+(type ==0?"车辆开锁":"车辆关锁")+"失败,请稍后重试,或者联系园区管理人员!"); 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
  
 | 
  
 | 
    /** 
 | 
     * 查询停车站点信息 
 | 
     * @return 
 | 
     */ 
 | 
    private Sites getBackSiteByPostion(double lat,double lng) { 
 | 
        Sites site = null;//查询停车站点信息 
 | 
        List<Sites> sitesList = sitesMapper.selectList(new QueryWrapper<Sites>().lambda() 
 | 
                .eq(Sites::getStatus,Constants.ZERO) 
 | 
                .eq(Sites::getIsdeleted,Constants.ZERO) 
 | 
                .eq(Sites::getType,Constants.ONE)); 
 | 
        if(sitesList ==null ||sitesList.size() ==0){ 
 | 
//            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按照要求前往停车点停车!"); 
 | 
            return  null; 
 | 
        } 
 | 
        for(Sites sites :sitesList){ 
 | 
            TypeReference typeReference =  new TypeReference<List<LocaltionDTO>>(){}; 
 | 
            List<LocaltionDTO> array = JSONObject.parseObject(sites.getElectronicFence(), typeReference.getType()); 
 | 
            if(array == null || array.size() ==0){ 
 | 
                continue; 
 | 
            } 
 | 
            if(PositionUtil.isInPolygon(lng,lat,array)){ 
 | 
                //如果在停车点范围内; 
 | 
                site = sites; 
 | 
                break; 
 | 
            } 
 | 
           /* if(site ==null){ 
 | 
                throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按照要求前往停车点停车!"); 
 | 
            }*/ 
 | 
        } 
 | 
        return site; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 临时停车 
 | 
     * @param param 
 | 
     */ 
 | 
    @Transactional(rollbackFor = {BusinessException.class}) 
 | 
    public void pauseElecBike(BackElecBikeRequest param) { 
 | 
        Member member = memberMapper.selectById(param.getMemberId()); 
 | 
        if (member == null) { 
 | 
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,您的账号信息查询失败,请返回重新进入小程序再试!"); 
 | 
        } 
 | 
        Goodsorder gparam = new Goodsorder(); 
 | 
        gparam.setMemberId(param.getMemberId()); 
 | 
        gparam.setStatus(Constants.goodsorderStatus.pay); 
 | 
        gparam.setType(Constants.ZERO); 
 | 
        Goodsorder goodsorder =  goodsorderService.findOne(gparam); 
 | 
        if(Objects.isNull(goodsorder)){ 
 | 
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有骑行中订单记录"); 
 | 
        } 
 | 
        //查询所有骑行记录 
 | 
        MemberRides memberRides = memberRidesJoinMapper.selectJoinOne(MemberRides.class,new MPJLambdaWrapper<MemberRides>() 
 | 
                .eq(MemberRides::getOrdreId,goodsorder.getId()) 
 | 
                .eq(MemberRides::getStatus,Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey()) 
 | 
                .selectAll(MemberRides.class) 
 | 
                .last("limit 1")); 
 | 
        if(memberRides ==null || memberRides.getBikeCode() == null){ 
 | 
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有骑行中记录"); 
 | 
        } 
 | 
        Bikes bike = getElecBikeByCode(memberRides.getBikeCode()); 
 | 
        //查询停车位置是否符合停车位置规范 
 | 
        checkPausePostionBiz(bike); 
 | 
        lockBikes(bike.getDeviceSn(),Constants.ONE);//发起关锁指令请求 
 | 
        memberRides.setPauseDate(new Date()); 
 | 
        memberRides.setEditDate(memberRides.getBackDate()); 
 | 
        memberRides.setStatus(Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey()); 
 | 
        memberRidesJoinMapper.updateById(memberRides);//更新骑行状态为临停中 
 | 
    } 
 | 
  
 | 
  
 | 
    private void checkPausePostionBiz(Bikes bike) { 
 | 
        int ruleType = 0; 
 | 
        try { 
 | 
            ruleType =Integer.parseInt( systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME,Constants.PAUSE_BIKE_TYPE).getCode()); 
 | 
        }catch (Exception e){ 
 | 
        } 
 | 
        if(ruleType == 1){ 
 | 
            //如果仅限于园区临时停车 
 | 
            List<LocaltionDTO> array = new ArrayList<>(); 
 | 
            try { 
 | 
                TypeReference typeReference =  new TypeReference<List<LocaltionDTO>>(){}; 
 | 
                array = JSONObject.parseObject(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.PARK_LAT_LNG_LIST).getCode(), typeReference.getType()); 
 | 
            }catch (Exception e){ 
 | 
            } 
 | 
            if(array == null || array.size() ==0){ 
 | 
                throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,园区运营区域配置有误,请联系园区管理员处理!"); 
 | 
            } 
 | 
            if( !PositionUtil.isInPolygon(bike.getLongitude().doubleValue(),bike.getLatitude().doubleValue(),array)){ 
 | 
                //如果在停车点范围内; 
 | 
                throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按要求在园区运营区域范围内停车!"); 
 | 
            } 
 | 
        }else{ 
 | 
            //检查是否满足停车点停车 
 | 
            if(bike.getSiteId() ==null){ 
 | 
                throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按要求前往停车点停车!"); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public void updateBikesInfo(List<T0200> list) throws Exception{ 
 | 
        Date date = new Date(); 
 | 
        BigDecimal lowVoltage = new BigDecimal(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME,Constants.LOW_VOLTAGE).getCode()); 
 | 
        String ddToken = systemDictDataBiz.queryByCode(Constants.DINGDING,Constants.DINGDING_TOKEN).getCode(); 
 | 
        String ddRobotCode = systemDictDataBiz.queryByCode(Constants.DINGDING,Constants.DINGDING_ROBOTCODE).getCode(); 
 | 
        String ddChatToken = systemDictDataBiz.queryByCode(Constants.DINGDING,Constants.DINGDING_CHATTOKEN).getCode(); 
 | 
        for(T0200 m : list){ 
 | 
            Bikes bike = new Bikes(); 
 | 
            bike.setDeviceSn(m.getClientId()); 
 | 
            if(m.getLatitude()!=0){ 
 | 
                bike.setLatitude(new BigDecimal(m.getLatitude()).divide(new BigDecimal(1000000),8,BigDecimal.ROUND_HALF_UP)); 
 | 
            } 
 | 
            if(m.getLongitude()!=0){ 
 | 
                bike.setLongitude(new BigDecimal(m.getLongitude()).divide(new BigDecimal(1000000),8,BigDecimal.ROUND_HALF_UP)); 
 | 
            } 
 | 
            updateMapLocation(bike); 
 | 
            bike.setHeartDate(DateUtil.getDateFromLocalDateTime(m.getDeviceTime())); 
 | 
            if(m.getAttributes()!=null ){ 
 | 
                Battery battery= (Battery) m.getAttributes().get(AttributeKey.Battery); 
 | 
                if(battery !=null && battery.getVoltage()!=null){ 
 | 
                    bike.setVoltage(new BigDecimal(battery.getVoltage())); 
 | 
                } 
 | 
            } 
 | 
            if(StringUtils.isBlank(bike.getDeviceSn() )){ 
 | 
                return; 
 | 
            } 
 | 
            String tSn = StringTools.leftPad(bike.getDeviceSn(),12,'0') ; 
 | 
            Bikes bikes = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda() 
 | 
                    .eq(Bikes::getDeviceSn,tSn) 
 | 
                    .eq(Bikes::getIsdeleted,Constants.ZERO) 
 | 
                    .eq(Bikes::getType,Constants.ONE) 
 | 
                    .last("limit 1")); 
 | 
            if(bikes == null){ 
 | 
                return; 
 | 
            } 
 | 
            Sites site = null; 
 | 
            if(bikes.getLatitude()!=null && bikes.getLongitude()!=null){ 
 | 
                //根据定位信息查询所在站点 
 | 
                site =  getBackSiteByPostion(bikes.getLatitude().doubleValue(),bikes.getLongitude().doubleValue()); 
 | 
            } 
 | 
            bikesMapper.update(null,new UpdateWrapper<Bikes>().lambda() 
 | 
                    .set(bike.getLatitude()!=null,Bikes::getLatitude,bike.getLatitude()) 
 | 
                    .set(bike.getVoltage()!=null,Bikes::getVoltage,bike.getVoltage()) 
 | 
                    .set(bike.getLongitude()!=null,Bikes::getLongitude,bike.getLongitude()) 
 | 
                    .set(Bikes::getSiteId,site ==null?null:site.getId()) 
 | 
                    .set( Bikes::getHeartDate,date) 
 | 
                    .eq(Bikes::getId,bikes.getId())); 
 | 
  
 | 
            if(bikes.getVoltage().compareTo(lowVoltage)>=Constants.ZERO 
 | 
                    && bike.getVoltage().compareTo(lowVoltage)<Constants.ZERO){ 
 | 
                //发送钉钉通知 
 | 
                DingDingNotice.lowVoltageNotice(bikes.getCode(), 
 | 
                        PositionUtil.getTxMapAddrByLatAndLng(Double.valueOf(bike.getLatitude().toString()),Double.valueOf(bike.getLongitude().toString()),mapHost,mapKey) 
 | 
                        ,Objects.nonNull(site)?site.getName():null, 
 | 
                        ddToken, 
 | 
                        ddRobotCode, 
 | 
                        ddChatToken); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private void updateMapLocation(Bikes bike) { 
 | 
        if(bike.getLatitude() == null || bike.getLongitude() == null){ 
 | 
            return; 
 | 
        } 
 | 
        PositionUtil.AMap aMap =PositionUtil.transform(bike.getLongitude().doubleValue() ,bike.getLatitude().doubleValue()); 
 | 
        bike.setLatitude(new BigDecimal(aMap.getLatitude())); 
 | 
        bike.setLongitude(new BigDecimal(aMap.getLongitude())); 
 | 
    } 
 | 
  
 | 
    public ConcurrentMap<String,Integer> cacheOpenLock = new ConcurrentReferenceHashMap<>(); 
 | 
  
 | 
  
 | 
    @Transactional(rollbackFor = {BusinessException.class}) 
 | 
    public MemberRidesDetailResponse openLock(OpenElecBikeRequest openElecBikeRequest){ 
 | 
        Member member = memberMapper.selectById(openElecBikeRequest.getMemberId()); 
 | 
        if (member == null) { 
 | 
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,您的账号信息查询失败,请返回重新进入小程序再试!"); 
 | 
        } 
 | 
        if(Constants.formatIntegerNum(cacheOpenLock.get(openElecBikeRequest.getCode())) == 1){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该车辆已被锁定借用,请尝试更换其他车辆!"); 
 | 
        } 
 | 
        Bikes bike = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda().eq(Bikes::getCode,openElecBikeRequest.getCode()).eq(Bikes::getIsdeleted,Constants.ZERO) 
 | 
                .eq(Bikes::getType,Constants.ONE).last(" limit 1 ")); 
 | 
        if(bike == null && StringUtils.isBlank(bike.getParamId())){ 
 | 
            //如果车辆类型是空 
 | 
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), " 该车型暂时不能借车操作哦,请更换其他车型重试!"); 
 | 
        } 
 | 
        if(!Constants.equalsInteger(bike.getStatus(),Constants.ZERO)){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该车辆已被锁定借用,请尝试更换其他车辆!"); 
 | 
        } 
 | 
        cacheOpenLock.put(openElecBikeRequest.getCode(), 1); 
 | 
        try { 
 | 
            //判断当前是否已支付押金 
 | 
            Goodsorder goodsorder = goodsorderService.findOneByWrapper(new QueryWrapper<Goodsorder>() 
 | 
                    .eq("isdeleted", Constants.ZERO) 
 | 
                    .eq("status", Constants.goodsorderStatus.pay) 
 | 
                    .eq("type", Constants.ZERO) 
 | 
                    .eq("member_id", member.getId()) 
 | 
                    .orderByDesc("create_date") 
 | 
                    .last("limit 1")); 
 | 
            if (Objects.isNull(goodsorder)) { 
 | 
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "未支付押金,无法进行该操作!"); 
 | 
            } 
 | 
            //判断当前押金订单是否为今日押金 
 | 
            if (!DateUtil.DateToStr(goodsorder.getPayDate(), "yyyy-MM-dd").equals(DateUtil.getDate(new Date(), "yyyy-MM-dd"))) { 
 | 
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "非今日押金订单,请结算后重新支付!"); 
 | 
            } 
 | 
            //是否存在其他骑行记录 
 | 
            if (memberRidesJoinMapper.selectCount(new QueryWrapper<MemberRides>().lambda().eq(MemberRides::getOrdreId,goodsorder.getId())) > Constants.ZERO) { 
 | 
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "已骑行其他车辆,无法扫码,请结算后重新尝试"); 
 | 
            } 
 | 
            //判断是否处于营业时间 
 | 
            goodsorderService.checkBusiness(); 
 | 
            //查询是否处于骑行中 
 | 
            if (memberRidesJoinMapper.selectCount(new QueryWrapper<MemberRides>().eq("member_id", member.getId()).in("status", 0, 1, 4)) > Constants.ZERO) { 
 | 
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "存在骑行中车辆,无法扫码"); 
 | 
            } 
 | 
            MemberRides memberRides = new MemberRides(); 
 | 
            //根据车型查询计价方案 
 | 
            isValidePricingType(bike,memberRides) ; 
 | 
            MemberRidesDetailResponse memberRidesDetailResponse = new MemberRidesDetailResponse(); 
 | 
            this.lockBikes(bike.getDeviceSn(),0); 
 | 
            //存储骑行记录 
 | 
            memberRides.setId(Constants.getUUID()); 
 | 
            memberRides.setIsdeleted(Constants.ZERO); 
 | 
            memberRides.setMemberId(member.getId()); 
 | 
            memberRides.setCreateDate(new Date()); 
 | 
            memberRides.setOrdreId(goodsorder.getId()); 
 | 
            memberRides.setBikeCode(bike.getCode()); 
 | 
            memberRides.setRentDate(new Date()); 
 | 
            memberRides.setType(Constants.ONE); 
 | 
            memberRides.setBalance(new BigDecimal(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME,Constants.RENT_DEPOSIT).getCode())); 
 | 
            memberRides.setStatus(Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey()); 
 | 
            memberRides.setCloseStatus(Constants.ZERO); 
 | 
            memberRidesJoinMapper.insert(memberRides); 
 | 
            BeanUtils.copyProperties(memberRides, memberRidesDetailResponse); 
 | 
            return memberRidesDetailResponse; 
 | 
        }catch (BusinessException biz){ 
 | 
            throw  biz; 
 | 
        }catch (Exception biz){ 
 | 
            throw  new BusinessException(ResponseStatus.SERVER_ERROR); 
 | 
        }finally { 
 | 
            cacheOpenLock.remove(openElecBikeRequest.getCode()); 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
    @Transactional(rollbackFor = {BusinessException.class}) 
 | 
    public void pauseOpenElecBike(BackElecBikeRequest param) { 
 | 
        Member member = memberMapper.selectById(param.getMemberId()); 
 | 
        if (member == null) { 
 | 
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,您的账号信息查询失败,请返回重新进入小程序再试!"); 
 | 
        } 
 | 
        Goodsorder gparam = new Goodsorder(); 
 | 
        gparam.setMemberId(param.getMemberId()); 
 | 
        gparam.setStatus(Constants.goodsorderStatus.pay); 
 | 
        gparam.setType(Constants.ZERO); 
 | 
        Goodsorder goodsorder =  goodsorderService.findOne(gparam); 
 | 
        if(Objects.isNull(goodsorder)){ 
 | 
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有骑行中订单记录"); 
 | 
        } 
 | 
        //查询当前正在临停中的骑行记录 
 | 
        MemberRides memberRides = memberRidesJoinMapper.selectJoinOne(MemberRides.class,new MPJLambdaWrapper<MemberRides>() 
 | 
                .eq(MemberRides::getOrdreId,goodsorder.getId()) 
 | 
                .eq(MemberRides::getStatus,Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey()) 
 | 
                .selectAll(MemberRides.class) 
 | 
                .last("limit 1")); 
 | 
        if(memberRides ==null || memberRides.getBikeCode() == null){ 
 | 
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有临停中记录"); 
 | 
        } 
 | 
        Bikes bike = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda().eq(Bikes::getCode,memberRides.getBikeCode()) 
 | 
                .eq(Bikes::getIsdeleted,Constants.ZERO) 
 | 
                .eq(Bikes::getType,Constants.ONE) 
 | 
                .last(" limit 1 ") 
 | 
        ); 
 | 
        if(bike == null && StringUtils.isBlank(bike.getParamId())){ 
 | 
            //如果车辆类型是空 
 | 
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "车型信息异常,请联系管理员"); 
 | 
        } 
 | 
        this.lockBikes(bike.getDeviceSn(),0); 
 | 
        //更新骑行状态为骑行中 
 | 
        memberRides.setEditDate(memberRides.getBackDate()); 
 | 
        memberRides.setStatus(Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey()); 
 | 
        memberRidesJoinMapper.updateById(memberRides); 
 | 
    } 
 | 
  
 | 
  
 | 
    private boolean isValidePricingType(Bikes bike,MemberRides memberRides ) { 
 | 
        //查询车子电量信息 
 | 
        if(goodsorderService.getVoltageStatus(bike)>0){ 
 | 
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"电量低,请扫描其它车辆!"); 
 | 
        }; 
 | 
        Date date =new Date(); 
 | 
        QueryWrapper<PricingParam> param = new QueryWrapper<>(); 
 | 
        param.lambda().eq(PricingParam::getStatus,Constants.ZERO); 
 | 
        param.lambda().eq(PricingParam::getIsdeleted,Constants.ZERO); 
 | 
        param.lambda().le(PricingParam::getStartDate,date); 
 | 
        param.lambda().ge(PricingParam::getEndDate,date); 
 | 
        param.lambda().last(" limit 1" ) ; 
 | 
        param.lambda().orderByAsc(PricingParam::getSortnum); 
 | 
        //查询优先级最高(排序码最小的)可用配价方案 
 | 
        PricingParam pp = pricingParamMapper.selectOne(param); 
 | 
        if(pp == null){ 
 | 
            //如果车辆未设置配价方案,提示开锁失败! 
 | 
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), " 该车型暂时不能借车操作哦,请更换其他车型重试哦!"); 
 | 
        } 
 | 
        QueryWrapper<PricingDetail> detail = new QueryWrapper<>(); 
 | 
        detail.lambda().eq(PricingDetail::getBikeTypeId,bike.getParamId()); 
 | 
        detail.lambda().eq(PricingDetail::getPricePramId,pp.getId()); 
 | 
        detail.lambda().eq(PricingDetail::getIsdeleted,Constants.ZERO); 
 | 
        detail.lambda().last(" limit 1" ) ; 
 | 
        //查询优先级最高(排序码最小的)可用配价方案 
 | 
        PricingDetail pricingDetail = pricingDetailMapper.selectOne(detail); 
 | 
        if(pricingDetail == null){ 
 | 
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), " 该车型暂时不能借车操作哦,请更换其他车型重试哦~"); 
 | 
        } 
 | 
        String nowDate = DateUtil.getDateLong(date); 
 | 
        Holidays holidays = new Holidays(); 
 | 
        holidays.setHoliday(nowDate); 
 | 
        holidays.setIsdeleted(Constants.ZERO); 
 | 
        memberRides.setBikeCode(bike.getCode()); 
 | 
        memberRides.setParamId(bike.getParamId()); 
 | 
        bike.setLastRentDate(new Date()); 
 | 
        bike.setStatus(Constants.ONE); 
 | 
        bikesMapper.updateById(bike); 
 | 
        //检查是否节假日 
 | 
        if(holidaysMapper.selectCount(new QueryWrapper<>(holidays)) >0){ 
 | 
            //如果是节假日 
 | 
            memberRides.setBasePrice(pricingDetail.getHolidayBasePrice()); 
 | 
            memberRides.setBaseTime(pricingDetail.getHolidayBaseTime()); 
 | 
            memberRides.setUnitPrice(pricingDetail.getHolidayUnitPrice()); 
 | 
            memberRides.setUnitTime(pricingDetail.getHolidayUnitTime()); 
 | 
            memberRides.setIsHoliday(Constants.ONE); 
 | 
        }else{ 
 | 
            //如果是工作日 
 | 
            memberRides.setBasePrice(pricingDetail.getBasePrice()); 
 | 
            memberRides.setBaseTime(pricingDetail.getBaseTime()); 
 | 
            memberRides.setUnitPrice(pricingDetail.getUnitPrice()); 
 | 
            memberRides.setUnitTime(pricingDetail.getUnitTime()); 
 | 
            memberRides.setIsHoliday(Constants.ZERO); 
 | 
        } 
 | 
        return true; 
 | 
    } 
 | 
  
 | 
  
 | 
    /** 
 | 
     * 临时停车超时 自动还车 
 | 
     */ 
 | 
    public void autoBackBike() throws WxErrorException { 
 | 
       List<MemberRides> memberRidesList =  memberRidesJoinMapper.selectJoinList(MemberRides.class,new MPJLambdaWrapper<MemberRides>() 
 | 
                .selectAll(MemberRides.class) 
 | 
                .leftJoin(Goodsorder.class,Goodsorder::getId,MemberRides::getOrdreId) 
 | 
                .eq(Goodsorder::getStatus,Constants.ONE) 
 | 
                .eq(MemberRides::getIsdeleted,Constants.ZERO) 
 | 
                .eq(MemberRides::getType,Constants.ONE) 
 | 
                .eq(MemberRides::getStatus,Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey()) 
 | 
                .apply(" NOW() >= (t.create_date  + INTERVAL '"+systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME,Constants.PAUSE_AUTO_CLOSE_TIME).getCode()+" min') ") 
 | 
        ); 
 | 
  
 | 
        ; 
 | 
        for (MemberRides timeOutRides:memberRidesList) { 
 | 
            Goodsorder goodsorder = goodsorderService.findById(timeOutRides.getOrdreId()); 
 | 
            //查询骑行记录 
 | 
            List<MemberRides>  memberRides = goodsorderService.getMemberRidesForClose(goodsorder.getId()); 
 | 
            if(memberRides!=null && memberRides.size()>0){ 
 | 
                for (MemberRides  rides : memberRides){ 
 | 
                    if(Constants.equalsInteger(rides.getStatus(),Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey()) 
 | 
                            &&Constants.equalsInteger(rides.getType(),Constants.ONE)){ 
 | 
                        //如果是电车并且是骑行中 进行关锁处理 
 | 
                        Bikes bike = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda() 
 | 
                                .eq(Bikes::getType,Constants.ONE) 
 | 
                                .eq(Bikes::getIsdeleted,Constants.ZERO) 
 | 
                                .eq(Bikes::getCode,rides.getBikeCode()) 
 | 
                        ); 
 | 
                        lockBikes(bike.getDeviceSn(),Constants.ONE);//发起关锁指令请求 
 | 
                        rides.setStatus(Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey());//已还车 
 | 
                        rides.setBackSiteId(bike.getSiteId());//还车站点 
 | 
                        rides.setBackDate(new Date()); 
 | 
                        Integer freeRentTime = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode()); 
 | 
                        Integer rideTime = DateUtil.betweenMin(rides.getRentDate(), rides.getBackDate()); 
 | 
                        //计算骑行计费时长 
 | 
                        rides.setDuration( rideTime > freeRentTime  ? rideTime : 0 ); 
 | 
                        rides.setEditDate(rides.getBackDate()); 
 | 
                        memberRidesJoinMapper.updateById(rides);//更新骑行状态为已还车 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
            //订单结算 
 | 
            Date date = new Date(); 
 | 
            goodsorder.setEditDate(date); 
 | 
            goodsorder.setEditor(null); 
 | 
            goodsorderService.dealCloseGoodsorderBiz( goodsorder,Constants.REFUND_TYPE.NORMAL.getKey(),memberRides); 
 | 
  
 | 
            //更新电动车车辆状态 
 | 
            bikesMapper.update(null,new UpdateWrapper<Bikes>().lambda().set(Bikes::getStatus,Constants.ZERO).eq(Bikes::getType,Constants.ONE) 
 | 
                    .apply(" code in ( select m.bike_code from member_rides m where m.ordre_id = '"+goodsorder.getId()+"' ) ") 
 | 
            ); 
 | 
  
 | 
            //发送小程序通知 
 | 
            Member member = memberMapper.selectById(goodsorder.getMemberId()); 
 | 
            if(Objects.nonNull(member)&&StringUtils.isNotBlank(member.getOpenid())){ 
 | 
                sendWxMessage.bookingsCancel(member.getOpenid(),goodsorder.getId(), 
 | 
                        WxMiniConfig.wxMaService.getAccessToken(), 
 | 
                        timeOutRides.getBikeCode(),goodsorder.getPayDate(),goodsorder.getEditDate()); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
  
 | 
//    public void test(double lat,double lng){ 
 | 
//        this.getBackSiteByPostion(lat,lng); 
 | 
//    } 
 | 
  
 | 
  
 | 
} 
 |