1. 根据订单号查询车辆轨迹

2. 根据sn更新设备
This commit is contained in:
邱贞招 2024-08-26 16:26:06 +08:00
parent 381fd389ad
commit 073305c702
11 changed files with 316 additions and 11 deletions

View File

@ -870,6 +870,7 @@ public class AppVerifyController extends BaseController
/**
* 根据经纬度判断是否在停车区
*/
@Log(title = "判断是否在停车区", businessType = BusinessType.ISINPARKING)
@GetMapping("/isInParkingArea")
public AjaxResult isInParkingArea(String longitude,String latitude,String areaId,String sn)
{
@ -1337,4 +1338,17 @@ public class AppVerifyController extends BaseController
}
return toAjax(etOrderService.updateEtOrderByOrderNo(etOrder));
}
/**
* 更新设备最新信息
*/
@Log(title = "更新设备", businessType = BusinessType.REFRESH)
@PostMapping("/refreshDevice")
public AjaxResult refreshDevice(String sn)
{
if (StrUtil.isBlank(sn)){
throw new ServiceException("未传sn");
}
return toAjax(asDeviceService.refreshDeviceBySn(sn));
}
}

View File

@ -296,5 +296,22 @@ public class AsDeviceController extends BaseController
return ajax;
}
/**
* 根据订单号查询车辆轨迹
*/
@PostMapping("/trajectoryByOrderNo")
public AjaxResult trajectoryByOrderNo(String orderNo)
{
AjaxResult ajax = AjaxResult.success();
if(StrUtil.isBlank(orderNo)){
logger.info("没有orderNo号参数【orderNo={}】",orderNo);
return error("请传订单号参数"+"【orderNo="+orderNo+"");
}
logger.info("【根据订单号查询车辆轨迹】orderNo={}",orderNo);
String trajectory = asDeviceService.trajectoryByOrderNo(orderNo);
ajax.put(AjaxResult.DATA_TAG,trajectory);
return ajax;
}
}

View File

@ -168,6 +168,11 @@ public enum BusinessType
*/
REBOOT,
/**
* 根据经纬度判断是否在停车区
*/
ISINPARKING,
/**
* 绑定
*/

View File

