| | |
| | | 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.ZERO);//发起关锁指令请求 |
| | | 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); |
| | | } |
| | | |
| | | 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); |
| | | 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 == 0){ |
| | | //如果仅限于园区临时停车 |
| | | 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.getLatitude().doubleValue(),bike.getLongitude().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(), " 该车型暂时不能借车操作哦,请更换其他车型重试!"); |
| | | } |
| | | 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(),1); |
| | | //存储骑行记录 |
| | | 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(),1); |
| | | //更新骑行状态为骑行中 |
| | | 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.ZERO);//发起关锁指令请求 |
| | | 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); |
| | | //发送小程序通知 |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |