diff --git a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java index ebccc06..4a9f47f 100644 --- a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java +++ b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -117,4 +117,9 @@ public class CacheConstants * 所有硬件版本名称 */ public static final String ALL_HARDWARE_VERSION_NAME = "all_hardware_version_name"; + + /** + * 操作日志队列 + */ + public static final String OPER_LOG_QUEUE = "oper_log_queue"; } diff --git a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/enums/LogBizType.java b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/enums/LogBizType.java index b606237..b23db49 100644 --- a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/enums/LogBizType.java +++ b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/enums/LogBizType.java @@ -40,7 +40,8 @@ public enum LogBizType { SOFTWARE_VERSION("SOFTWARE_VERSION", "软件版本"), USER_APP("USER_APP", "用户APP关联"), WITHDRAW("WITHDRAW", "提现"), - USER("USER", "用户"); + USER("USER", "用户"), + COMMAND_LOG("COMMAND_LOG", "命令日志"); private final String type; private final String msg; diff --git a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/utils/LogParamHolder.java b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/utils/LogParamHolder.java new file mode 100644 index 0000000..ff1cad6 --- /dev/null +++ b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/utils/LogParamHolder.java @@ -0,0 +1,55 @@ +package com.ruoyi.common.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * 日志参数持有者,用于在当前线程中传递参数到日志切面 + */ +public class LogParamHolder { + + private static final ThreadLocal> PARAM_HOLDER = ThreadLocal.withInitial(HashMap::new); + + public static final String DEVICE_LON = "deviceLon"; // 设备经度 + public static final String DEVICE_LAT = "deviceLat"; // 设备纬度 + public static final String DEVICE_ID = "deviceId"; // 设备ID、 + public static final String PARAM_LON = "paramLon"; // 参数经度 + public static final String PARAM_LAT = "paramLat"; // 参数纬度 + + /** + * 设置参数 + * + * @param key 参数键 + * @param value 参数值 + */ + public static void set(String key, Object value) { + PARAM_HOLDER.get().put(key, value); + } + + /** + * 获取参数 + * + * @param key 参数键 + * @return 参数值 + */ + public static Object get(String key) { + return PARAM_HOLDER.get().get(key); + } + + /** + * 获取所有参数 + * + * @return 参数Map + */ + public static Map getAll() { + return PARAM_HOLDER.get(); + } + + /** + * 清除当前线程的参数 + */ + public static void clear() { + PARAM_HOLDER.remove(); + } + +} \ No newline at end of file diff --git a/common-ruoyi/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/common-ruoyi/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java index 83789f0..fbd2ad6 100644 --- a/common-ruoyi/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java +++ b/common-ruoyi/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -36,6 +36,7 @@ import com.ruoyi.common.core.interfaces.LogBizParam; import com.ruoyi.common.enums.BusinessStatus; import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.filter.PropertyPreExcludeFilter; +import com.ruoyi.common.utils.LogParamHolder; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; @@ -210,6 +211,18 @@ public class LogAspect getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); // 设置消耗时间 operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get()); + // 获取设备信息 + Object deviceId = LogParamHolder.get(LogParamHolder.DEVICE_ID); + operLog.setDeviceId(deviceId != null ? (Long) deviceId : null); + Object deviceLon = LogParamHolder.get(LogParamHolder.DEVICE_LON); + operLog.setDeviceLon(deviceLon != null ? deviceLon.toString() : null); + Object deviceLat = LogParamHolder.get(LogParamHolder.DEVICE_LAT); + operLog.setDeviceLat(deviceLat != null ? deviceLat.toString() : null); + Object paramLon = LogParamHolder.get(LogParamHolder.PARAM_LON); + operLog.setParamLon(paramLon != null ? paramLon.toString() : null); + Object paramLat = LogParamHolder.get(LogParamHolder.PARAM_LAT); + operLog.setParamLat(paramLat != null ? paramLat.toString() : null); + // 保存数据库 AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); } @@ -222,6 +235,8 @@ public class LogAspect finally { TIME_THREADLOCAL.remove(); + // 清理ThreadLocal中的参数 + LogParamHolder.clear(); } } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/commandLog/domain/CommandLog.java b/ruoyi-service/src/main/java/com/ruoyi/bst/commandLog/domain/CommandLog.java index 2023291..184789a 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/commandLog/domain/CommandLog.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/commandLog/domain/CommandLog.java @@ -7,6 +7,7 @@ import org.springframework.format.annotation.DateTimeFormat; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.interfaces.LogBizParam; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -18,7 +19,7 @@ import lombok.Data; * @date 2025-04-03 */ @Data -public class CommandLog extends BaseEntity +public class CommandLog extends BaseEntity implements LogBizParam { private static final long serialVersionUID = 1L; @@ -76,4 +77,9 @@ public class CommandLog extends BaseEntity @Excel(name = "原始响应") @ApiModelProperty("原始响应") private String originResponse; + + @Override + public Object logBizId() { + return this.id; + } } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/vo/DeviceIotVO.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/vo/DeviceIotVO.java index ca50e47..266ad20 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/vo/DeviceIotVO.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/domain/vo/DeviceIotVO.java @@ -19,6 +19,8 @@ public class DeviceIotVO { // 物联网操作是否成功 private Boolean iot; - + public boolean isIotSuccess() { + return iot != null && iot; + } } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java b/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java index 7635086..ea4936e 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/device/utils/DeviceUtil.java @@ -104,4 +104,22 @@ public class DeviceUtil { && !MathUtils.equals(lon, BigDecimal.ZERO) && !MathUtils.equals(lat, BigDecimal.ZERO); } + + /** + * 判断设备信号是否弱 + * @param device 设备 + * @return 是否弱 + */ + public static boolean isLowSignal(DeviceVO device) { + return device != null && device.getSignalStrength() != null && device.getSignalStrength() < 10; + } + + /** + * 判断卫星信号是否弱 + * @param device 设备 + * @return 是否弱 + */ + public static boolean isLowSatelliteSignal(DeviceVO device) { + return device != null && device.getSatellites() != null && device.getSatellites() <= 5; + } } \ No newline at end of file diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderEndDTO.java b/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderEndDTO.java index 01d49f7..06e411f 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderEndDTO.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderEndDTO.java @@ -30,6 +30,9 @@ public class OrderEndDTO implements LogBizParam { @ApiModelProperty("还车类型") private String returnType; + + @ApiModelProperty("是否必须IOT成功") + private Boolean requiredIot; @Override public Object logBizId() { diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderOpenDeviceDTO.java b/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderOpenDeviceDTO.java index db0316a..baaf065 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderOpenDeviceDTO.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/order/domain/dto/OrderOpenDeviceDTO.java @@ -4,6 +4,8 @@ import java.math.BigDecimal; import javax.validation.constraints.NotNull; +import com.ruoyi.common.core.interfaces.LogBizParam; + import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -11,7 +13,7 @@ import lombok.Data; * 订单开锁请求参数 */ @Data -public class OrderOpenDeviceDTO { +public class OrderOpenDeviceDTO implements LogBizParam { @ApiModelProperty("订单id") @NotNull(message = "订单id不能为空") private Long orderId; @@ -24,4 +26,9 @@ public class OrderOpenDeviceDTO { @ApiModelProperty("IOT是否必须成功") private Boolean requiredIot; + + @Override + public Object logBizId() { + return this.orderId; + } } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java index 6531534..443aee1 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/order/service/impl/OrderServiceImpl.java @@ -77,6 +77,7 @@ import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisLock; import com.ruoyi.common.core.redis.enums.RedisLockKey; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.LogParamHolder; import com.ruoyi.common.utils.MathUtils; import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.SnowFlakeUtil; @@ -403,8 +404,11 @@ public class OrderServiceImpl implements OrderService { // 转为BO对象 OrderEndBO bo = orderConverter.toEndBO(dto); - // 异步使用手机定位更新设备定位 + // 获取设备信息 DeviceVO device = bo.getDevice(); + // 设置日志参数 + this.setLogParam(dto.getLon(), dto.getLat(), device); + // 异步使用手机定位更新设备定位 this.handleDeviceLocationAsync(device, dto.getLon(), dto.getLat()); // 校验参数 @@ -456,7 +460,7 @@ public class OrderServiceImpl implements OrderService { // 设备上锁(必须放最后,因为会操作设备) DeviceIotVO lock = deviceIotService.lock(orderDevice.getDeviceId(), isAdmin, - "订单结束上锁:" + orderDevice.getOrderNo(), false); + "订单结束上锁:" + orderDevice.getOrderNo(), dto.getRequiredIot()); ServiceUtil.assertion(lock.getDb() != 1, "ID为%s的设备上锁失败", orderDevice.getDeviceId()); vo.setIot(lock.getIot()); @@ -471,9 +475,25 @@ public class OrderServiceImpl implements OrderService { return vo; } + /** + * 设置日志参数 + * @param lon 手机定位经度 + * @param lat 手机定位纬度 + * @param device 设备信息 + */ + private void setLogParam(BigDecimal lon, BigDecimal lat, DeviceVO device) { + LogParamHolder.set(LogParamHolder.PARAM_LON, lon); + LogParamHolder.set(LogParamHolder.PARAM_LAT, lat); + if (device != null) { + LogParamHolder.set(LogParamHolder.DEVICE_ID, device.getId()); + LogParamHolder.set(LogParamHolder.DEVICE_LON, device.getLongitude()); + LogParamHolder.set(LogParamHolder.DEVICE_LAT, device.getLatitude()); + } + } + // 异步使用手机定位更新设备定位 private void handleDeviceLocationAsync(DeviceVO device, BigDecimal lon, BigDecimal lat) { - if (device != null && device.getId() != null && DeviceUtil.validLocation(lon, lat)) { + if (device != null && device.getId() != null && DeviceUtil.isLowSatelliteSignal(device) && DeviceUtil.validLocation(lon, lat)) { scheduledExecutorService.execute(() -> { device.setLongitude(lon); device.setLatitude(lat); @@ -625,6 +645,7 @@ public class OrderServiceImpl implements OrderService { return null; } + // 设备信息 DeviceVO device = deviceService.selectDeviceById(order.getDeviceId()); deviceIotService.refresh(device, null); if (device == null) { @@ -680,7 +701,9 @@ public class OrderServiceImpl implements OrderService { // 查询设备 DeviceVO device = deviceService.selectDeviceById(orderDevice.getDeviceId()); ServiceUtil.assertion(device == null, "ID为%s的设备不存在", orderDevice.getDeviceId()); - + deviceIotService.refresh(device, null); + // 设置日志参数 + this.setLogParam(dto.getLon(), dto.getLat(), device); // 异步使用手机定位更新设备定位 this.handleDeviceLocationAsync(device, dto.getLon(), dto.getLat()); @@ -705,7 +728,8 @@ public class OrderServiceImpl implements OrderService { DeviceVO device = deviceService.selectDeviceById(orderDevice.getDeviceId()); ServiceUtil.assertion(device == null, "ID为%s的设备不存在", orderDevice.getDeviceId()); deviceIotService.refresh(device, null); - + // 设置日志参数 + this.setLogParam(dto.getLon(), dto.getLat(), device); // 异步使用手机定位更新设备定位 this.handleDeviceLocationAsync(device, dto.getLon(), dto.getLat()); @@ -744,6 +768,8 @@ public class OrderServiceImpl implements OrderService { OrderInParkingVO inParkingVO = bo.getInParkingVO(); DeviceVO oldDevice = bo.getOldDevice(); + // 设置日志参数 + this.setLogParam(dto.getLon(), dto.getLat(), oldDevice); // 异步使用手机定位更新设备定位 this.handleDeviceLocationAsync(oldDevice, dto.getLon(), dto.getLat()); diff --git a/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java index bfcc1c6..cceb9f7 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/iot/service/impl/IotReceiveServiceImpl.java @@ -3,6 +3,7 @@ package com.ruoyi.iot.service.impl; import java.math.BigDecimal; import java.time.Duration; import java.time.LocalDateTime; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -21,6 +22,7 @@ import com.ruoyi.bst.device.domain.enums.DeviceLockStatus; import com.ruoyi.bst.device.domain.enums.DeviceQuality; import com.ruoyi.bst.device.domain.enums.DeviceStatus; import com.ruoyi.bst.device.domain.enums.DeviceUnLockType; +import com.ruoyi.bst.device.domain.vo.DeviceIotVO; import com.ruoyi.bst.device.service.DeviceIotService; import com.ruoyi.bst.device.service.DeviceService; import com.ruoyi.bst.device.utils.DeviceUtil; @@ -28,6 +30,8 @@ import com.ruoyi.bst.locationLog.domain.LocationLog; import com.ruoyi.bst.locationLog.service.LocationLogConverter; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.LogBizType; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.MathUtils; import com.ruoyi.common.utils.StringUtils; @@ -37,6 +41,8 @@ import com.ruoyi.iot.domain.ReceiveMsg; import com.ruoyi.iot.enums.ReceiveType; import com.ruoyi.iot.service.IotReceiveService; import com.ruoyi.iot.util.IotUtil; +import com.ruoyi.system.operLog.domain.OperLog; +import com.ruoyi.system.operLog.domain.enums.OperLogStatus; import com.ruoyi.ws.service.DeviceWebSocketService; import lombok.extern.slf4j.Slf4j; @@ -242,6 +248,7 @@ public class IotReceiveServiceImpl implements IotReceiveService { if (!hasOrder) { return 0; } + Long orderId = device.getOrderId(); // 获取车辆位置信息 LocationAreaVO locationArea = AreaUtil.getLocationArea(device.getLongitude(), device.getLatitude(), area, noRidingList); @@ -254,7 +261,8 @@ public class IotReceiveServiceImpl implements IotReceiveService { // 在运营区内,并且不在禁行区内,并且车辆为强制断电状态,为车辆上电 if (isInAreaMax && !isInNoRidingArea && isQLocked && !isOpen && hasOrder) { - deviceIotService.unlock(device, DeviceUnLockType.BACK_AREA, "重新返回运营区上电", false); + DeviceIotVO unlock = deviceIotService.unlock(device, DeviceUnLockType.BACK_AREA, "重新返回运营区上电", false); + this.operLog("重新返回运营区上电", unlock.isIotSuccess(), LogBizType.ORDER, orderId, device); return 1; } @@ -262,13 +270,15 @@ public class IotReceiveServiceImpl implements IotReceiveService { if (noRidingOutage) { // 进入禁行区,并且车辆为开锁状态,强制断电 if (isInNoRidingArea && isOpen) { - deviceIotService.qLock(device, "进入禁行区,强制断电", false); + DeviceIotVO qLock = deviceIotService.qLock(device, "进入禁行区,强制断电", false); + this.operLog("进入禁行区,强制断电", qLock.isIotSuccess(), LogBizType.ORDER, orderId, device); return 1; } // 靠近禁行区,并且为开启状态,播报语音警告 if (isNearNoRidingArea && isOpen) { - deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近禁行区", false); + boolean play = deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近禁行区", false); + this.operLog("靠近禁行区,播报语音警告", play, LogBizType.ORDER, orderId, device); return 1; } } @@ -278,17 +288,20 @@ public class IotReceiveServiceImpl implements IotReceiveService { if (areaOutOutage && hasAreaBoundary) { // 超出运营区最大边界 && 有订单 && 不是调度中,强制断电 if (!isInAreaMax && hasOrder && !isDispatching) { - deviceIotService.qLock(device, "超出运营区外边界最大值,强制断电", false); + DeviceIotVO qLock = deviceIotService.qLock(device, "超出运营区外边界最大值,强制断电", false); + this.operLog("超出运营区外边界最大值,强制断电", qLock.isIotSuccess(), LogBizType.ORDER, orderId, device); return 1; } // 二次警告 if(!isInArea && isInAreaMax) { - deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_OUT, "超出运营区外边界,还未到达断电距离", false); + boolean play = deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_OUT, "超出运营区外边界,还未到达断电距离", false); + this.operLog("超出运营区外边界警告", play, LogBizType.ORDER, orderId, device); return 1; } // 一次警告 if (isInArea && !isInAreaMin) { - deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近运营区内边界", false); + boolean play = deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近运营区内边界", false); + this.operLog("靠近运营区内边界警告", play, LogBizType.ORDER, orderId, device); return 1; } } @@ -296,6 +309,33 @@ public class IotReceiveServiceImpl implements IotReceiveService { return 0; } + /** + * 记录操作日志 + */ + private void operLog(String title, boolean success, LogBizType bizType, Long bizId, DeviceVO device) { + OperLog operLog = new OperLog(); + operLog.setTitle(title); + operLog.setBusinessType(BusinessType.OTHER.name()); + operLog.setBizType(bizType.getType()); + operLog.setBizIds(Collections.singletonList(bizId.toString())); + operLog.setOperName("系统"); + operLog.setOperTime(DateUtils.getNowDate()); + operLog.setStatus(success ? OperLogStatus.SUCCESS.getCode() : OperLogStatus.FAIL.getCode()); + + if (device != null) { + operLog.setDeviceId(device.getId()); + if (device.getLongitude() != null) { + operLog.setDeviceLon(device.getLongitude().toString()); + } + if (device.getLatitude() != null) { + operLog.setDeviceLat(device.getLatitude().toString()); + } + } + + // 保存到Redis缓存 + redisCache.rightPush(CacheConstants.OPER_LOG_QUEUE, operLog); + } + // 定位日志处理 private void handleLocationLog(DeviceVO device) { // 卫星数量小于5,不保存定位日志 diff --git a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/OperLog.java b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/OperLog.java index ba15bbb..6fd05e7 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/OperLog.java +++ b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/OperLog.java @@ -101,4 +101,24 @@ public class OperLog extends BaseEntity /** 操作人ID */ @Excel(name = "操作人ID") private Long operUserId; + + /** 设备ID */ + @Excel(name = "设备ID") + private Long deviceId; + + /** 设备经度 */ + @Excel(name = "设备经度") + private String deviceLon; + + /** 设备纬度 */ + @Excel(name = "设备纬度") + private String deviceLat; + + /** 参数经度 */ + @Excel(name = "参数经度") + private String paramLon; + + /** 参数纬度 */ + @Excel(name = "参数纬度") + private String paramLat; } diff --git a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/enums/OperLogStatus.java b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/enums/OperLogStatus.java new file mode 100644 index 0000000..34ee22d --- /dev/null +++ b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/domain/enums/OperLogStatus.java @@ -0,0 +1,15 @@ +package com.ruoyi.system.operLog.domain.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum OperLogStatus { + SUCCESS(1, "成功"), + FAIL(0, "失败"); + + private final Integer code; + private final String message; + +} diff --git a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.java b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.java index 985eff8..2217054 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.java +++ b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.java @@ -1,11 +1,13 @@ package com.ruoyi.system.operLog.mapper; +import java.util.List; + +import org.apache.ibatis.annotations.Param; + import com.ruoyi.system.operLog.domain.OperLog; import com.ruoyi.system.operLog.domain.OperLogQuery; import com.ruoyi.system.operLog.domain.OperLogVO; -import java.util.List; - /** * 操作日志 数据层 * @@ -48,4 +50,11 @@ public interface OperLogMapper * 清空操作日志 */ public void cleanOperLog(); + + /** + * 批量插入操作日志 + * @param list 操作日志列表 + * @return 插入的条数 + */ + public int batchInsert(@Param("list") List list); } diff --git a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.xml b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.xml index 77ccaae..a8017ea 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.xml +++ b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/mapper/OperLogMapper.xml @@ -29,7 +29,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" cost_time, biz_ids, biz_type, - oper_user_id + oper_user_id, + device_id, + device_lon, + device_lat, + param_lon, + param_lat from sys_oper_log @@ -53,7 +58,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" oper_time, biz_ids, biz_type, - oper_user_id + oper_user_id, + device_id, + device_lon, + device_lat, + param_lon, + param_lat ) values ( #{title}, @@ -74,10 +84,99 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sysdate(), #{bizIds,typeHandler=com.ruoyi.common.mybatis.typehandler.StringSplitListTypeHandler}, #{bizType}, - #{operUserId} + #{operUserId}, + #{deviceId}, + #{deviceLon}, + #{deviceLat}, + #{paramLon}, + #{paramLat} ) + + + insert into sys_oper_log + + title, + business_type, + method, + request_method, + operator_type, + oper_name, + dept_name, + oper_url, + oper_ip, + oper_location, + oper_param, + json_result, + status, + error_msg, + oper_time, + cost_time, + biz_ids, + biz_type, + oper_user_id, + device_id, + device_lon, + device_lat, + param_lon, + param_lat, + + values + + + #{i.title}, + default, + #{i.businessType}, + default, + #{i.method}, + default, + #{i.requestMethod}, + default, + #{i.operatorType}, + default, + #{i.operName}, + default, + #{i.deptName}, + default, + #{i.operUrl}, + default, + #{i.operIp}, + default, + #{i.operLocation}, + default, + #{i.operParam}, + default, + #{i.jsonResult}, + default, + #{i.status}, + default, + #{i.errorMsg}, + default, + #{i.operTime}, + default, + #{i.costTime}, + default, + #{i.bizIds,typeHandler=com.ruoyi.common.mybatis.typehandler.StringSplitListTypeHandler}, + default, + #{i.bizType}, + default, + #{i.operUserId}, + default, + #{i.deviceId}, + default, + #{i.deviceLon}, + default, + #{i.deviceLat}, + default, + #{i.paramLon}, + default, + #{i.paramLat}, + default, + + + + diff --git a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/OperLogService.java b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/OperLogService.java index af07bc2..ac4cda5 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/OperLogService.java +++ b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/OperLogService.java @@ -1,11 +1,11 @@ package com.ruoyi.system.operLog.service; +import java.util.List; + import com.ruoyi.system.operLog.domain.OperLog; import com.ruoyi.system.operLog.domain.OperLogQuery; import com.ruoyi.system.operLog.domain.OperLogVO; -import java.util.List; - /** * 操作日志 服务层 * @@ -48,4 +48,11 @@ public interface OperLogService * 清空操作日志 */ public void cleanOperLog(); + + /** + * 批量插入操作日志 + * @param list 操作日志列表 + * @return 插入的条数 + */ + public int batchInsert(List list); } diff --git a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/impl/OperLogServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/impl/OperLogServiceImpl.java index 66adf5a..0d93012 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/impl/OperLogServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/system/operLog/service/impl/OperLogServiceImpl.java @@ -1,14 +1,15 @@ package com.ruoyi.system.operLog.service.impl; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + import com.ruoyi.system.operLog.domain.OperLog; import com.ruoyi.system.operLog.domain.OperLogQuery; import com.ruoyi.system.operLog.domain.OperLogVO; import com.ruoyi.system.operLog.mapper.OperLogMapper; import com.ruoyi.system.operLog.service.OperLogService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; /** * 操作日志 服务层处理 @@ -76,4 +77,9 @@ public class OperLogServiceImpl implements OperLogService { operLogMapper.cleanOperLog(); } + + @Override + public int batchInsert(List list) { + return operLogMapper.batchInsert(list); + } } diff --git a/ruoyi-web/src/main/java/com/ruoyi/task/OperLog/OperLogTask.java b/ruoyi-web/src/main/java/com/ruoyi/task/OperLog/OperLogTask.java new file mode 100644 index 0000000..6f408e2 --- /dev/null +++ b/ruoyi-web/src/main/java/com/ruoyi/task/OperLog/OperLogTask.java @@ -0,0 +1,34 @@ +package com.ruoyi.task.OperLog; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.system.operLog.domain.OperLog; +import com.ruoyi.system.operLog.service.OperLogService; + +import lombok.extern.slf4j.Slf4j; + +@Component +@Slf4j +public class OperLogTask { + + + @Autowired + private RedisCache redisCache; + + @Autowired + private OperLogService operLogService; + + // 将缓存中的定位日志保存到数据库 + public void freshToDb() { + List logList = redisCache.getAndClearCacheList(CacheConstants.OPER_LOG_QUEUE); + + // 保存到数据库 + int rows = operLogService.batchInsert(logList); + log.info("保存到数据库{}条操作日志", rows); + } +} diff --git a/ruoyi-web/src/main/java/com/ruoyi/web/app/AppCommandLogController.java b/ruoyi-web/src/main/java/com/ruoyi/web/app/AppCommandLogController.java index 5dc243e..ef6048f 100644 --- a/ruoyi-web/src/main/java/com/ruoyi/web/app/AppCommandLogController.java +++ b/ruoyi-web/src/main/java/com/ruoyi/web/app/AppCommandLogController.java @@ -11,6 +11,8 @@ import com.ruoyi.bst.commandLog.service.CommandLogService; 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.common.enums.LogBizType; import com.ruoyi.common.utils.StringUtils; import io.swagger.annotations.ApiOperation; @@ -24,7 +26,7 @@ public class AppCommandLogController extends BaseController { @ApiOperation("记录蓝牙发送命令日志") @PostMapping("/bluetooth") - @Log(title = "记录蓝牙发送命令日志") + @Log(title = "记录蓝牙发送命令日志", businessType = BusinessType.INSERT, bizIdName = "arg0", bizType = LogBizType.COMMAND_LOG) public AjaxResult addBluetoothLog(@RequestBody CommandLog data) { // 去掉MAC号的前缀 if (StringUtils.hasText(data.getMac())) { diff --git a/ruoyi-web/src/main/java/com/ruoyi/web/app/AppOrderController.java b/ruoyi-web/src/main/java/com/ruoyi/web/app/AppOrderController.java index 51e2034..b206964 100644 --- a/ruoyi-web/src/main/java/com/ruoyi/web/app/AppOrderController.java +++ b/ruoyi-web/src/main/java/com/ruoyi/web/app/AppOrderController.java @@ -107,6 +107,7 @@ public class AppOrderController extends BaseController { ServiceUtil.assertion(!orderValidator.canEnd(order, getUserId()), "您无权结束ID为%s的订单", order.getId()); dto.setReturnType(OrderReturnType.NORMAL.getCode()); dto.setEndReason("用户【" + getNickName() + "】手动还车"); + dto.setRequiredIot(false); OrderEndVO vo = orderService.endOrder(dto); if (vo.getDb() > 0) { return success(vo); @@ -131,7 +132,9 @@ public class AppOrderController extends BaseController { ServiceUtil.assertion(order == null, "订单不存在"); ServiceUtil.assertion(!orderValidator.canOpenDevice(order, getUserId()), "您无权操作ID为%s的订单设备开启", order.getId()); ServiceUtil.assertion(orderValidator.isTimeout(order), "当前订单已超时,请在安全的区域还车"); - dto.setRequiredIot(true); + if (dto.getRequiredIot() == null) { + dto.setRequiredIot(true); + } return success(orderService.openDevice(dto)); } @@ -143,7 +146,9 @@ public class AppOrderController extends BaseController { ServiceUtil.assertion(order == null, "订单不存在"); ServiceUtil.assertion(!orderValidator.canCloseDevice(order, getUserId()), "您无权操作ID为%s的订单设备关闭", order.getId()); ServiceUtil.assertion(orderValidator.isTimeout(order), "当前订单已超时,请在安全的区域还车"); - dto.setRequiredIot(true); + if (dto.getRequiredIot() == null) { + dto.setRequiredIot(true); + } return success(orderService.closeDevice(dto)); } diff --git a/ruoyi-web/src/main/java/com/ruoyi/web/bst/OrderController.java b/ruoyi-web/src/main/java/com/ruoyi/web/bst/OrderController.java index 9ada92d..8c2985e 100644 --- a/ruoyi-web/src/main/java/com/ruoyi/web/bst/OrderController.java +++ b/ruoyi-web/src/main/java/com/ruoyi/web/bst/OrderController.java @@ -114,6 +114,7 @@ public class OrderController extends BaseController } dto.setReturnType(OrderReturnType.AUXILIARY.getCode()); dto.setEndReason("管理员【" + getNickName() + "】手动还车"); + dto.setRequiredIot(false); OrderEndVO vo = orderService.endOrder(dto); if (vo.getDb() > 0) { return success(vo); diff --git a/ruoyi-web/src/main/java/com/ruoyi/web/monitor/SysOperlogController.java b/ruoyi-web/src/main/java/com/ruoyi/web/monitor/SysOperlogController.java index f306246..a4f5cba 100644 --- a/ruoyi-web/src/main/java/com/ruoyi/web/monitor/SysOperlogController.java +++ b/ruoyi-web/src/main/java/com/ruoyi/web/monitor/SysOperlogController.java @@ -44,6 +44,22 @@ public class SysOperlogController extends BaseController return getDataTable(list); } + /** + * 查询全部日志 + * @param query + * @return + */ + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/listAll") + public AjaxResult listAll(OperLogQuery query) + { + if (query.getDeviceId() == null && query.getBizId() == null) { + return error("设备ID或业务ID不能为空"); + } + List list = operLogService.selectOperLogList(query); + return success(list); + } + @Log(title = "操作日志", businessType = BusinessType.EXPORT) @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") @PostMapping("/export")