@ -5,8 +5,10 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.map.GpsCoordinateUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
@ -177,4 +179,52 @@ public class CommonUtil {
log.info("根据百分比计算出的电压:{}V",add);
return add.intValue();
}
/** 坐标转换 */
@NotNull
public static double[] coordinateConvert(String lon1, String lat1) {
BigDecimal lon = new BigDecimal(lon1);
BigDecimal lat = new BigDecimal(lat1);
// log.info("WGS84经纬度未计算" + lon + "---" + lat);
// 除以100
lon = lon.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
lat = lat.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
// 取出lon中后面的小数点
String[] lonStr = getDecimalPart(lon);
String[] latStr = getDecimalPart(lat);
// log.info("WGS84经纬度截取小数点" + lonStr[0] + "---" + lonStr[1] + "---"+ latStr[0]+"---"+ latStr[1]);
// 再将结果乘以5/3
String lon2 = "0."+ lonStr[1];
String lat2 = "0."+ latStr[1];
BigDecimal lons = new BigDecimal(lon2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
BigDecimal lats = new BigDecimal(lat2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
BigDecimal lo = new BigDecimal(lonStr[0]).add(lons);
BigDecimal la = new BigDecimal(latStr[0]).add(lats);
// log.info("WGS84经纬度计算后" + lo + "---" + la);
lo = lo.setScale(8, RoundingMode.HALF_UP);
la = la.setScale(8, RoundingMode.HALF_UP);
// log.info("WGS84经纬度保留8为小数" + lo + "---" + la);
double[] doubles = GpsCoordinateUtils.calWGS84toGCJ02(la.doubleValue(), lo.doubleValue());
return doubles;
}
public static String[] getDecimalPart(BigDecimal number) {
// 将BigDecimal转换为字符串
String numberStr = number.toPlainString();
// 找到小数点的位置
int indexOfDecimal = numberStr.indexOf(".");
// 初始化结果数组
String[] parts = new String[2];
// 如果有小数点
if (indexOfDecimal >= 0) {
parts[0] = numberStr.substring(0, indexOfDecimal); // 整数部分
parts[1] = numberStr.substring(indexOfDecimal + 1); // 小数部分
} else {
// 如果没有小数点整数部分为整个字符串小数部分为空
parts[0] = numberStr;
parts[1] = "";
}
return parts;
}
}

View File

@ -0,0 +1,21 @@
package com.ruoyi.common.utils.onenet;
import lombok.Data;
@Data
public class LocationVo {
private String lon;//经度
private String lat;//纬度
private Integer status;//电动车状态 0断电1上电运行 2轮动抱死 3超出区域断电远程下发了qlose
private Integer bat;//电池电压 "bat":571 ==> 57.1V
private Integer csq;//信号强度
private Integer s;//卫星数量
private Integer q;//质量
}

View File

@ -140,6 +140,14 @@ public interface IAsDeviceService extends IService<AsDevice>
*/
int refreshDevice(Long[] deviceIds);
/**
* 更新设备
*
* @param deviceIds 需要更新设备的设备主键集合
* @return 结果
*/
int refreshDeviceBySn(String sn);
/**
* 删除设备信息
*
@ -377,11 +385,21 @@ public interface IAsDeviceService extends IService<AsDevice>
*/
boolean updateVersion(String sn);
/**
* 更新最新的位置信息
*/
boolean updateLatestLocation(String sn);
/**
* 根据时间查询车辆轨迹
*/
String trajectory(String sn,String startTime,String endTime);
/**
* 根据订单号查询车辆轨迹
*/
String trajectoryByOrderNo(String orderNo);
// /**
// * 是否靠近运营区边界
// */

View File

@ -8,7 +8,10 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.*;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.CommonUtil;
@ -42,7 +45,10 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -591,10 +597,46 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
}else{
log.info("设备【"+device.getSn()+"】更新版本失败");
}
// 最新位置信息
if(updateLatestLocation(device.getSn())){
log.info("设备【"+device.getSn()+"】更新位置成功");
}else{
log.info("设备【"+device.getSn()+"】更新位置失败");
}
}
return 1;
}
/**
* 根据sn更新设备
* @param sn sn
* @return 结果
*/
@Override
public int refreshDeviceBySn(String sn)
{
AsDevice device = asDeviceMapper.selectAsDeviceBySn(sn);
//设备是否在线
if(isOnline(device.getSn())){
log.info("设备【"+device.getSn()+"】在线");
}else{
log.info("设备【"+device.getSn()+"】不在线");
}
if(updateVersion(device.getSn())){
log.info("设备【"+device.getSn()+"】更新版本成功");
}else{
log.info("设备【"+device.getSn()+"】更新版本失败");
}
// 最新位置信息
if(updateLatestLocation(device.getSn())){
log.info("设备【"+device.getSn()+"】更新位置成功");
}else{
log.info("设备【"+device.getSn()+"】更新位置失败");
}
return 1;
}
/**
* 删除设备信息
*
@ -680,6 +722,13 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
EtModel model = etModelService.selectEtModelByModelId(modelId);
if(ObjectUtil.isNotNull(model)){
asDevice.setModel(model.getModel());
Integer remainingMileage = 0;
if(StrUtil.isNotBlank(asDevice.getVoltage())){
remainingMileage = CommonUtil.getRemainingMileage(asDevice.getVoltage(), model.getFullVoltage(), model.getLowVoltage(), model.getFullEndurance());
}
Integer electricQuantity = CommonUtil.getElectricQuantity(asDevice.getVoltage(), model.getFullVoltage(), model.getLowVoltage());//电量百分百
asDevice.setRemainingMileage(remainingMileage);
asDevice.setRemainingPower(electricQuantity.toString());
}
}
}
@ -2504,6 +2553,8 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
log.info("【查询数据点】===>更新版本失败");
}
}
}else{
}
}
}
@ -2546,6 +2597,45 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
return trajectoryStr.toString();
}
/**
* 根据时间查询车辆轨迹
*/
@Override
public String trajectoryByOrderNo(String orderNo) {
EtOrder order = etOrderMapper.selectEtOrderByOrderNo(orderNo);
String endTime;
if(ObjectUtil.isNull(order.getReturnTime())){
endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate());
}else{
endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, order.getReturnTime());
}
String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, order.getUnlockTime());
List<EtLocationLog> etLocationLogs = etLocationLogMapper.selectEtLocationLogListByCreateTime(order.getDeviceMac(), startTime, endTime);
// 将etLocationLogs中的longitude和latitude 转换成 [[120.2534,27.1048],[120.2556,27.1051],[120.2569,27.1057]] 这样的格式
List<double[]> coordinatesList = new ArrayList<>();
for (EtLocationLog log : etLocationLogs) {
double longitude = Double.parseDouble(log.getLongitude());
double latitude = Double.parseDouble(log.getLatitude());
coordinatesList.add(new double[]{longitude, latitude});
}
StringBuilder trajectoryStr = new StringBuilder();
int size = coordinatesList.size();
trajectoryStr.append("["); // 在循环之前添加一个 "["
for (int i = 0; i < size; i++) {
double[] coordinate = coordinatesList.get(i);
trajectoryStr.append("[").append(coordinate[0]).append(", ").append(coordinate[1]).append("]");
if (i < size - 1) {
trajectoryStr.append(",");
}
}
trajectoryStr.append("]"); // 在循环之后添加一个 "]"
return trajectoryStr.toString();
}
/**
* sn和mac号绑定
@ -2590,6 +2680,86 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
}
/**
* 更新最新的位置信息
*/
@Override
@SneakyThrows
public boolean updateLatestLocation(String sn) {
AsDevice device = asDeviceMapper.selectAsDeviceBySn(sn);
if(device!=null){
String version = device.getVersion();
if(StrUtil.isBlank(version)){
String token = Token.getToken();
DataPointRes datapoints = historyDatapoints(asDeviceMapper.selectAsDeviceBySn(sn).getMac(), token);
if(datapoints.getCode() == 0){
Data data = datapoints.getData();
List<Datastream> datastreams = data.getDevices();
for (Datastream datastream: datastreams) {
List<Datapoint> datapointList = datastream.getDatastreams();
if(ObjectUtil.isNotNull(datapointList)){
for (Datapoint datapoint:datapointList) {
if(datapoint.getId().equals(IotConstants.ONENET_LOCATION)){
String string = JSON.toJSONString(datapoint.getValue());
if(StrUtil.isNotBlank(string)){
LocationVo locationVo = JSONObject.parseObject(string, LocationVo.class);
log.info("【手动更新】: locationVo---【{}】" , JSON.toJSONString(locationVo));
double[] doubles = CommonUtil.coordinateConvert(locationVo.getLon(), locationVo.getLat());
BigDecimal lat = new BigDecimal(doubles[0]).setScale(8, RoundingMode.HALF_UP);
BigDecimal lon = new BigDecimal(doubles[1]).setScale(8, RoundingMode.HALF_UP);
log.info("转换后的GCJ02经纬度" + lon + "---" + lat);
/** 计算电量和里程后更新设备*/
int i = updateDevice(locationVo, device, lon, lat);
if(i > 0){
log.info("【手动更新】===>更新设备成功");
return true;
}else{
log.info("【手动更新】===>更新设备失败");
return false;
}
}
}
}
}
}
}
}
}
return false;
}
/** 计算电量和里程后更新设备*/
public int updateDevice(LocationVo locationVo, AsDevice device, BigDecimal lon, BigDecimal lat) {
device.setLatitude(lat.toString());
device.setLongitude(lon.toString());
Integer bat = locationVo.getBat();
BigDecimal divide = new BigDecimal(bat).divide(new BigDecimal(10));
log.info("保存电压:" + divide);
device.setVoltage(divide.toString());//电压
// 根据电压计算续航里程
EtModel model = etModelService.selectEtModelByModelId(device.getModelId());
if(ObjectUtil.isNotNull(model)){
Integer remainingMileage = 0;
if(StrUtil.isNotBlank(device.getVoltage())){
remainingMileage = CommonUtil.getRemainingMileage(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage(), model.getFullEndurance());
}
Integer electricQuantity = CommonUtil.getElectricQuantity(device.getVoltage(), model.getFullVoltage(), model.getLowVoltage());//电量百分百
device.setRemainingMileage(remainingMileage);
device.setRemainingPower(electricQuantity.toString());
}
device.setLastTime(DateUtils.getNowDate());
device.setLastLocationTime(DateUtils.getNowDate());
device.setGps("1");
// 信号强度
device.setSignalStrength(locationVo.getCsq());
device.setSatellites(locationVo.getS());
device.setQuality(locationVo.getQ());
int i = updateLocation(device);
return i;
}
/**
* 判断是否靠近边界
*/

