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.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.WxMiniUtilService;
|
import com.doumee.dao.business.*;
|
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.jtt808.web.endpoint.MessageManager;
|
import com.doumee.service.business.GoodsorderService;
|
import com.doumee.service.business.PricingRuleService;
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
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;
|
|
@Service
|
public class Jtt808Service {
|
@Autowired
|
private MessageManager messageManager;
|
@Autowired
|
private GoodsorderService goodsorderService;
|
@Autowired
|
private BikesMapper bikesMapper;
|
|
@Autowired
|
private DiscountMemberMapper discountMemberMapper;
|
|
@Autowired
|
private DiscountLogMapper discountLogMapper;
|
|
@Autowired
|
GoodsorderJoinMapper goodsorderJoinMapper;
|
|
@Autowired
|
private SystemDictDataBiz systemDictDataBiz;
|
|
@Autowired
|
private MemberMapper memberMapper;
|
@Autowired
|
private BaseParamMapper baseParamMapper;
|
@Autowired
|
private RefundMapper refundMapper;
|
|
@Autowired
|
private RefundJoinMapper refundJoinMapper;
|
@Autowired
|
private SitesMapper sitesMapper;
|
|
@Autowired
|
private MemberRidesJoinMapper memberRidesJoinMapper;
|
|
@Autowired
|
private AdMapper adMapper;
|
|
@Autowired
|
private TransactionsMapper transactionsMapper;
|
|
@Autowired
|
private WxMiniUtilService wxMiniUtilService;
|
|
@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;
|
}
|
|
@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);
|
Goodsorder goodsorder = goodsorderService.findOne(gparam);
|
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());
|
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.leftPad(clientId,12,'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(lat,lng,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);
|
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) {
|
Date date = new Date();
|
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));
|
}
|
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()));
|
}
|
}
|
}
|