Compare commits

...

16 Commits

Author SHA1 Message Date
bb9e0de398 1. 计费方式跟着订单走,修改收费模版也不影响前面的订单 2024-09-04 08:43:06 +08:00
24383a9cd9 1. 优惠券增加描述、原件 2024-09-03 18:01:27 +08:00
ec1af23e89 1. 优化经纬度相同的定位,不插入 2024-09-03 17:25:46 +08:00
bea016d61c 1. 优惠券调整 2024-09-03 16:49:47 +08:00
f43e93f7fa 1. 优惠券调整 2024-09-03 15:57:22 +08:00
b046963a42 1. 优惠券调整 2024-09-03 15:54:11 +08:00
91da8794ed 1. 调整 2024-09-03 08:53:47 +08:00
59c308668a 1. 调整 2024-09-02 17:16:26 +08:00
df9c586af9 Merge branch 'redis'
# Conflicts:
#	electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java
2024-09-02 16:41:28 +08:00
ec42f42704 1. 增加冷却时间 2024-09-02 16:38:18 +08:00
426608a239 1. 调整日志 2024-09-02 14:38:49 +08:00
1b4833fde2 1. 定时任务调整 2024-09-02 08:54:03 +08:00
c115f0ef62 1. 相差一分钟以上的消息不做处理 2024-08-31 16:19:13 +08:00
67ef07c021 1. 靠近运营区边沿 2024-08-31 09:22:50 +08:00
05af4cecba 1. 心跳的逻辑移到redis中 2024-08-29 15:18:01 +08:00
d2bc7617a6 1. 心跳的逻辑移到redis中 2024-08-28 21:43:56 +08:00
31 changed files with 923 additions and 374 deletions

View File

@ -686,6 +686,11 @@ public class AppController extends BaseController
@GetMapping("/couponList")
public AjaxResult list(EtCoupon etCoupon)
{
if(etCoupon.getType().contains(",")){
String[] typeList = etCoupon.getType().split(",");
etCoupon.setTypeList(typeList);
etCoupon.setType(null);
}
List<EtCoupon> list = etCouponService.selectEtCouponList(etCoupon);
return success(list);
}

View File

@ -185,6 +185,9 @@ public class AppVerifyController extends BaseController
if(order.getRuleId()==null){
return error("=============================================ruleId未传=============================================");
}
if(order.getUserId()==null){
return error("=============================================userId未传=============================================");
}
// 判断该订单是否已结束
EtOrder etOrder = etOrderService.selectEtOrderByOrderNo(order.getOrderNo());
if(ObjectUtil.isNotNull(etOrder)){
@ -1299,31 +1302,45 @@ public class AppVerifyController extends BaseController
}
/**
* 根据用户搜索优惠券
* 我的骑行卡(未使用)
*/
@GetMapping("/getCouponListByUserId")
public AjaxResult list(Long userId)
public AjaxResult getCouponListByUserId(Long userId)
{
logger.info("根据用户搜索优惠券【userId="+userId+"");
EtCouponClaimLog etCouponClaimLog = new EtCouponClaimLog();
etCouponClaimLog.setUserId(userId);
etCouponClaimLog.setStatus(ServiceConstants.COUPON_STATUS_UNUSED);
etCouponClaimLog.setStatusList(new String[]{ServiceConstants.COUPON_STATUS_UNUSED, ServiceConstants.COUPON_STATUS_EXPIRED});
List<EtCouponClaimLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponClaimLog);
EtCouponUserLog etCouponUserLog = new EtCouponUserLog();
etCouponUserLog.setUserId(userId);
etCouponUserLog.setStatus(ServiceConstants.COUPON_STATUS_UNUSED);
etCouponUserLog.setStatusList(new String[]{ServiceConstants.COUPON_STATUS_UNUSED, ServiceConstants.COUPON_STATUS_EXPIRED});
List<EtCouponUserLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponUserLog);
return success(list);
}
/**
* 优惠券使用记录
* 优惠券使用记录已使用
*/
@GetMapping("/getCouponUsageRecord")
public AjaxResult getCouponUsageRecord(Long userId)
{
logger.info("优惠券使用记录【userId="+userId+"");
EtCouponClaimLog etCouponClaimLog = new EtCouponClaimLog();
etCouponClaimLog.setUserId(userId);
etCouponClaimLog.setStatus(ServiceConstants.COUPON_STATUS_USED);
List<EtCouponClaimLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponClaimLog);
logger.info("【优惠券使用记录已使用【userId="+userId+"");
EtCouponUserLog etCouponUserLog = new EtCouponUserLog();
etCouponUserLog.setUserId(userId);
etCouponUserLog.setStatus(ServiceConstants.COUPON_STATUS_USED);
List<EtCouponUserLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponUserLog);
return success(list);
}
/**
* 优惠券购买记录
*/
@GetMapping("/couponBuyRecord")
public AjaxResult couponBuyRecord(Long userId)
{
logger.info("【优惠券购买记录】【userId="+userId+"");
EtCouponUserLog etCouponUserLog = new EtCouponUserLog();
etCouponUserLog.setUserId(userId);
etCouponUserLog.setGainMethod(ServiceConstants.COUPON_GAIN_METHOD_BUY);
List<EtCouponUserLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponUserLog);
return success(list);
}

View File

