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.LambdaQueryWrapper; 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.dao.business.web.response.UserResponse; 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 lombok.extern.slf4j.Slf4j; 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 @Slf4j 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 bikeControl(@RequestBody T8500 request) { Mono> result = messageManager.requestR(request, T0201_0500.class); APIResult 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 = goodsorderService.getMemberRidesForClose(goodsorder.getId()); List 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().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().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> result = messageManager.requestR(request, T0201_0500.class); APIResult 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 sitesList = sitesMapper.selectList(new QueryWrapper().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 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() .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 array = new ArrayList<>(); try { TypeReference typeReference = new TypeReference>(){}; 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 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().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().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) 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().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.getBikeStatus(),Constants.ONE)){ 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() .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().lambda().eq(MemberRides::getOrdreId,goodsorder.getId())) > Constants.ZERO) { throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "已骑行其他车辆,无法扫码,请结算后重新尝试"); } //判断是否处于营业时间 goodsorderService.checkBusiness(); //查询是否处于骑行中 if (memberRidesJoinMapper.selectCount(new QueryWrapper().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() .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().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 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 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 memberRidesList = memberRidesJoinMapper.selectJoinList(MemberRides.class,new MPJLambdaWrapper() .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 = 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().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().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 String updateLockStatusBatch(UserResponse user, List idList, Integer lockStatus) { if(idList ==null && idList.size()==0){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } String message = ""; int sNum =0,eNum=0,ingNum=0; lockStatus = lockStatus==0?0:1; List bikesList = bikesMapper.selectList(new LambdaQueryWrapper() .eq(Bikes::getType,Constants.ONE) .in(Bikes::getIsdeleted,Constants.ZERO) .in(Bikes::getId,idList) ); for(Bikes bike: bikesList){ if(Constants.equalsInteger(bike.getStatus(),Constants.ONE)){ //出借中 ingNum++; continue; } boolean r = true; try { this.lockBikes(bike.getDeviceSn(),lockStatus==0?1:0); }catch (Exception e){ log.error(e.getMessage()); r =false; eNum++; } if(r){ bikesMapper.update(null,new UpdateWrapper().lambda() .set(Bikes::getEditDate,new Date()) .set(Bikes::getEditor,user.getId()) .set(Bikes::getLockStatus,lockStatus) .set(Bikes::getIsdeleted,Constants.ZERO) .eq(Bikes::getType,Constants.ONE ) .eq(Bikes::getId,bike.getId())); sNum++; } } message="成功操作["+sNum+"]辆电车"; if(ingNum>0){ message = message+",["+ingNum+"]辆电车正出借中"; } if(eNum>0){ message = message+",["+eNum+"]辆电车远程操作失败"; } return message; } }