操作日志

This commit is contained in:
磷叶 2025-05-14 18:11:30 +08:00
parent bac3041339
commit 4ab271acc9
22 changed files with 427 additions and 29 deletions

View File

@ -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";
}

View File

@ -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;

View File

@ -0,0 +1,55 @@
package com.ruoyi.common.utils;
import java.util.HashMap;
import java.util.Map;
/**
* 日志参数持有者用于在当前线程中传递参数到日志切面
*/
public class LogParamHolder {
private static final ThreadLocal<Map<String, Object>> 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<String, Object> getAll() {
return PARAM_HOLDER.get();
}
/**
* 清除当前线程的参数
*/
public static void clear() {
PARAM_HOLDER.remove();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -19,6 +19,8 @@ public class DeviceIotVO {
// 物联网操作是否成功
private Boolean iot;
public boolean isIotSuccess() {
return iot != null && iot;
}
}

View File

@ -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;
}
}

View File

@ -31,6 +31,9 @@ public class OrderEndDTO implements LogBizParam {
@ApiModelProperty("还车类型")
private String returnType;
@ApiModelProperty("是否必须IOT成功")
private Boolean requiredIot;
@Override
public Object logBizId() {
return orderId;

View File

@ -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;
}
}

View File

@ -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());

View File

@ -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不保存定位日志

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<OperLog> list);
}

View File

@ -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
</sql>
@ -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>
<insert id="batchInsert" parameterType="SysOperLog" useGeneratedKeys="true" keyProperty="operId">
insert into sys_oper_log
<trim prefix="(" suffix=")" suffixOverrides=",">
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,
</trim>
values
<foreach collection="list" item="i" separator=",">
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="i.title != null ">#{i.title},</if>
<if test="i.title == null ">default,</if>
<if test="i.businessType != null ">#{i.businessType},</if>
<if test="i.businessType == null ">default,</if>
<if test="i.method != null ">#{i.method},</if>
<if test="i.method == null ">default,</if>
<if test="i.requestMethod != null ">#{i.requestMethod},</if>
<if test="i.requestMethod == null ">default,</if>
<if test="i.operatorType != null ">#{i.operatorType},</if>
<if test="i.operatorType == null ">default,</if>
<if test="i.operName != null ">#{i.operName},</if>
<if test="i.operName == null ">default,</if>
<if test="i.deptName != null ">#{i.deptName},</if>
<if test="i.deptName == null ">default,</if>
<if test="i.operUrl != null ">#{i.operUrl},</if>
<if test="i.operUrl == null ">default,</if>
<if test="i.operIp != null ">#{i.operIp},</if>
<if test="i.operIp == null ">default,</if>
<if test="i.operLocation != null ">#{i.operLocation},</if>
<if test="i.operLocation == null ">default,</if>
<if test="i.operParam != null ">#{i.operParam},</if>
<if test="i.operParam == null ">default,</if>
<if test="i.jsonResult != null ">#{i.jsonResult},</if>
<if test="i.jsonResult == null ">default,</if>
<if test="i.status != null ">#{i.status},</if>
<if test="i.status == null ">default,</if>
<if test="i.errorMsg != null ">#{i.errorMsg},</if>
<if test="i.errorMsg == null ">default,</if>
<if test="i.operTime != null ">#{i.operTime},</if>
<if test="i.operTime == null ">default,</if>
<if test="i.costTime != null ">#{i.costTime},</if>
<if test="i.costTime == null ">default,</if>
<if test="i.bizIds != null ">#{i.bizIds,typeHandler=com.ruoyi.common.mybatis.typehandler.StringSplitListTypeHandler},</if>
<if test="i.bizIds == null ">default,</if>
<if test="i.bizType != null ">#{i.bizType},</if>
<if test="i.bizType == null ">default,</if>
<if test="i.operUserId != null ">#{i.operUserId},</if>
<if test="i.operUserId == null ">default,</if>
<if test="i.deviceId != null ">#{i.deviceId},</if>
<if test="i.deviceId == null ">default,</if>
<if test="i.deviceLon != null ">#{i.deviceLon},</if>
<if test="i.deviceLon == null ">default,</if>
<if test="i.deviceLat != null ">#{i.deviceLat},</if>
<if test="i.deviceLat == null ">default,</if>
<if test="i.paramLon != null ">#{i.paramLon},</if>
<if test="i.paramLon == null ">default,</if>
<if test="i.paramLat != null ">#{i.paramLat},</if>
<if test="i.paramLat == null ">default,</if>
</trim>
</foreach>
</insert>
<select id="selectOperLogList" parameterType="OperLogQuery" resultMap="SysOperLogResult">
<include refid="selectOperLogVo"/>
<where>
@ -111,6 +210,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="bizType != null and bizType != ''">
and biz_type = #{bizType}
</if>
<if test="operParam != null and operParam != ''">
and oper_param like concat('%', #{operParam}, '%')
</if>
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
AND oper_time &gt;= #{params.beginTime}
</if>
@ -124,6 +226,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND oper_time &gt;= #{operTimeRange[0]}
AND oper_time &lt;= #{operTimeRange[1]}
</if>
<if test="deviceId != null">
and device_id = #{deviceId}
</if>
</where>
order by oper_id desc
</select>

View File

@ -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<OperLog> list);
}

View File

@ -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<OperLog> list) {
return operLogMapper.batchInsert(list);
}
}

View File

@ -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<OperLog> logList = redisCache.getAndClearCacheList(CacheConstants.OPER_LOG_QUEUE);
// 保存到数据库
int rows = operLogService.batchInsert(logList);
log.info("保存到数据库{}条操作日志", rows);
}
}

View File

@ -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())) {

View File

@ -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));
}

View File

@ -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);

View File

@ -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<OperLogVO> list = operLogService.selectOperLogList(query);
return success(list);
}
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
@PostMapping("/export")