@ -1,29 +1,32 @@
package com.ruoyi.web.controller.iot.receive;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.map.GeoUtils;
import com.ruoyi.common.utils.map.GpsCoordinateUtils;
import com.ruoyi.common.utils.onenet.LogEntry;
import com.ruoyi.common.utils.onenet.Token;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.EtLocationLogMapper;
import com.ruoyi.system.domain.AsDevice;
import com.ruoyi.system.domain.EtAdminOrder;
import com.ruoyi.system.domain.EtOnlineLog;
import com.ruoyi.system.domain.EtOperatingArea;
import com.ruoyi.system.mapper.AsDeviceMapper;
import com.ruoyi.system.service.*;
import com.ruoyi.web.controller.iot.domain.BodyObj;
import com.ruoyi.web.controller.iot.domain.LogEntry;
import com.ruoyi.web.controller.iot.util.Util;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.locationtech.jts.geom.Geometry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -37,7 +40,8 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@ -56,12 +60,11 @@ public class ReceiveController {
@Value(value = "${iot.token}")
private String token;
@Resource
private IAsDeviceService asDeviceService;
@Autowired
private IEtModelService etModelService;
@Resource
private AsDeviceMapper asDeviceMapper;
@Resource
private IEtOperatingAreaService etOperatingAreaService;
@ -81,18 +84,21 @@ public class ReceiveController {
@Autowired
private IEtOnlineLogService etOnlineLogService;
@Resource
private EtLocationLogMapper etLocationLogMapper;
private final Object lock = new Object();
@Autowired
private RedisCache redisCache;
@Autowired
private ISysConfigService sysConfigService;
// 用于记录上次发送命令的时间
private static AtomicLong lastCommandTime = new AtomicLong(0);
private static final long COMMAND_COOLDOWN_MS = 5 * 60 * 1000; // 5分钟
private static final Map<String, Long> commandCooldownMap = new ConcurrentHashMap<>();
private static final long COOLDOWN_PERIOD_MS = 10000; // 冷却时间为 10
/**
* 功能描述第三方平台数据接收<p>
@ -113,29 +119,22 @@ public class ReceiveController {
log.info("receive方法接收到参数: body String --- " +body);
/************************************************
* 解析数据推送请求非加密模式
* 如果是明文模式使用以下代码 hangdleBody(body, false); ChatGPT is under heavy load
* 如果是明文模式使用以下代码 hangdleBody(body, false);
**************************************************/
/*************明文模式 start****************/
BodyObj obj = Util.resolveBody(body, false);
log.info("receive方法解析对象: body Object --- " + JSON.toJSONString(obj));
log.info("接收到receive方法时间: " + System.currentTimeMillis());
/** */
// 起一个异步线程处理数据
scheduledExecutorService.schedule(() -> {
new Thread(() -> {
synchronized (lock) {
try {
handleBody(obj);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
// 使用线程池提交任务
scheduledExecutorService.submit(() -> {
synchronized (lock) {
try {
handleBody(obj);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}).start();
}, 0, TimeUnit.SECONDS);
}
});
/*************明文模式 end****************/
return "ok";
}
@ -144,160 +143,143 @@ public class ReceiveController {
if (obj != null){
boolean dataRight = Util.checkSignature(obj, token);
// elec_device_设备id_info:{ccccccc}
// 1. handleBody中的所有保存数据库的操作全部保存在redis中
// 2. 定时任务更新设备的在线状态, 5秒一次
// 3. 定时任务更新设备的定位和电压, 5秒一次
// 4. 定时任务插入onenet定位信息, 5秒一次
// 5. 获取最新的定位从redis中获取
if (dataRight){
// 记录开始时间
long startTime = System.nanoTime();
log.info("receive方法验证签名正确: content" + JSON.toJSONString(obj));
String msg = (String) obj.getMsg();
log.info("receive方法-获取到消息体: msg---" +msg);
JSONObject jsonObject = JSONObject.parseObject(msg, JSONObject.class);
String devName = (String)jsonObject.get("dev_name");
/*异步更新在线状态*/
AsDevice asDevice = asDeviceService.selectAsDeviceByMac(devName);
AsDevice asDevice = asDeviceMapper.selectAsDeviceByMac(devName);
asynchronousUpdateOnlineStatus(asDevice);
if(IotConstants.ONENET_LOCATION.equals(jsonObject.get("ds_id")) && ObjectUtil.isNotNull(jsonObject.get("value"))){
LogEntry logEntry = JSONObject.parseObject(msg, LogEntry.class);
log.info("logEntry转换后的对象: logEntry---【{}】" , JSON.toJSONString(logEntry));
LogEntry.LocationValue value = logEntry.getValue();
/**如果是定位日志则获取到车辆mac找到对应车辆
* 1.更新车辆定位计算续航里程
* 2.判断是否在禁行区内如果在根据配置禁行区内断电配置进行断电
* 3.超出运营区外断电
* 4.行程线路添加更新订单中的trip_route字段
* 5.低于电量%不得骑行声音播报
* 6.低电量 生成换电工单
* 7.运营边界判断
* */
/** 1.更新车辆定位、电压;计算续航里程 */
AsDevice device = asDeviceService.selectAsDeviceByMac(logEntry.getDevName());
if(ObjectUtil.isNull(device)){
if(ObjectUtil.isNull(asDevice)){
throw new ServiceException("未找到车辆信息");
}
if(ObjectUtil.isNotNull(device)){
if(ObjectUtil.isNotNull(asDevice)){
// 将msg的定位信息保存到redis中
redisCache.setCacheObject(CacheConstants.CACHE_DEVICE_KEY+asDevice.getSn(),msg);
log.info("reids更新定位成功==========================>" +asDevice.getSn());
// 坐标转换 WGS84 GCJ02
double[] doubles = coordinateConvert(value);
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);
asynchronousSaveLog(msg,logEntry.getAt(),devName, lon,lat,device);
if(BigDecimal.ZERO.compareTo(lon) != 0 && BigDecimal.ZERO.compareTo(lat) != 0){
// 计算电量和里程后更新设备
int i = updateDevice(value, device, lon, lat);
if(i>0){
log.info("更新定位成功==========================>" +logEntry.getDevName());
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(device.getAreaId());
if(ObjectUtil.isNotNull(area)){
/** 2. 判断是否在禁行区内 如果在, 根据配置‘禁行区内断电配置’进行断电 **/
String isAdminUnlocking = device.getIsAdminUnlocking();// 是否是管理员开锁0-1-
boolean noRidingArea = isNoRidingArea(value, device, area, isAdminUnlocking);
/** 3.超出运营区外断电*/
outAreaOutage(value, device, lon, lat, area, isAdminUnlocking, noRidingArea);
/** 4.锁同步关锁 */
lockSynchronization(msg, asDevice, logEntry, value, device, lon, lat);
/** 5.低电量 生成换电工单*/
replacementOrder(device, area);
}
}else{
log.info("更新定位失败:" +logEntry.getDevName());
}
}else{
log.info("----------------无定位更新设备----------------" + logEntry.getDevName());
noLocationUpdateDevice(logEntry, value, device);
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(asDevice.getAreaId());
// 相差一分钟以上的消息不做处理
boolean oneMinuteDifference = DateUtils.oneMinuteDifference(logEntry.getAt(), System.currentTimeMillis());
if(ObjectUtil.isNotNull(area) && !oneMinuteDifference){
/** 2. 判断是否在禁行区内 如果在, 根据配置‘禁行区内断电配置’进行断电 **/
String isAdminUnlocking = asDevice.getIsAdminUnlocking();// 是否是管理员开锁0-1-
boolean noRidingArea = isNoRidingArea(value, asDevice, area, isAdminUnlocking);
/** 3.超出运营区外断电 包含靠近运营区播报 */
outAreaOutage(value, asDevice, lon, lat, area, isAdminUnlocking, noRidingArea);
/** 4.锁同步关锁 */
lockSynchronization(msg, asDevice, logEntry, value, asDevice, lon, lat);
/** 5.低电量 生成换电工单*/
replacementOrder(asDevice, area);
}
}else{
log.info("未找到车辆对象:" +logEntry.getDevName());
}
}
// 计算执行时间以毫秒为单位
long duration = (System.nanoTime() - startTime) / 1_000_000;
// 输出执行时间
log.info("===============回调方法执行时间============= " + duration + " 毫秒");
}else {
log.info("receive方法验证签名错误: signature error");
}
}else {
log.info("receive方法参数为空: body empty error");
}
}
/**
* 异步保存定位
*/
private void asynchronousSaveLog(String msg, long at,String mac,BigDecimal lon,BigDecimal lat,AsDevice device) {
//异步保存定位
scheduledExecutorService.schedule(() -> {
EtLocationLog etLocationLog = new EtLocationLog();
etLocationLog.setOnenetMsg(msg);
etLocationLog.setCreateTime(DateUtils.getNowDate());
etLocationLog.setLongitude(lon.toString());
etLocationLog.setLatitude(lat.toString());
etLocationLog.setMac(mac);
etLocationLog.setAt(new Date(at));
etLocationLog.setStatus(device.getStatus());
etLocationLog.setLockStatus(device.getLockStatus());
etLocationLogMapper.insertEtLocationLog(etLocationLog);
}, 0, TimeUnit.SECONDS);
}
/** 无定位更新设备 */
private void noLocationUpdateDevice(LogEntry logEntry, LogEntry.LocationValue value, AsDevice device) {
Integer bat = value.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.setGps("0");
device.setSignalStrength(value.getCsq());
device.setSatellites(0);
device.setQuality(value.getQ());
int i = asDeviceService.updateLocation(device);
if(i>0){
log.info("未获取到定位===============保存电压等数值成功===========>" + logEntry.getDevName());
}
}
/** 计算电量和里程后更新设备*/
private int updateDevice(LogEntry.LocationValue value, AsDevice device, BigDecimal lon, BigDecimal lat) {
device.setLatitude(lat.toString());
device.setLongitude(lon.toString());
Integer bat = value.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(value.getCsq());
device.setSatellites(value.getS());
device.setQuality(value.getQ());
int i = asDeviceService.updateLocation(device);
return i;
}
// 移动到定时任务中处理
// /**
// * 异步保存定位
// */
// private void asynchronousSaveLog(String msg, long at,String mac,BigDecimal lon,BigDecimal lat,AsDevice device) {
// //异步保存定位
// scheduledExecutorService.schedule(() -> {
// EtLocationLog etLocationLog = new EtLocationLog();
// etLocationLog.setOnenetMsg(msg);
// etLocationLog.setCreateTime(DateUtils.getNowDate());
// etLocationLog.setLongitude(lon.toString());
// etLocationLog.setLatitude(lat.toString());
// etLocationLog.setMac(mac);
// etLocationLog.setAt(new Date(at));
// etLocationLog.setStatus(device.getStatus());
// etLocationLog.setLockStatus(device.getLockStatus());
// etLocationLogMapper.insertEtLocationLog(etLocationLog);
// }, 0, TimeUnit.SECONDS);
// }
//
// /** 无定位更新设备 */
// private void noLocationUpdateDevice(LogEntry logEntry, LogEntry.LocationValue value, AsDevice device) {
// Integer bat = value.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.setGps("0");
// device.setSignalStrength(value.getCsq());
// device.setSatellites(0);
// device.setQuality(value.getQ());
// int i = asDeviceService.updateLocation(device);
// if(i>0){
// log.info("未获取到定位===============保存电压等数值成功===========>" + logEntry.getDevName());
// }
// }
//
// /** 计算电量和里程后更新设备*/
// private int updateDevice(LogEntry.LocationValue value, AsDevice device, BigDecimal lon, BigDecimal lat) {
// device.setLatitude(lat.toString());
// device.setLongitude(lon.toString());
// Integer bat = value.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(value.getCsq());
// device.setSatellites(value.getS());
// device.setQuality(value.getQ());
// int i = asDeviceService.updateLocation(device);
// return i;
// }
/** 坐标转换 */
@NotNull
@ -330,44 +312,87 @@ public class ReceiveController {
/** 超出运营区断电*/
private void outAreaOutage(LogEntry.LocationValue value, AsDevice device, BigDecimal lon, BigDecimal lat, EtOperatingArea area, String isAdminUnlocking, boolean noRidingArea) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
boolean isAreaZone = asDeviceService.isAreaZone(device.getSn(), area);
if(!isAreaZone){
//是否在30米范围内
boolean inPolygon = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), GeoUtils.fromWkt(area.getBoundary()), 60);
if(inPolygon && !isAdminUnlocking.equals("1")){
String nearBoundaryDistanceConfig = sysConfigService.selectConfigByKey("near.boundary.distance");// 靠近运营区边界时的播报距离
log.info("靠近运营区边界时的播报距离==================" + nearBoundaryDistanceConfig);
double nearBoundaryDistance = Double.parseDouble(nearBoundaryDistanceConfig);
String exceedArea = sysConfigService.selectConfigByKey("exceed.area.distance");// 超出运营区外断电距离
log.info("超出运营区外断电距离================" + exceedArea);
int exceedDistance = Integer.parseInt(exceedArea);
// 创建多边形对象
Geometry polygon = GeoUtils.fromWkt(area.getBoundary());
// 是否在缩短后的运营区边界内
boolean inPolygonWithTolerance = GeoUtils.isInPolygonWithShorten(lon.toString(), lat.toString(), polygon, nearBoundaryDistance);
log.info("=========================是否在缩短后的运营区边界内:{},车辆定位=【{},{}】边界=【{}】",inPolygonWithTolerance,lon,lat,polygon);
if(!inPolygonWithTolerance && !isAdminUnlocking.equals("1") && device.getStatus().equals(ServiceConstants.VEHICLE_STATUS_IN_USING)){//没有在缩短后的运营区边界内
boolean inPolygonWithTolerance1 = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), polygon, 0);// 是否在运营区内
boolean isNearBoundary = GeoUtils.isInPolygonWithTolerance(lon.toString(), lat.toString(), polygon, exceedDistance );
if(inPolygonWithTolerance1){//是否在运营区边界内
// 在靠近运营区边界时发警报
log.info("靠近运营区边界发警告命令===============--SN" + device.getSn());
sendCommandWithCooldown(device, IotConstants.COMMAND_PLAY2, "靠近运营区边界");
returnPower(device, noRidingArea);
}else if(isNearBoundary){ // 是否在超出运营区边界多少米内
//在20米范围内发报警
log.info("超出运营区30米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY3, "超出运营区30米内",null,null);
log.info("超出运营区"+exceedDistance+"米内发送警告命令==============--SN" + device.getSn());
sendCommandWithCooldown(device, IotConstants.COMMAND_PLAY3, "超出运营区" + exceedDistance + "米内");
}else{
//超出运营区外断电
// 超出运营区外断电
String areaOutOutage = area.getAreaOutOutage();
if (areaOutOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 超出营运区断电
log.info("超出营运区断电命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "超出营运区断电",null,null);
if (areaOutOutage.equals("1")) { // 超出营运区断电
log.info("超出营运区断电命令=================--SN" + device.getSn());
sendCommandWithCooldown(device, IotConstants.COMMAND_QLOSE + IotConstants.COMMAND_FREQUENCY_5, "超出营运区断电");
device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
int updateAsDevice = asDeviceService.updateAsDevice(device);
if (updateAsDevice > 0) {
log.info("禁行区内断电--更新设备锁状态成功SN" + device.getSn());
log.info("超出营运区断电命令--更新设备锁状态成功SN" + device.getSn());
}
}
}
}else{
// 判断该车辆是否在进行中的订单,并且车辆的锁状态是关状态是骑行中
Boolean inOrderBySn = etOrderService.isInOrderBySn(device.getSn());
if (inOrderBySn && ServiceConstants.VEHICLE_STATUS_IN_USING.equals(device.getStatus()) && ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus())) { // 有正在骑行的订单给车辆上电
if(!noRidingArea){
log.info("返回营运区上电,有正在骑行的订单,给车辆上电--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5, "返回营运区上电",null,null);
// 更新车辆状态和锁状态
/** 3.更新车辆状态*/
device.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN);
device.setStatus(ServiceConstants.VEHICLE_STATUS_IN_USING);
device.setIsAdminUnlocking("0");
int i1 = asDeviceService.updateAsDevice(device);
if(i1>1){
log.info("【返回营运区上电】更新车辆状态成功");
}
}
log.info("在缩短后的运营区边界内====================" + device.getSn());
returnPower(device, noRidingArea);
}
}
/** 带20秒的冷却时间 */
private void sendCommandWithCooldown(AsDevice device, String command, String message) {
String deviceKey = device.getSn() + "_" + command; // 使用设备SN和命令作为唯一标识
long currentTime = System.currentTimeMillis();
Long lastCommandTime = commandCooldownMap.get(deviceKey);
if (lastCommandTime == null || (currentTime - lastCommandTime) > COOLDOWN_PERIOD_MS) {
// 冷却时间已过可以发送命令
try {
asDeviceService.sendCommand(device.getMac(), Token.getToken(), command, message, null, null);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
commandCooldownMap.put(deviceKey, currentTime); // 更新命令发送时间
} else {
log.info("命令在冷却时间内,不执行命令==============--SN" + device.getSn());
}
}
/** 返回运营区上电 */
private void returnPower(AsDevice device, boolean noRidingArea) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
// 判断该车辆是否在进行中的订单,并且车辆的锁状态是关状态是骑行中
Boolean inOrderBySn = etOrderService.isInOrderBySn(device.getSn());
if (inOrderBySn && ServiceConstants.VEHICLE_STATUS_IN_USING.equals(device.getStatus()) && ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus()) && !noRidingArea) { // 有正在骑行的订单给车辆上电
log.info("返回营运区上电,有正在骑行的订单,给车辆上电--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5, "返回营运区上电",null,null);
// 更新车辆状态和锁状态
/** 3.更新车辆状态*/
device.setLockStatus(ServiceConstants.LOCK_STATUS_OPEN);
device.setStatus(ServiceConstants.VEHICLE_STATUS_IN_USING);
device.setIsAdminUnlocking("0");
int i1 = asDeviceMapper.updateAsDevice(device);
if(i1>1){
log.info("【返回营运区上电】更新车辆状态成功");
}
}
}
@ -379,9 +404,9 @@ public class ReceiveController {
String noRidingOutage = area.getNoRidingOutage();
if (noRidingOutage.equals("1") && value.getStatus() != 3 && !isAdminUnlocking.equals("1")) { // 禁行区内断电
log.info("禁行区内断电命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_QLOSE+IotConstants.COMMAND_FREQUENCY_5, "禁行区内断电",null,null);
sendCommandWithCooldown(device, IotConstants.COMMAND_QLOSE + IotConstants.COMMAND_FREQUENCY_5, "禁行区内断电");
device.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE);
int updateAsDevice = asDeviceService.updateAsDevice(device);
int updateAsDevice = asDeviceMapper.updateAsDevice(device);
if (updateAsDevice > 0) {
log.info("禁行区内断电--更新设备锁状态成功SN" + device.getSn());
}
@ -391,7 +416,7 @@ public class ReceiveController {
boolean inPolygon = asDeviceService.isNoRidingAreaWithTolerance(device.getSn(), device.getAreaId(),30);
if (inPolygon && !isAdminUnlocking.equals("1")) {
log.info("距离禁行区20米内发送警告命令--SN" + device.getSn());
asDeviceService.sendCommand(device.getMac(), Token.getToken(), IotConstants.COMMAND_PLAY2, "距离禁行区30米内",null,null);
sendCommandWithCooldown(device, IotConstants.COMMAND_PLAY2, "距离禁行区30米内");
}
}
return noRidingArea;

View File

@ -16,7 +16,7 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.EtCouponClaimLog;
import com.ruoyi.system.domain.EtCouponUserLog;
import com.ruoyi.system.service.IEtCouponClaimLogService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
@ -39,10 +39,10 @@ public class EtCouponClaimLogController extends BaseController
*/
@PreAuthorize("@ss.hasPermi('system:claimLog:list')")
@GetMapping("/list")
public TableDataInfo list(EtCouponClaimLog etCouponClaimLog)
public TableDataInfo list(EtCouponUserLog etCouponUserLog)
{
startPage();
List<EtCouponClaimLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponClaimLog);
List<EtCouponUserLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponUserLog);
return getDataTable(list);
}
@ -52,10 +52,10 @@ public class EtCouponClaimLogController extends BaseController
@PreAuthorize("@ss.hasPermi('system:claimLog:export')")
@Log(title = "优惠券领取记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, EtCouponClaimLog etCouponClaimLog)
public void export(HttpServletResponse response, EtCouponUserLog etCouponUserLog)
{
List<EtCouponClaimLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponClaimLog);
ExcelUtil<EtCouponClaimLog> util = new ExcelUtil<EtCouponClaimLog>(EtCouponClaimLog.class);
List<EtCouponUserLog> list = etCouponClaimLogService.selectEtCouponClaimLogList(etCouponUserLog);
ExcelUtil<EtCouponUserLog> util = new ExcelUtil<EtCouponUserLog>(EtCouponUserLog.class);
util.exportExcel(response, list, "优惠券领取记录数据");
}
@ -75,9 +75,9 @@ public class EtCouponClaimLogController extends BaseController
@PreAuthorize("@ss.hasPermi('system:claimLog:add')")
@Log(title = "优惠券领取记录", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody EtCouponClaimLog etCouponClaimLog)
public AjaxResult add(@RequestBody EtCouponUserLog etCouponUserLog)
{
return toAjax(etCouponClaimLogService.insertEtCouponClaimLog(etCouponClaimLog));
return toAjax(etCouponClaimLogService.insertEtCouponClaimLog(etCouponUserLog));
}
/**
@ -86,9 +86,9 @@ public class EtCouponClaimLogController extends BaseController
@PreAuthorize("@ss.hasPermi('system:claimLog:edit')")
@Log(title = "优惠券领取记录", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody EtCouponClaimLog etCouponClaimLog)
public AjaxResult edit(@RequestBody EtCouponUserLog etCouponUserLog)
{
return toAjax(etCouponClaimLogService.updateEtCouponClaimLog(etCouponClaimLog));
return toAjax(etCouponClaimLogService.updateEtCouponClaimLog(etCouponUserLog));
}
/**

View File

@ -16,6 +16,7 @@ import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.mapper.AsUserMapper;
import com.ruoyi.system.service.IAsUserService;
import com.ruoyi.system.service.IEtCouponClaimLogService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysMenuService;
import lombok.extern.slf4j.Slf4j;
@ -56,6 +57,9 @@ public class SysLoginController
@Resource
private AsUserMapper asUserMapper;
@Autowired
private IEtCouponClaimLogService etCouponClaimLogService;
/**
* 登录方法

View File

@ -6,7 +6,7 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/electripper?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://localhost:3306/ele2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
# url: jdbc:mysql://117.26.179.22:61110/electripper?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8

View File

@ -1,4 +1,3 @@
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.RuoYiApplication;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants;
@ -9,13 +8,11 @@ import com.ruoyi.system.domain.EtOperatingArea;
import com.ruoyi.system.service.IAsDeviceService;
import com.ruoyi.system.service.IEtOperatingAreaService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.web.controller.iot.domain.LogEntry;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.operation.buffer.BufferOp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@ -41,6 +38,8 @@ public class MainTests {
@Test
@SneakyThrows
public void testSelectActivityById() {
// 记录开始时间
long startTime = System.nanoTime();
AsDevice device = asDeviceService.selectAsDeviceByMac("75D30EA71454");
BigDecimal lon = new BigDecimal("120.25709");
@ -88,6 +87,15 @@ public class MainTests {
}else{
log.info("在运营区域内");
}
// 记录结束时间
long endTime = System.nanoTime();
// 计算执行时间以毫秒为单位
long duration = (endTime - startTime) / 1_000_000;
// 输出执行时间
System.out.println("Execution time: " + duration + " milliseconds");
}

View File

@ -52,4 +52,9 @@ public class CacheConstants
* 登录账户密码错误次数 redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
/**
* 设备定位信息 redis key
*/
public static final String CACHE_DEVICE_KEY = "device:";
}

View File

@ -718,5 +718,26 @@ public class ServiceConstants {
/**----------------------------优惠券状态end----------------------------*/
/**----------------------------优惠券类型start----------------------------*/
/** 类型1-时间卡2-贵宾卡3-折扣卡4-抵用券
/**
* 1-时间卡
*/
public static final String COUPON_TYPE_TIME_CARD = "1";
/**
* 2-贵宾卡
*/
public static final String COUPON_TYPE_VIP_CARD = "2";
/**
* 3-折扣卡
*/
public static final String COUPON_TYPE_DISCOUNT_CARD = "3";
/**
* 4-抵用券
*/
public static final String COUPON_TYPE_VOUCHER = "4";
/**----------------------------优惠券类型end----------------------------*/
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.core.domain.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
@ -118,6 +119,28 @@ public class AsUser extends BaseEntity
/** appId*/
public String appId;
/** 会员类型 0-无会员1-普通会员2-贵宾会员 */
public String vipType;
/** 有效时间 */
private Date expirationTime;
public String getVipType() {
return vipType;
}
public void setVipType(String vipType) {
this.vipType = vipType;
}
public Date getExpirationTime() {
return expirationTime;
}
public void setExpirationTime(Date expirationTime) {
this.expirationTime = expirationTime;
}
public String getAppId() {
return appId;
}

View File

@ -321,4 +321,51 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
ZonedDateTime zonedDateTime = offsetDateTime.toZonedDateTime();
return Date.from(zonedDateTime.toInstant());
}
/**
* 是否相差一分钟
* * @param at 第一个时间戳毫秒级
* * @param currentTimeMillis 第二个时间戳毫秒级
* * @return 如果两个时间戳相差超过一分钟则返回 true否则返回 false
*/
public static boolean oneMinuteDifference(long at, long currentTimeMillis) {
// 计算两个时间戳的差值取绝对值
long difference = Math.abs(currentTimeMillis - at);
// 判断是否大于 60,000 毫秒1 分钟
return difference > 60_000;
}
/**
* 根据有效期单位和有效期值返回一个加上固定多少单位的时间
*
* @param startDate 起始日期
* @param validityUnit 有效期单位day-week-month-quarter-季度year-
* @param validityValue 有效期值
* @return 加上有效期后的时间
*/
public static Date addValidity(Date startDate, String validityUnit, Integer validityValue) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
switch (validityUnit.toLowerCase()) {
case "day": //
calendar.add(Calendar.DAY_OF_MONTH, validityValue);
break;
case "week": //
calendar.add(Calendar.WEEK_OF_YEAR, validityValue);
break;
case "month": //
calendar.add(Calendar.MONTH, validityValue);
break;
case "quarter": // 季度
calendar.add(Calendar.MONTH, validityValue * 3);
break;
case "year": //
calendar.add(Calendar.YEAR, validityValue);
break;
default:
throw new IllegalArgumentException("无效的有效期单位: " + validityUnit);
}
return calendar.getTime(); // 返回新的时间
}
}

View File

@ -1,4 +1,4 @@
package com.ruoyi.web.controller.iot.domain;
package com.ruoyi.common.utils.onenet;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

View File

@ -23,6 +23,9 @@ public class EtCoupon extends BaseEntity
/** 优惠券id */
private Long couponId;
/** 名称 */
private String name;
/** 类型 */
@Excel(name = "类型")
private String type;
@ -61,11 +64,15 @@ public class EtCoupon extends BaseEntity
/** 描述 */
@Excel(name = "描述")
private String desc;
private String descr;
/** 零食价 */
@Excel(name = "零食价")
private BigDecimal snackPrice;
/** 零售价 */
@Excel(name = "零售价")
private BigDecimal retailPrice;
/** 原价 */
@Excel(name = "原价")
private String originalPrice;
/** 有效期值 */
@Excel(name = "有效期值")
@ -74,4 +81,10 @@ public class EtCoupon extends BaseEntity
/** 有效期单位 */
@Excel(name = "有效期单位")
private String validityUnit;
/** 类型列表 */
private String[] typeList;
/** 是否热门0-非热门1-热门 */
private String isHot;
}

View File

@ -6,16 +6,17 @@ import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 优惠券领取记录对象 et_coupon_user_log
* 我的优惠券对象 et_coupon_user_log
*
* @author qzz
* @date 2024-08-08
*/
@Data
public class EtCouponClaimLog extends BaseEntity
public class EtCouponUserLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -42,6 +43,14 @@ public class EtCouponClaimLog extends BaseEntity
@Excel(name = "优惠券")
private Long couponId;
/** 优惠券名称 */
@Excel(name = "优惠券名称")
private String couponName;
/** 零售价 */
@Excel(name = "零售价")
private BigDecimal retailPrice;
/** 获取方式claim-领取buy-购买issue-下发 */
@Excel(name = "获取方式claim-领取buy-购买issue-下发")
private String gainMethod;

View File

@ -172,4 +172,7 @@ public class EtFeeRule extends BaseEntity
/** 是否已删除*/
@Excel(name = "是否已删除")
private String isDeleted;
@Excel(name = "描述")
private String description;
}

View File

@ -267,4 +267,37 @@ public class EtOrder extends BaseEntity
/** 锁单中: 0-否1-是 */
@Excel(name = "锁单中: 0-否1-是")
private String locking;
/** 还车结算___小时后自动退押金 */
@Excel(name = "还车结算___小时后自动退押金")
private Integer autoRefundDeposit;
/** 免费骑行时长(分钟) */
@Excel(name = "免费骑行时长(分钟)")
private Integer freeRideTime;
/** 租赁单位minutes-分钟hours-小时day-天 */
@Excel(name = "租赁单位")
private String rentalUnit;
/** 计费规则1-起步价计费 2-区间计费 */
@Excel(name = "计费规则")
private String ridingRule;
/** 计费规则json串*/
@Excel(name = "计费规则json")
private String ridingRuleJson;
/** 计费周期1-订单生成后__小时 2-自定义时刻 */
@Excel(name = "计费周期")
private String chargingCycle;
/** 计费周期值:*/
@Excel(name = "计费周期值")
private String chargingCycleValue;
/** 封顶金额*/
@Excel(name = "封顶金额")
private BigDecimal cappedAmount;
}

View File

@ -1,7 +1,7 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.EtCouponClaimLog;
import com.ruoyi.system.domain.EtCouponUserLog;
/**
* 优惠券领取记录Mapper接口
@ -17,31 +17,31 @@ public interface EtCouponClaimLogMapper
* @param claimId 优惠券领取记录主键
* @return 优惠券领取记录
*/
public EtCouponClaimLog selectEtCouponClaimLogByLogId(Long claimId);
public EtCouponUserLog selectEtCouponClaimLogByLogId(Long claimId);
/**
* 查询优惠券领取记录列表
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 优惠券领取记录集合
*/
public List<EtCouponClaimLog> selectEtCouponClaimLogList(EtCouponClaimLog etCouponClaimLog);
public List<EtCouponUserLog> selectEtCouponClaimLogList(EtCouponUserLog etCouponUserLog);
/**
* 新增优惠券领取记录
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 结果
*/
public int insertEtCouponClaimLog(EtCouponClaimLog etCouponClaimLog);
public int insertEtCouponClaimLog(EtCouponUserLog etCouponUserLog);
/**
* 修改优惠券领取记录
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 结果
*/
public int updateEtCouponClaimLog(EtCouponClaimLog etCouponClaimLog);
public int updateEtCouponClaimLog(EtCouponUserLog etCouponUserLog);
/**
* 删除优惠券领取记录

View File

@ -76,4 +76,10 @@ public interface EtLocationLogMapper
*/
int deleteLocationLogByCreateTime();
/**
* 获取最后一条消息
*
* @return 结果
*/
String getLastMsg(String mac);
}