View File

@ -467,12 +467,12 @@ public class AsUserServiceImpl implements IAsUserService
public Boolean checkIsDeposit(Long userId) {
AsUser asUser = asUserMapper.selectUserById(userId);
BigDecimal balance = asUser.getBalance();
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(Long.parseLong(asUser.getAreaId()));
BigDecimal deposit = new BigDecimal(area.getDeposit());
if(deposit.compareTo(BigDecimal.ZERO)==0){//押金为0直接返回true
log.info("运营区【{}】押金为0",area.getAreaName());
return true;
}
// EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(Long.parseLong(asUser.getAreaId()));
// BigDecimal deposit = new BigDecimal(area.getDeposit());
// if(deposit.compareTo(BigDecimal.ZERO)==0){//押金为0直接返回true
// log.info("运营区【{}】押金为0",area.getAreaName());
// return true;
// }
if(ObjectUtil.isNull(balance)){
log.info("用户【{}】余额为空",userId);
return false;

View File

@ -134,6 +134,15 @@ public class EtOrderServiceImpl implements IEtOrderService
AsDevice device = asDeviceMapper.selectAsDeviceBySn(order.getSn());
order.setDevice(device);
EtFeeRule etFeeRule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
String endTime;
if(ObjectUtil.isNull(order.getReturnTime())){
endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate());
}else{
endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, order.getReturnTime());
}
String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, order.getUnlockTime());
String trajectory = deviceService.trajectory(order.getSn(), startTime, endTime);
order.setTripRouteStr(trajectory);
order.setRule(etFeeRule);
//行程记录
EtTripLog tripLog = new EtTripLog();