View File

@ -1,7 +1,7 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.EtCouponClaimLog;
import com.ruoyi.system.domain.EtCouponUserLog;
/**
* 优惠券领取记录Service接口
@ -17,31 +17,31 @@ public interface IEtCouponClaimLogService
* @param claimId 优惠券领取记录主键
* @return 优惠券领取记录
*/
public EtCouponClaimLog selectEtCouponClaimLogByLogId(Long claimId);
public EtCouponUserLog selectEtCouponClaimLogByLogId(Long claimId);
/**
* 查询优惠券领取记录列表
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 优惠券领取记录集合
*/
public List<EtCouponClaimLog> selectEtCouponClaimLogList(EtCouponClaimLog etCouponClaimLog);
public List<EtCouponUserLog> selectEtCouponClaimLogList(EtCouponUserLog etCouponUserLog);
/**
* 新增优惠券领取记录
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 结果
*/
public int insertEtCouponClaimLog(EtCouponClaimLog etCouponClaimLog);
public int insertEtCouponClaimLog(EtCouponUserLog etCouponUserLog);
/**
* 修改优惠券领取记录
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 结果
*/
public int updateEtCouponClaimLog(EtCouponClaimLog etCouponClaimLog);
public int updateEtCouponClaimLog(EtCouponUserLog etCouponUserLog);
/**
* 批量删除优惠券领取记录

View File

@ -8,11 +8,9 @@ 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.HttpStatus;
import com.ruoyi.common.constant.IotConstants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.constant.*;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils;
@ -110,13 +108,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
private IEtOnlineLogService etOnlineLogService;
@Autowired
private IEtRefundService etRefundService;
@Resource
private IAsUserService asUserService;
@Autowired
private CallbackService callbackService;
private RedisCache redisCache;
@Autowired
private ISysConfigService sysConfigService;
@ -209,12 +201,22 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
if(ObjectUtil.isNotNull(model)){
asDevice.setModel(model.getModel());
}
// if(StrUtil.isNotBlank(asDevice.getLongitude()) && StrUtil.isNotBlank(asDevice.getLatitude())){
// asDevice.setLocation(CommonUtil.getAddressByGeo(asDevice.getLongitude() + ","+asDevice.getLatitude()));
// }
if(StrUtil.isNotBlank(asDevice.getVoltage())){
asDevice.setRemainingMileage(CommonUtil.getRemainingMileage(asDevice.getVoltage(),model.getFullVoltage(),model.getLowVoltage(),model.getFullEndurance()));
}
String msg = redisCache.getCacheObject(CacheConstants.CACHE_DEVICE_KEY + asDevice.getSn());
if(StrUtil.isNotBlank(msg)){
log.info("【根据sn号查询车辆实时信息】-========redis缓存中的数据" + msg);
LogEntry logEntry = JSONObject.parseObject(msg, LogEntry.class);
log.info("【根据sn号查询车辆实时信息】============logEntry转换后的对象: logEntry---【{}】" , JSON.toJSONString(logEntry));
LogEntry.LocationValue value = logEntry.getValue();
// 坐标转换 WGS84 GCJ02
double[] doubles = CommonUtil.coordinateConvert(value.getLon(),value.getLat());
BigDecimal lon = new BigDecimal(doubles[1]).setScale(8, RoundingMode.HALF_UP);
BigDecimal lat = new BigDecimal(doubles[0]).setScale(8, RoundingMode.HALF_UP);
asDevice.setLongitude(lon.toString());
asDevice.setLatitude(lat.toString());
}
//正在进行中的订单
EtOrder order = new EtOrder();
order.setSn(asDevice.getSn());
@ -1908,38 +1910,33 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
private EtOrder calculateOrderFee(EtOrder order,String isInParkingArea) {
String type = order.getType();
if(type.equals("1")){//骑行订单,正常骑行包含预约费计时收费根据开锁时间起步价和起步时长时长费和时长分钟等参数如果有预约还要加上预约费计算费用,还要判断封顶费用根据开锁时间
Long ruleId = order.getRuleId();
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(ruleId);
if(ObjectUtil.isNull(rule)){
throw new ServiceException("计费规则不存在");
}
String rentalUnit = rule.getRentalUnit();//租赁单位
String rentalUnit = order.getRentalUnit();//租赁单位
//根据订单的开始时间和还车时间计算出在第几个计费周期在第一个计费周期内并没有超过封顶费用则根据规则算出骑行费
Integer cycle = null;
Date startTime = order.getUnlockTime();
Date endTime = order.getReturnTime();
String chargingCycle = rule.getChargingCycle();
String chargingCycleValue = rule.getChargingCycleValue();
String chargingCycle = order.getChargingCycle();
String chargingCycleValue = order.getChargingCycleValue();
if(ServiceConstants.CHARGING_CYCLE_HOUR.equals(chargingCycle)) {//订单生成后__小时 第几个
cycle = inHowManyChargingCycle(startTime, endTime, chargingCycleValue);
BigDecimal ridingFee;
if(cycle == 1){
order.setCycle(1);//在第几个计费周期内
ridingFee = calculateRidingFee(order.getUnlockTime(), order.getReturnTime(), rule, rule.getRidingRuleJson(), rentalUnit);
order.setCycle(1);//在第几个计费周期内 rule, rule.getRidingRuleJson(), rentalUnit
ridingFee = calculateRidingFee(order,order.getUnlockTime(), order.getReturnTime());
}else {
// 判断一个计费周期是否超过封顶费用如果超出 骑行费 = (第几个周期 - 1) * 封顶费用 + 骑行费
// 如果不超出骑行费 = 骑行费
Date oneCycleAfter = DateUtils.getTimeAfterXHours(order.getUnlockTime(), Integer.parseInt(chargingCycleValue));
if(isFeeExceedingCap(order.getUnlockTime(),oneCycleAfter, rule,rentalUnit)){
if(isFeeExceedingCap(order.getUnlockTime(),oneCycleAfter,order,order.getRentalUnit())){
// 如果超出 骑行费 = (第几个周期 - 1) * 封顶费用 + 骑行费
order.setCycle(cycle);
Date afterXHours = DateUtils.getTimeAfterXHours(order.getUnlockTime(), Integer.parseInt(chargingCycleValue)*(cycle-1));
BigDecimal remainingFee = calculateRidingFee(afterXHours, order.getReturnTime(), rule, rule.getRidingRuleJson(),rentalUnit);
ridingFee = new BigDecimal(cycle - 1).multiply(rule.getCappedAmount()).add(remainingFee);
BigDecimal remainingFee = calculateRidingFee(order,afterXHours,order.getReturnTime());
ridingFee = new BigDecimal(cycle - 1).multiply(order.getCappedAmount()).add(remainingFee);
}else{
ridingFee = calculateRidingFee(order.getUnlockTime(), order.getReturnTime(), rule, rule.getRidingRuleJson(), rentalUnit);
ridingFee = calculateRidingFee(order, order.getUnlockTime(), order.getReturnTime());
}
}
order.setRidingFee(ridingFee);
@ -1965,21 +1962,21 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
BigDecimal ridingFee;
if (order.getUnlockTime().before(customCycleTime) && endTime.after(customCycleTime)) {//如果自定义时间在骑行时间段内分段计算骑行费用并考虑封顶费用
BigDecimal firstPeriodFee = calculateRidingFee(order.getUnlockTime(), customCycleTime, rule, rule.getRidingRuleJson(), rentalUnit);
BigDecimal secondPeriodFee = calculateRidingFee(customCycleTime, endTime, rule, rule.getRidingRuleJson(), rentalUnit);
BigDecimal firstPeriodFee = calculateRidingFee(order,order.getUnlockTime(), customCycleTime);
BigDecimal secondPeriodFee = calculateRidingFee(order,customCycleTime, endTime);
if (firstPeriodFee.compareTo(rule.getCappedAmount()) > 0) {
firstPeriodFee = rule.getCappedAmount();
if (firstPeriodFee.compareTo(order.getCappedAmount()) > 0) {
firstPeriodFee = order.getCappedAmount();
}
if (secondPeriodFee.compareTo(rule.getCappedAmount()) > 0) {
secondPeriodFee = rule.getCappedAmount();
if (secondPeriodFee.compareTo(order.getCappedAmount()) > 0) {
secondPeriodFee = order.getCappedAmount();
}
ridingFee = firstPeriodFee.add(secondPeriodFee);
} else {// 如果自定义时间不在骑行时间段内直接计算骑行费用并考虑封顶费用
ridingFee = calculateRidingFee(order.getUnlockTime(), endTime, rule, rule.getRidingRuleJson(), rentalUnit);
if (ridingFee.compareTo(rule.getCappedAmount()) > 0) {
ridingFee = rule.getCappedAmount();
ridingFee = calculateRidingFee(order,order.getUnlockTime(), endTime);
if (ridingFee.compareTo(order.getCappedAmount()) > 0) {
ridingFee = order.getCappedAmount();
}
}
@ -2040,9 +2037,9 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
* 判断一个计费周期是否超过封顶费用
*/
@NotNull
private Boolean isFeeExceedingCap(Date startTime, Date endTime, EtFeeRule rule, String rentalUnit) {
private Boolean isFeeExceedingCap(Date startTime, Date endTime, EtOrder order, String rentalUnit) {
Integer minutes = DateUtils.timeDifferenceInMinutes(endTime,startTime);//计算相隔多少分钟
StartingRuleVo startingRule = JSONObject.parseObject(rule.getRidingRuleJson(), StartingRuleVo.class);
StartingRuleVo startingRule = JSONObject.parseObject(order.getRidingRuleJson(), StartingRuleVo.class);
String timeoutPrice = startingRule.getTimeoutPrice();//超时价格
Integer timeoutTime = Integer.parseInt(startingRule.getTimeoutTime());//超时时间
@ -2054,32 +2051,27 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
double ceil = Math.ceil(minutes / timeoutTime) +1 ;
BigDecimal ridingFee = new BigDecimal(ceil * Double.parseDouble(timeoutPrice));
return ridingFee.compareTo(rule.getCappedAmount())>0;
return ridingFee.compareTo(order.getCappedAmount())>0;
}
/**
* 计算骑行费
* @param unlockTime 开锁时间
* @param returnTime 还车时间
* @param rule 计费规则
* @param ridingRuleJson 起步价规则
* @param rentalUnit 租赁单位
*/
@NotNull
private BigDecimal calculateRidingFee(Date unlockTime,Date returnTime, EtFeeRule rule, String ridingRuleJson,String rentalUnit) {
private BigDecimal calculateRidingFee(EtOrder order,Date unlockTime,Date returnTime) {
BigDecimal ridingFee = BigDecimal.ZERO;
//没有预约根据订单中的开锁时间计算费用骑行费用 ((还车时间-开锁时间转成分钟数)/ 时长分钟)-起步价分钟数 * 时长费 + 起步价
// Date returnTime = order.getReturnTime();//还车时间
String rentalUnit = order.getRentalUnit();
//在免费骑行时间内骑行费为0
Integer minutes = DateUtils.timeDifferenceInMinutes(returnTime,unlockTime);//计算相隔多少分钟
Integer freeRideTime = rule.getFreeRideTime();
Integer freeRideTime = order.getFreeRideTime();
if(freeRideTime!=0 && freeRideTime!=null && minutes<=freeRideTime){
return ridingFee;
}
if(rule.getRidingRule().equals(ServiceConstants.RIDING_RULE_STARTING_PRICE_MODE)){//1-起步价计费
StartingRuleVo startingRule = JSONObject.parseObject(ridingRuleJson, StartingRuleVo.class);
if(order.getRidingRule().equals(ServiceConstants.RIDING_RULE_STARTING_PRICE_MODE)){//1-起步价计费
StartingRuleVo startingRule = JSONObject.parseObject(order.getRidingRuleJson(), StartingRuleVo.class);
String startingPrice = startingRule.getStartingPrice();//起步价
Integer startingTime = Integer.parseInt(startingRule.getStartingTime());//起步时间
String timeoutPrice = startingRule.getTimeoutPrice();//超时价格
@ -2113,7 +2105,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
}
}
}else{//2-区间计费
IntervalRuleVo intervalRuleVo = JSONObject.parseObject(ridingRuleJson, IntervalRuleVo.class);
IntervalRuleVo intervalRuleVo = JSONObject.parseObject(order.getRidingRuleJson(), IntervalRuleVo.class);
List<IntervalRuleVo.IntervalRule> rule1 = intervalRuleVo.getRule();
//骑行时长
Integer duration = DateUtils.timeDifferenceInMinutes(returnTime,unlockTime);//计算相隔多少分钟

View File

@ -523,8 +523,7 @@ public class CallbackServiceImpl implements CallbackService {
* 退还押金定时任务
*/
private void refundDeposit(String deposit, EtOrder order, AsUser asUser) {
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
Integer autoRefundDeposit = rule.getAutoRefundDeposit();
Integer autoRefundDeposit = order.getAutoRefundDeposit();
logger.info("【微信支付回调】进入退还押金");
if(autoRefundDeposit!=null){

View File

@ -5,7 +5,7 @@ import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.EtCouponClaimLogMapper;
import com.ruoyi.system.domain.EtCouponClaimLog;
import com.ruoyi.system.domain.EtCouponUserLog;
import com.ruoyi.system.service.IEtCouponClaimLogService;
/**
@ -27,7 +27,7 @@ public class EtCouponClaimLogServiceImpl implements IEtCouponClaimLogService
* @return 优惠券领取记录
*/
@Override
public EtCouponClaimLog selectEtCouponClaimLogByLogId(Long claimId)
public EtCouponUserLog selectEtCouponClaimLogByLogId(Long claimId)
{
return etCouponClaimLogMapper.selectEtCouponClaimLogByLogId(claimId);
}
@ -35,38 +35,38 @@ public class EtCouponClaimLogServiceImpl implements IEtCouponClaimLogService
/**
* 查询优惠券领取记录列表
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 优惠券领取记录
*/
@Override
public List<EtCouponClaimLog> selectEtCouponClaimLogList(EtCouponClaimLog etCouponClaimLog)
public List<EtCouponUserLog> selectEtCouponClaimLogList(EtCouponUserLog etCouponUserLog)
{
return etCouponClaimLogMapper.selectEtCouponClaimLogList(etCouponClaimLog);
return etCouponClaimLogMapper.selectEtCouponClaimLogList(etCouponUserLog);
}
/**
* 新增优惠券领取记录
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 结果
*/
@Override
public int insertEtCouponClaimLog(EtCouponClaimLog etCouponClaimLog)
public int insertEtCouponClaimLog(EtCouponUserLog etCouponUserLog)
{
etCouponClaimLog.setCreateTime(DateUtils.getNowDate());
return etCouponClaimLogMapper.insertEtCouponClaimLog(etCouponClaimLog);
etCouponUserLog.setCreateTime(DateUtils.getNowDate());
return etCouponClaimLogMapper.insertEtCouponClaimLog(etCouponUserLog);
}
/**
* 修改优惠券领取记录
*
* @param etCouponClaimLog 优惠券领取记录
* @param etCouponUserLog 优惠券领取记录
* @return 结果
*/
@Override
public int updateEtCouponClaimLog(EtCouponClaimLog etCouponClaimLog)
public int updateEtCouponClaimLog(EtCouponUserLog etCouponUserLog)
{
return etCouponClaimLogMapper.updateEtCouponClaimLog(etCouponClaimLog);
return etCouponClaimLogMapper.updateEtCouponClaimLog(etCouponUserLog);
}
/**

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.service.impl;
import java.util.Date;
import java.util.List;
import cn.hutool.core.util.ObjectUtil;
@ -135,16 +136,35 @@ public class EtCouponServiceImpl implements IEtCouponService
* */
// 1. 插入一条记录et_coupon_user_log 获取方式是购买
AsUser asUser = userMapper.selectUserById(userId);
if(ObjectUtil.isNull(asUser)){
throw new ServiceException("用户【"+userId+"】不存在");
}
EtCoupon etCoupon = etCouponMapper.selectEtCouponByCouponId(couponId);
EtCouponClaimLog etCouponClaimLog = new EtCouponClaimLog();
etCouponClaimLog.setCouponId(couponId);
etCouponClaimLog.setUserId(userId);
etCouponClaimLog.setUserName(asUser.getUserName());
etCouponClaimLog.setCreateTime(DateUtils.getNowDate());
etCouponClaimLog.setGainMethod(ServiceConstants.COUPON_GAIN_METHOD_BUY);
etCouponClaimLog.setAreaId(etCoupon.getAreaId());
etCouponClaimLog.setAreaName(etCoupon.getAreaName());
int i1 = etCouponClaimLogMapper.insertEtCouponClaimLog(etCouponClaimLog);
if(ObjectUtil.isNull(etCoupon)){
throw new ServiceException("优惠券【"+couponId+"】不存在");
}
EtCouponUserLog etCouponUserLog = new EtCouponUserLog();
etCouponUserLog.setCouponId(couponId);
etCouponUserLog.setUserId(userId);
etCouponUserLog.setUserName(asUser.getUserName());
etCouponUserLog.setCreateTime(DateUtils.getNowDate());
etCouponUserLog.setGainMethod(ServiceConstants.COUPON_GAIN_METHOD_BUY);
etCouponUserLog.setAreaId(etCoupon.getAreaId());
etCouponUserLog.setAreaName(etCoupon.getAreaName());
etCouponUserLog.setExpirationTime(DateUtils.addValidity(new Date(),etCoupon.getValidityUnit(),etCoupon.getValidityValue()));
if(ServiceConstants.COUPON_TYPE_TIME_CARD.equals(etCoupon.getType()) || ServiceConstants.COUPON_TYPE_VIP_CARD.equals(etCoupon.getType())){
AsUser asUser1 = new AsUser(userId);
asUser1.setVipType(etCoupon.getType());
Date expirationTime;
if(ObjectUtil.isNull(asUser.getExpirationTime())){
expirationTime = DateUtils.getNowDate();
}else{
expirationTime = asUser.getExpirationTime();
}
asUser1.setExpirationTime(DateUtils.addValidity(expirationTime,etCoupon.getValidityUnit(),etCoupon.getValidityValue()));
int updateUser = userMapper.updateUser(asUser1);
}
int i1 = etCouponClaimLogMapper.insertEtCouponClaimLog(etCouponUserLog);
if(i1 == 0){
throw new ServiceException("保存优惠券领取记录失败");
}
@ -175,8 +195,8 @@ public class EtCouponServiceImpl implements IEtCouponService
/** 订单类型 1骑行 2预约 3套餐 4押金 根据类型不同下单的参数也不同,不同的参数有: 金额、类型、rule_id套餐id*/
etOrder.setArea(etCoupon.getAreaName());
etOrder.setType(ServiceConstants.ORDER_TYPE_COUPON);
etOrder.setTotalFee(etCoupon.getSnackPrice());
etOrder.setPayFee(etCoupon.getSnackPrice());
etOrder.setTotalFee(etCoupon.getRetailPrice());
etOrder.setPayFee(etCoupon.getRetailPrice());
return etOrder;
}
}

View File

@ -3,13 +3,17 @@ package com.ruoyi.system.service.impl;
import java.util.List;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.EtAreaRule;
import com.ruoyi.system.domain.EtOperatingArea;
import com.ruoyi.system.domain.vo.IntervalRuleVo;
import com.ruoyi.system.domain.vo.StartingRuleVo;
import com.ruoyi.system.mapper.EtAreaRuleMapper;
import com.ruoyi.system.service.IEtOperatingAreaService;
import com.ruoyi.system.service.IWxPayService;
@ -86,7 +90,25 @@ public class EtFeeRuleServiceImpl implements IEtFeeRuleService
SysDept sysDept = wxPayService.getDeptObjByAreaId(etFeeRule.getAreaId());
etFeeRule.setDeptId(sysDept.getDeptId());
}
return etFeeRuleMapper.selectEtFeeRuleList(etFeeRule);
List<EtFeeRule> etFeeRules = etFeeRuleMapper.selectEtFeeRuleList(etFeeRule);
for (EtFeeRule rule:etFeeRules) {
StringBuilder sb = new StringBuilder();
String ridingRuleJson = rule.getRidingRuleJson();
String unit = "";
if(rule.getRidingRule().equals("1")){
StartingRuleVo startingRule = JSONObject.parseObject(ridingRuleJson, StartingRuleVo.class);
String rentalUnit = rule.getRentalUnit();
if(rentalUnit.equals(ServiceConstants.RENTAL_UNIT_MINUTES)){
unit = "分钟";
}else if(rentalUnit.equals(ServiceConstants.RENTAL_UNIT_HOURS)){
unit = "小时";
}
sb.append("起步价:"+startingRule.getStartingPrice()+"元(含"+startingRule.getStartingTime()+unit+"),");
sb.append("超出价:"+startingRule.getTimeoutPrice()+"元/"+startingRule.getTimeoutTime()+unit);
}
rule.setDescription(sb.toString());
}
return etFeeRules;
}
/**

View File

@ -472,28 +472,31 @@ public class EtOrderServiceImpl implements IEtOrderService
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】", order.getOrderNo(),outTradeNo);
// 如果原来有outtradeno去查询一次查询是否支付过
Transaction transaction = wxPayService.queryOrderByOutTradeNo(outTradeNo);
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
// 订单已支付
order.setPaid(ServiceConstants.ORDER_PAY_STATUS_PAID);
order.setPayTime(DateUtils.getNowDate());
order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END);
order.setPayType(ServiceConstants.PAY_TYPE_WX);
order.setMark("主动查询-骑行支付");
try {
int updateEtOrder = etOrderMapper.updateEtOrder(order);
try {
if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
// 订单已支付
order.setPaid(ServiceConstants.ORDER_PAY_STATUS_PAID);
order.setPayTime(DateUtils.getNowDate());
order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END);
order.setPayType(ServiceConstants.PAY_TYPE_WX);
order.setMark("主动查询-骑行支付");
int updateEtOrder = etOrderMapper.updateEtOrderByOrderNo(order);
if (updateEtOrder == 0) {
// 抛出自定义异常来标识订单更新失败
throw new ServiceException("押金抵扣失败,更新骑行订单失败");
}
} finally {
// 无论订单更新是否成功一定抛出异常来终止后续操作
throw new ServiceException("订单已支付,请勿操作");
return 1;
}else{
SysDept dept = wxPayService.getDeptObjByAreaId(order.getAreaId());
// 没有支付则关闭订单
boolean b = wxPayService.closeOrder(outTradeNo, dept);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", order.getOrderNo(),outTradeNo,b);
}
}else{
SysDept dept = wxPayService.getDeptObjByAreaId(order.getAreaId());
// 没有支付则关闭订单
boolean b = wxPayService.closeOrder(outTradeNo, dept);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", order.getOrderNo(),outTradeNo,b);
} catch (ServiceException e) {
log.error("异常发生: {}", e.getMessage());
return -1; // -1 表示失败
} finally {
log.warn("订单已支付,请勿操作");
}
}
EtOrder depositOrder = getDepositOrder(order.getUserId());
@ -1192,6 +1195,17 @@ public class EtOrderServiceImpl implements IEtOrderService
etOrder.setUserName(user.getUserName());
etOrder.setMark(order.getMark());
etOrder.setCreateTime(DateUtils.getNowDate());
if(ObjectUtil.isNotNull(order.getRuleId())){
EtFeeRule etFeeRule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
etOrder.setAutoRefundDeposit(etFeeRule.getAutoRefundDeposit());
etOrder.setFreeRideTime(etFeeRule.getFreeRideTime());
etOrder.setRentalUnit(etFeeRule.getRentalUnit());
etOrder.setRidingRule(etFeeRule.getRidingRule());
etOrder.setRidingRuleJson(etFeeRule.getRidingRuleJson());
etOrder.setChargingCycle(etFeeRule.getChargingCycle());
etOrder.setChargingCycleValue(etFeeRule.getChargingCycleValue());
etOrder.setCappedAmount(etFeeRule.getCappedAmount());
}
etOrder.setRuleId(order.getRuleId());
etOrder.setAreaId(order.getAreaId());
/** 订单类型 1骑行 2预约 3套餐 4押金 根据类型不同下单的参数也不同,不同的参数有: 金额、类型、rule_id套餐id*/
@ -1924,7 +1938,7 @@ public class EtOrderServiceImpl implements IEtOrderService
Boolean execute = transactionTemplate.execute(e -> {
/** 2.发送命令*/
if(!"true".equals(isBluetooth)){
ResponseVo responseVo = asDeviceService.sendCommandWithResp(newDevice.getMac(), token, IotConstants.COMMAND_CLOSE + IotConstants.COMMAND_FREQUENCY_3600, "换车开锁",orderNo);
ResponseVo responseVo = asDeviceService.sendCommandWithResp(newDevice.getMac(), token, IotConstants.COMMAND_OPEN+IotConstants.COMMAND_FREQUENCY_5, "换车开锁",orderNo);
if(responseVo.getCode()!=0){
log.info("【换车开锁】远程关锁失败");
throw new ServiceException("换车开锁失败");

View File

@ -3,21 +3,27 @@ package com.ruoyi.system.task;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.core.domain.entity.AsUser;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.map.GeoUtils;
import com.ruoyi.common.utils.map.GpsCoordinateUtils;
import com.ruoyi.common.utils.onenet.LogEntry;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.*;
import com.wechat.pay.java.service.refund.model.Refund;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@ -25,12 +31,10 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
@ -80,9 +84,6 @@ public class EtTask {
@Resource
private AsUserMapper asUserMapper;
@Autowired
private CallbackService callbackService;
@Resource
private EtLocationLogMapper etLocationLogMapper;
@ -90,6 +91,12 @@ public class EtTask {
private IAsDeviceService deviceService;
@Autowired
private IEtModelService etModelService;
@Resource
private EtCouponClaimLogMapper etCouponClaimLogMapper;
/**
* 1.启动时判断是否有未取消预约的订单
@ -111,13 +118,13 @@ public class EtTask {
List<EtOrder> orders = etOrderMapper.selectUserListFinishOrder();
log.info("已完成的订单未退还押金的的订单 = " + JSON.toJSONString(orders));
for(EtOrder order:orders){
EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
if(ObjectUtil.isNull(rule)){
throw new ServiceException("骑行订单:【"+order.getOrderNo()+"】未找到该套餐【"+order.getRuleId()+"");
}
// EtFeeRule rule = etFeeRuleService.selectEtFeeRuleByRuleIdIncludeDelete(order.getRuleId());
// if(ObjectUtil.isNull(rule)){
// throw new ServiceException("骑行订单:【"+order.getOrderNo()+"】未找到该套餐【"+order.getRuleId()+"");
// }
EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(order.getAreaId());
AsUser asUser = asUserMapper.selectUserById(order.getUserId());
Integer autoRefundDeposit = rule.getAutoRefundDeposit();
Integer autoRefundDeposit = order.getAutoRefundDeposit();
// 根据用户查询最后一次押金充值订单
EtOrder etOrder = new EtOrder();
@ -524,4 +531,210 @@ public class EtTask {
}
/**
* 更新设备的定位和电压 10秒一次
* cron: 0 10 0 * * ?
*/
public void updateLocation10(){
log.info("-------------------【定时任务10秒一次】更新设备的定位和电压-----开始--------------");
// 记录开始时间
long startTime = System.nanoTime();
Collection<String> keys = redisCache.keys(CacheConstants.CACHE_DEVICE_KEY + "*");
log.info("redis缓存中的数据" + JSON.toJSONString(keys));
for(String key:keys){
String msg = redisCache.getCacheObject(key);
log.info("redis缓存中的数据" + msg);
LogEntry logEntry = JSONObject.parseObject(msg, LogEntry.class);
log.info("logEntry转换后的对象: logEntry---【{}】" , JSON.toJSONString(logEntry));
LogEntry.LocationValue value = logEntry.getValue();
AsDevice device = asDeviceMapper.selectAsDeviceByMac(logEntry.getDevName());
if(!isRepeatMsg(msg,logEntry.getDevName())){
log.info("device: sn={},【{}】",device.getSn() , JSON.toJSONString(device));
if(ServiceConstants.LOCK_STATUS_OPEN.equals(device.getLockStatus()) && device.getStatus().equals(ServiceConstants.VEHICLE_STATUS_IN_USING)){
updateLocationHandle(msg, logEntry, value, device);
}
}
}
// 计算执行时间以毫秒为单位
long duration = (System.nanoTime() - startTime) / 1_000_000;
log.info("-------------------【定时任务10秒一次】更新设备的定位和电压----结束---------------"+duration+ " 毫秒");
}
private boolean isRepeatMsg(String msg,String mac){
// 获取最后一条消息
String lastMsg = etLocationLogMapper.getLastMsg(mac);
if(ObjectUtil.isNotNull(lastMsg) && msg.equals(lastMsg)){
return true;
}else{
return false;
}
}
/**
* 更新设备的定位和电压 5分钟一次
* cron: 0 20 0 * * ?
*/
public void updateLocation300(){
log.info("-------------------【定时任务5分钟一次】更新设备的定位和电压-----开始--------------");
// 记录开始时间
long startTime = System.nanoTime();
Collection<String> keys = redisCache.keys(CacheConstants.CACHE_DEVICE_KEY + "*");
log.info("redis缓存中的数据" + JSON.toJSONString(keys));
for(String key:keys){
String msg = redisCache.getCacheObject(key);
log.info("redis缓存中的数据" + msg);
LogEntry logEntry = JSONObject.parseObject(msg, LogEntry.class);
log.info("logEntry转换后的对象: logEntry---【{}】" , JSON.toJSONString(logEntry));
LogEntry.LocationValue value = logEntry.getValue();
AsDevice device = asDeviceMapper.selectAsDeviceByMac(logEntry.getDevName());
if(ServiceConstants.LOCK_STATUS_CLOSE.equals(device.getLockStatus())){
updateLocationHandle(msg, logEntry, value, device);
}
}
// 计算执行时间以毫秒为单位
long duration = (System.nanoTime() - startTime) / 1_000_000;
log.info("-------------------【定时任务5分钟一次】更新设备的定位和电压----结束---------------"+duration+ " 毫秒");
}
private void updateLocationHandle(String msg, LogEntry logEntry, LogEntry.LocationValue value, AsDevice device) {
// 坐标转换 WGS84 GCJ02
double[] doubles = coordinateConvert(value);
BigDecimal lon = new BigDecimal(doubles[1]).setScale(8, RoundingMode.HALF_UP);
BigDecimal lat = new BigDecimal(doubles[0]).setScale(8, RoundingMode.HALF_UP);
asynchronousSaveLog(msg, logEntry.getAt(), logEntry.getDevName(), lon, lat, device);
BigDecimal divide = new BigDecimal(value.getBat()).divide(new BigDecimal(10));
device.setVoltage(divide.toString());//电压
EtModel model = etModelService.selectEtModelByModelId(device.getModelId());
device.setLastTime(DateUtils.getNowDate());
device.setSignalStrength(value.getCsq());
device.setQuality(value.getQ());
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());
}
if(BigDecimal.ZERO.compareTo(lon) != 0 && BigDecimal.ZERO.compareTo(lat) != 0){
device.setLatitude(lat.toString());
device.setLongitude(lon.toString());
device.setLastLocationTime(DateUtils.getNowDate());
device.setGps("1");
// 信号强度
device.setSatellites(value.getS());
}else{
device.setGps("0");
device.setSatellites(0);
}
int i = deviceService.updateLocation(device);
if(i>0){
log.info("===============更新设备信息成功===========>" + logEntry.getDevName());
}
}
/**
* 异步保存定位
*/
private void asynchronousSaveLog(String msg, long at,String mac,BigDecimal lon,BigDecimal lat,AsDevice device){
//异步保存定位
scheduledExecutorService.schedule(() -> {
EtLocationLog etLocationLog = new EtLocationLog();
etLocationLog.setOnenetMsg(msg);
etLocationLog.setCreateTime(DateUtils.getNowDate());
etLocationLog.setLongitude(lon.toString());
etLocationLog.setLatitude(lat.toString());
etLocationLog.setMac(mac);
etLocationLog.setAt(new Date(at));
etLocationLog.setStatus(device.getStatus());
etLocationLog.setLockStatus(device.getLockStatus());
etLocationLogMapper.insertEtLocationLog(etLocationLog);
}, 0, TimeUnit.SECONDS);
}
/** 坐标转换 */
@NotNull
private double[] coordinateConvert(LogEntry.LocationValue value) {
BigDecimal lon = new BigDecimal(value.getLon());
BigDecimal lat = new BigDecimal(value.getLat());
// 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);
// log.info("WGS84经纬度除以100后" + lon + "---" + lat);
// 取出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;
}
private 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;
}
/**
* 判断优惠券是否过期
*
*/
public void couponIsExpires(){
log.info("-------------------【定时任务】判断优惠券是否过期---开始----------------");
EtCouponUserLog etCouponUserLog = new EtCouponUserLog();
etCouponUserLog.setStatus(ServiceConstants.COUPON_STATUS_UNUSED);
List<EtCouponUserLog> couponUserLogs = etCouponClaimLogMapper.selectEtCouponClaimLogList(etCouponUserLog);
// 获取当前时间
Date currentTime = new Date();
for(EtCouponUserLog couponLog :couponUserLogs){
// 获取优惠券的过期时间
Date expirationTime = couponLog.getExpirationTime();
// 判断优惠券是否过期
if (expirationTime != null && expirationTime.before(currentTime)) {
// 如果过期更新状态为已过期
couponLog.setStatus(ServiceConstants.COUPON_STATUS_EXPIRED);
// 更新到数据库
int result = etCouponClaimLogMapper.updateEtCouponClaimLog(couponLog);
if (result > 0) {
log.info("优惠券ID: {} 已过期,状态已更新为:已过期", couponLog.getCouponId());
} else {
log.warn("优惠券ID: {} 更新状态失败", couponLog.getCouponId());
}
}
}
log.info("-------------------【定时任务】判断优惠券是否过期---结束----------------");
}
}

View File

@ -35,13 +35,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="isAuthentication" column="is_authentication" />
<result property="appName" column="app_name" />
<result property="appId" column="appid" />
<result property="vipType" column="vip_type" />
<result property="expirationTime" column="expiration_time" />
</resultMap>
<sql id="selectUserVo">
select u.user_id, u.user_name, u.real_name, u.id_card, u.nick_name, u.email, u.avatar,
u.phonenumber, u.balance, u.birthday, u.password, u.pay_password, u.sex, u.status,
u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.wxopenid,
u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid
u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid,u.vip_type,u.expiration_time
from et_user u
</sql>
@ -200,6 +202,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="isAuthentication != null">is_authentication,</if>
<if test="appName != null and appName != ''">app_name,</if>
<if test="appId != null and appId != ''">appid,</if>
<if test="vipType != null and vipType != ''">vip_type,</if>
<if test="expirationTime != null and expirationTime != ''">expiration_time,</if>
create_time
)values(
<if test="userId != null and userId != ''">#{userId},</if>
@ -224,6 +228,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="isAuthentication != null">#{isAuthentication},</if>
<if test="appName != null and appName != ''">#{appName},</if>
<if test="appId != null and appId != ''">#{appId},</if>
<if test="vipType != null and vipType != ''">#{vipType},</if>
<if test="expirationTime != null and expirationTime != ''">#{expirationTime},</if>
sysdate()
)
</insert>
@ -254,6 +260,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="isAuthentication != null">is_authentication = #{isAuthentication},</if>
<if test="appName != null">app_name = #{appName},</if>
<if test="appId != null">appid = #{appId},</if>
<if test="vipType != null">vip_type = #{vipType},</if>
<if test="expirationTime != null">expiration_time = #{expirationTime},</if>
update_time = sysdate()
</set>
where user_id = #{userId}

View File

@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.EtCouponClaimLogMapper">
<resultMap type="EtCouponClaimLog" id="EtCouponClaimLogResult">
<resultMap type="EtCouponUserLog" id="EtCouponClaimLogResult">
<result property="logId" column="log_id" />
<result property="areaId" column="area_id" />
<result property="userId" column="user_id" />
@ -19,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select log_id, area_id, user_id, coupon_id, create_time, gain_method, status, expiration_time from et_coupon_user_log
</sql>
<select id="selectEtCouponClaimLogList" parameterType="EtCouponClaimLog" resultMap="EtCouponClaimLogResult">
<select id="selectEtCouponClaimLogList" parameterType="EtCouponUserLog" resultMap="EtCouponClaimLogResult">
select
l.log_id,
l.area_id,
@ -30,24 +30,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
l.coupon_id,
l.create_time,
l.gain_method,
l.expiration_time
l.expiration_time,
c.name couponName,
c.type,
c.retail_price retailPrice
from et_coupon_user_log l
left join et_operating_area a on a.area_id = l.area_id
left join et_user u on u.user_id = l.user_id
left join et_coupon c on c.coupon_id = l.coupon_id
<where>
<if test="areaId != null "> and l.area_id like concat('%', #{areaId}, '%')</if>
<if test="areaName != null "> and a.area_name like concat('%', #{areaName}, '%')</if>
<if test="userId != null "> and l.user_id = #{userId}</if>
<if test="userName != null "> and u.user_name = #{userName}</if>
<if test="gainMethod != null "> and u.gain_method = #{gainMethod}</if>
<if test="gainMethod != null "> and l.gain_method = #{gainMethod}</if>
<if test="status != null and status != ''"> and l.status = #{status}</if>
<if test="couponId != null "> and l.coupon_id like concat('%', #{couponId}, '%')</if>
<if test="statusList != null">
AND o.status IN
<foreach item="item" index="index" collection="statusList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</where>
</select>
@ -56,7 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where log_id = #{logId}
</select>
<insert id="insertEtCouponClaimLog" parameterType="EtCouponClaimLog" useGeneratedKeys="true" keyProperty="logId">
<insert id="insertEtCouponClaimLog" parameterType="EtCouponUserLog" useGeneratedKeys="true" keyProperty="logId">
insert into et_coupon_user_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="areaId != null">area_id,</if>
@ -78,7 +76,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
</insert>
<update id="updateEtCouponClaimLog" parameterType="EtCouponClaimLog">
<update id="updateEtCouponClaimLog" parameterType="EtCouponUserLog">
update et_coupon_user_log
<trim prefix="SET" suffixOverrides=",">
<if test="areaId != null">area_id = #{areaId},</if>

View File

@ -6,55 +6,62 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="EtCoupon" id="EtCouponResult">
<result property="couponId" column="coupon_id" />
<result property="name" column="name" />
<result property="type" column="type" />
<result property="discountPercent" column="discount_percent" />
<result property="areaId" column="area_id" />
<result property="userId" column="user_id" />
<result property="discountAmount" column="discount_amount" />
<result property="createTime" column="create_time" />
<result property="validityValue" column="validity_value" />
<result property="validityUnit" column="validity_unit" />
<result property="status" column="status" />
<result property="limitNum" column="limit_num" />
<result property="desc" column="desc" />
<result property="snackPrice" column="snack_price" />
<result property="descr" column="descr" />
<result property="retailPrice" column="retail_price" />
<result property="originalPrice" column="original_price" />
<result property="isHot" column="is_hot" />
</resultMap>
<sql id="selectEtCouponVo">
select coupon_id, type, discount_percent, area_id, user_id, discount_amount, create_time, validity_value, validity_unit, status, limit_num, `desc`, snack_price from et_coupon
select coupon_id, name, type, discount_percent, area_id, discount_amount, create_time, validity_value, validity_unit, status, limit_num, `descr`, retail_price, original_price, is_hot from et_coupon
</sql>
<select id="selectEtCouponList" parameterType="EtCoupon" resultMap="EtCouponResult">
SELECT
c.coupon_id,
c.name,
c.type,
c.discount_percent,
c.area_id,
a.area_name areaName,
c.user_id,
u.user_name userName,
c.discount_amount,
c.create_time,
c.validity_value,
c.validity_unit,
c.status,
c.limit_num,
c.desc,
c.snack_price
c.descr,
c.retail_price,
c.original_price,
c.is_hot
FROM
et_coupon c
left join et_operating_area a on a.area_id = c.area_id
left join et_user u on u.user_id = c.user_id
<where>
<if test="name != null "> and c.name like concat('%', #{name}, '%')</if>
<if test="type != null and type != ''"> and c.type = #{type}</if>
<if test="discountPercent != null "> and c.discount_percent = #{discountPercent}</if>
<if test="areaId != null "> and c.area_id = #{areaId}</if>
<if test="areaName != null "> and a.area_name like concat('%', #{areaName}, '%')</if>
<if test="userId != null "> and c.user_id = like concat('%', #{userId}, '%')</if>
<if test="userName != null "> and u.user_name = #{userName}</if>
<if test="discountAmount != null "> and c.discount_amount = #{discountAmount}</if>
<if test="status != null and status != ''"> and c.status = #{status}</if>
<if test="limitNum != null and limitNum != ''"> and c.limit_num = #{limitNum}</if>
<if test="typeList != null">
AND c.type IN
<foreach item="item" index="index" collection="typeList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</where>
</select>
@ -66,50 +73,56 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertEtCoupon" parameterType="EtCoupon" useGeneratedKeys="true" keyProperty="couponId">
insert into et_coupon
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if>
<if test="type != null">type,</if>
<if test="discountPercent != null">discount_percent,</if>
<if test="areaId != null">area_id,</if>
<if test="userId != null">user_id,</if>
<if test="discountAmount != null">discount_amount,</if>
<if test="createTime != null">create_time,</if>
<if test="validityValue != null">validity_value,</if>
<if test="validityUnit != null">validity_unit,</if>
<if test="status != null">status,</if>
<if test="limitNum != null">limit_num,</if>
<if test="desc != null">desc,</if>
<if test="snackPrice != null">snack_price,</if>
<if test="descr != null">descr,</if>
<if test="retailPrice != null">retail_price,</if>
<if test="originalPrice != null">original_price,</if>
<if test="isHot != null">is_hot,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">#{name},</if>
<if test="type != null">#{type},</if>
<if test="discountPercent != null">#{discountPercent},</if>
<if test="areaId != null">#{areaId},</if>
<if test="userId != null">#{userId},</if>
<if test="discountAmount != null">#{discountAmount},</if>
<if test="createTime != null">#{createTime},</if>
<if test="validityValue != null">#{validityValue},</if>
<if test="validityUnit != null">#{validityUnit},</if>
<if test="status != null">#{status},</if>
<if test="limitNum != null">#{limitNum},</if>
<if test="desc != null">#{desc},</if>
<if test="snackPrice != null">#{snackPrice},</if>
<if test="descr != null">#{descr},</if>
<if test="retailPrice != null">#{retailPrice},</if>
<if test="originalPrice != null">#{originalPrice},</if>
<if test="isHot != null">#{isHot},</if>
</trim>
</insert>
<update id="updateEtCoupon" parameterType="EtCoupon">
update et_coupon
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">name = #{name},</if>
<if test="type != null">type = #{type},</if>
<if test="discountPercent != null">discount_percent = #{discountPercent},</if>
<if test="areaId != null">area_id = #{areaId},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="discountAmount != null">discount_amount = #{discountAmount},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="validityValue != null">validity_value = #{validityValue},</if>
<if test="validityUnit != null">validity_unit = #{validityUnit},</if>
<if test="status != null">status = #{status},</if>
<if test="limitNum != null">limit_num = #{limitNum},</if>
<if test="desc != null">desc = #{desc},</if>
<if test="snackPrice != null">snack_price = #{snackPrice},</if>
<if test="descr != null">descr = #{descr},</if>
<if test="retailPrice != null">retail_price = #{retailPrice},</if>
<if test="originalPrice != null">original_price = #{originalPrice},</if>
<if test="isHot != null">is_hot = #{isHot},</if>
</trim>
where coupon_id = #{couponId}
</update>

View File

@ -51,6 +51,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where location_id = #{locationId}
</select>
<select id="getLastMsg" resultType="java.lang.String">
SELECT onenet_msg
FROM et_location_log
WHERE mac = #{mac}
ORDER BY create_time DESC
LIMIT 1
</select>
<insert id="insertEtLocationLog" parameterType="EtLocationLog" useGeneratedKeys="true" keyProperty="locationId">
insert into et_location_log
<trim prefix="(" suffix=")" suffixOverrides=",">

View File

@ -47,6 +47,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="usedSn" column="used_sn" />
<result property="changeReason" column="change_reason" />
<result property="locking" column="locking" />
<result property="autoRefundDeposit" column="auto_refund_deposit" />
<result property="freeRideTime" column="free_ride_time" />
<result property="rentalUnit" column="rental_unit" />
<result property="ridingRule" column="riding_rule" />
<result property="ridingRuleJson" column="riding_rule_json" />
<result property="chargingCycle" column="charging_cycle" />
<result property="chargingCycleValue" column="charging_cycle_value" />
<result property="cappedAmount" column="capped_amount" />
</resultMap>
<sql id="selectEtOrderVo">
@ -54,7 +62,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
device_mac, sn, pay_time, paid, pay_type, type, total_fee, pay_fee, dispatch_fee,
manage_fee, riding_fee, appointment_fee, mark, duration, distance, status,
create_time, appointment_start_time, appointment_end_time,appointment_timeout, unlock_time,return_time,
rule_end_time, return_type, AsText(trip_route) trip_route,trip_route_str,cycle,deposit_deduction,video_url,upload_time,deduction_amount,audio_files,used_sn,change_reason,locking from et_order
rule_end_time, return_type, AsText(trip_route) trip_route,trip_route_str,cycle,deposit_deduction,video_url,
upload_time,deduction_amount,audio_files,used_sn,change_reason,locking,auto_refund_deposit,free_ride_time,
rental_unit,riding_rule,riding_rule_json,charging_cycle,charging_cycle_value,capped_amount from et_order
</sql>
<sql id="selectEtOrderVoNoRoute">
@ -62,7 +72,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
device_mac, sn, pay_time, paid, pay_type, type, total_fee, pay_fee, dispatch_fee,
manage_fee, riding_fee, appointment_fee, mark, duration, distance, status,
create_time, appointment_start_time, appointment_end_time,appointment_timeout, unlock_time,return_time,
rule_end_time, return_type, cycle,deposit_deduction,video_url,upload_time,deduction_amount,audio_files,used_sn,change_reason,locking from et_order
rule_end_time, return_type, cycle,deposit_deduction,video_url,upload_time,deduction_amount,audio_files,used_sn,change_reason,locking,auto_refund_deposit,free_ride_time,
rental_unit,riding_rule,riding_rule_json,charging_cycle,charging_cycle_value,capped_amountfrom et_order
</sql>
<select id="selectEtOrderList" parameterType="EtOrder" resultMap="EtOrderResult">
@ -817,6 +828,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="tripRoute != null">trip_route,</if>
<if test="tripRouteStr != null">trip_route_str,</if>
<if test="cycle != null">cycle,</if>
<if test="autoRefundDeposit != null">auto_refund_deposit,</if>
<if test="freeRideTime != null">free_ride_time,</if>
<if test="rentalUnit != null">rental_unit,</if>
<if test="ridingRule != null">riding_rule,</if>
<if test="ridingRuleJson != null">riding_rule_json,</if>
<if test="chargingCycle != null">charging_cycle,</if>
<if test="chargingCycleValue != null">charging_cycle_value,</if>
<if test="cappedAmount != null">capped_amount,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderId != null">#{orderId},</if>
@ -851,6 +870,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="tripRoute != null">GeomFromText(#{tripRoute}),</if>
<if test="tripRouteStr != null">#{tripRouteStr},</if>
<if test="cycle != null">#{cycle},</if>
<if test="autoRefundDeposit != null">#{autoRefundDeposit},</if>
<if test="freeRideTime != null">#{freeRideTime},</if>
<if test="rentalUnit != null">#{rentalUnit},</if>
<if test="ridingRule != null">#{ridingRule},</if>
<if test="ridingRuleJson != null">#{ridingRuleJson},</if>
<if test="chargingCycle != null">#{chargingCycle},</if>
<if test="chargingCycleValue != null">#{chargingCycleValue},</if>
<if test="cappedAmount != null">#{cappedAmount},</if>
</trim>
</insert>
@ -895,6 +922,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="usedSn != null">used_sn = #{usedSn},</if>
<if test="changeReason != null">change_reason = #{changeReason},</if>
<if test="locking != null">locking = #{locking},</if>
<if test="autoRefundDeposit != null">auto_refund_deposit = #{autoRefundDeposit},</if>
<if test="freeRideTime != null">free_ride_time = #{freeRideTime},</if>
<if test="rentalUnit != null">rental_unit = #{rentalUnit},</if>
<if test="ridingRule != null">riding_rule = #{ridingRule},</if>
<if test="ridingRuleJson != null">riding_rule_json = #{ridingRuleJson},</if>
<if test="chargingCycle != null">charging_cycle = #{chargingCycle},</if>
<if test="chargingCycleValue != null">charging_cycle_value = #{chargingCycleValue},</if>
<if test="cappedAmount != null">capped_amount = #{cappedAmount},</if>
</trim>
where order_id = #{orderId}
</update>
@ -940,6 +975,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="usedSn != null">used_sn = #{usedSn},</if>
<if test="changeReason != null">change_reason = #{changeReason},</if>
<if test="locking != null">locking = #{locking},</if>
<if test="autoRefundDeposit != null">auto_refund_deposit = #{autoRefundDeposit},</if>
<if test="freeRideTime != null">free_ride_time = #{freeRideTime},</if>
<if test="rentalUnit != null">rental_unit = #{rentalUnit},</if>
<if test="ridingRule != null">riding_rule = #{ridingRule},</if>
<if test="ridingRuleJson != null">riding_rule_json = #{ridingRuleJson},</if>
<if test="chargingCycle != null">charging_cycle = #{chargingCycle},</if>
<if test="chargingCycleValue != null">charging_cycle_value = #{chargingCycleValue},</if>
<if test="cappedAmount != null">capped_amount = #{cappedAmount},</if>
</trim>
where order_no = #{orderNo}
</update>