View File

@ -111,7 +111,7 @@ public class WxPayService implements IWxPayService {
}
String outTradeNo = IdUtils.getOrderNo("wx");
order.setOutTradeNo(outTradeNo);
order.setLocking("1");
// order.setLocking("1");
int updateEtOrder = etOrderService.updateEtOrder(order);
if(updateEtOrder == 0){
throw new ServiceException("更新订单outTradeNo失败");

View File

@ -37,12 +37,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<if test="mac != null and mac != ''"> and mac = #{mac}</if>
<if test="startTime != null and startTime != ''">
AND date_format(create_time,'%Y%m%d%H%i%s') &gt;= date_format(#{startTime},'%Y%m%d%H%i%s')
AND date_format(`AT`,'%Y%m%d%H%i%s') &gt;= date_format(#{startTime},'%Y%m%d%H%i%s')
</if>
<if test="endTime != null and endTime != ''">
AND date_format(create_time,'%Y%m%d%H%i%s') &lt;= date_format(#{endTime},'%Y%m%d%H%i%s')
AND date_format(`AT`,'%Y%m%d%H%i%s') &lt;= date_format(#{endTime},'%Y%m%d%H%i%s')
</if>
</where>
order by `AT`
</select>
<select id="selectEtLocationLogByLocationId" parameterType="Long" resultMap="EtLocationLogResult">