设备控制加日志

master
lld 2026-01-29 23:16:42 +08:00
parent a3019355e0
commit f8f37ae22b
10 changed files with 908 additions and 3 deletions

View File

@ -0,0 +1,34 @@
package com.agri.common.enums;
/**
*
*/
public enum DtuEnum {
JM1K("jm1k", "卷膜1开"),
JM1G("jm1g", "卷膜1关"),
JM2K("jm2k", "卷膜2开"),
JM2G("jm2g", "卷膜2关"),
JM3K("jm3k", "卷膜3开"),
JM3G("jm3g", "卷膜3关"),
JBK("jbk", "卷被开"),
JBG("jbg", "卷被关");
private final String code;
private final String name;
DtuEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
}

View File

@ -5,12 +5,16 @@ import com.agri.framework.config.MqttConfig;
import com.agri.framework.manager.MqttAutoOffManager; import com.agri.framework.manager.MqttAutoOffManager;
import com.agri.framework.manager.MqttSubscriptionManager; import com.agri.framework.manager.MqttSubscriptionManager;
import com.agri.system.domain.SysAgriLimit; import com.agri.system.domain.SysAgriLimit;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysAgriLimitService; import com.agri.system.service.ISysAgriLimitService;
import com.agri.system.service.ISysDevOperLogService;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -76,6 +80,9 @@ public class DeviceStatusHandler {
@Value("${spring.mqtt.latest-ttl-seconds:120}") @Value("${spring.mqtt.latest-ttl-seconds:120}")
private int latestTtlSeconds; private int latestTtlSeconds;
@Autowired
private ISysDevOperLogService sysDevOperLogService;
// 初始化映射(建议放在类初始化块/构造方法中,只初始化一次) // 初始化映射(建议放在类初始化块/构造方法中,只初始化一次)
private static final Map<String, Function<SysAgriLimit, Integer>> LIMIT_MAP = new HashMap<>(); private static final Map<String, Function<SysAgriLimit, Integer>> LIMIT_MAP = new HashMap<>();
private static final Set<String> VALID_FUNC_CODES = new HashSet<>(); private static final Set<String> VALID_FUNC_CODES = new HashSet<>();
@ -171,6 +178,23 @@ public class DeviceStatusHandler {
mqttAutoOffManager.scheduleAutoOff(deviceId, funcType, autoOffSeconds); mqttAutoOffManager.scheduleAutoOff(deviceId, funcType, autoOffSeconds);
log.debug("【自动关任务】标记需要执行deviceId={}, funcType={}, delay={}s", deviceId, funcType, autoOffSeconds); log.debug("【自动关任务】标记需要执行deviceId={}, funcType={}, delay={}s", deviceId, funcType, autoOffSeconds);
} }
sysDevOperLogService.lambdaUpdate()
.eq(SysDevOperLog::getImei, deviceId)
.eq(SysDevOperLog::getFuncCode, funcType)
.eq(SysDevOperLog::getOpType, funcValue)
.eq(SysDevOperLog::getLockAcquired,1)
.orderByDesc(SysDevOperLog::getCreateTime)
.last("LIMIT 1")
.set(SysDevOperLog::getExecResult,1)
.set(SysDevOperLog::getAckReceived,1)
.set(SysDevOperLog::getIsLockSuc,1)
.set(SysDevOperLog::getAckSuc, 1)
.set(SysDevOperLog::getIsTask,autoOffSeconds > 0?1:0)
.set(ObjectUtils.isEmpty(autoOffSeconds), SysDevOperLog::getNoTaskReason,"当前运行时间:【"+autoOffSeconds+"】")
.set(SysDevOperLog::getAck, payload)
.set(SysDevOperLog::getExecResult, 1)
.update();
} }
if (suc && StringUtils.hasText(funcType) && funcValue != null && funcValue == 0) { if (suc && StringUtils.hasText(funcType) && funcValue != null && funcValue == 0) {

View File

@ -2,10 +2,15 @@ package com.agri.framework.interceptor;
import com.agri.framework.config.MqttConfig; import com.agri.framework.config.MqttConfig;
import com.agri.framework.manager.MqttAutoOffManager; import com.agri.framework.manager.MqttAutoOffManager;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.SysAgriLimit; import com.agri.system.domain.SysAgriLimit;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysAgriLimitService; import com.agri.system.service.ISysAgriLimitService;
import com.agri.system.service.ISysDevOperLogService;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference; import com.alibaba.fastjson2.TypeReference;
import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -56,6 +61,12 @@ public class FrontendControlHandler {
@Autowired @Autowired
private ISysAgriLimitService agriLimitService; private ISysAgriLimitService agriLimitService;
@Autowired
private ISysAgriInfoService sysAgriInfoService;
@Autowired
private ISysDevOperLogService sysDevOperLogService;
@Value("${dtu-ctl-lock-ttl}") @Value("${dtu-ctl-lock-ttl}")
private int dtuCtlLockTTL; private int dtuCtlLockTTL;
private static final Map<String, Function<SysAgriLimit, Integer>> LIMIT_MAP = new HashMap<>(); private static final Map<String, Function<SysAgriLimit, Integer>> LIMIT_MAP = new HashMap<>();
@ -133,6 +144,22 @@ public class FrontendControlHandler {
//todo //todo
mqttMessageSender.publish(deviceTopic, payload); mqttMessageSender.publish(deviceTopic, payload);
// testAutoOffTask(deviceId,funcCodeMap); // testAutoOffTask(deviceId,funcCodeMap);
SysAgriInfo agriInfo = sysAgriInfoService.lambdaQuery()
.eq(SysAgriInfo::getImei, deviceId)
.one();
String agriName = (agriInfo!=null && ObjectUtils.isNotEmpty(agriInfo.getAgriName()))?agriInfo.getAgriName():null;
SysDevOperLog logDto = new SysDevOperLog();
logDto.setAgriName(agriName);
logDto.setImei(deviceId);
logDto.setFuncCode(funcType);
logDto.setOpType(funcCodeMap.get(funcType));
logDto.setOpSource(1);
logDto.setPayload(payload);
logDto.setLockAcquired(1);
logDto.setLockHolder(clientId);
logDto.setExecResult(1);
sysDevOperLogService.save(logDto);
log.info("【指令转发】前端{} → 设备{}的{}功能", clientId, deviceId, funcType); log.info("【指令转发】前端{} → 设备{}的{}功能", clientId, deviceId, funcType);
} }

View File

@ -2,11 +2,17 @@ package com.agri.framework.manager;
import com.agri.common.utils.wechat.WxUtil; import com.agri.common.utils.wechat.WxUtil;
import com.agri.framework.config.MqttConfig; import com.agri.framework.config.MqttConfig;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysDevOperLogService;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -67,6 +73,12 @@ public class MqttAutoOffManager {
@Value("${dtu-ctl-lock-ttl}") @Value("${dtu-ctl-lock-ttl}")
private int dtuCtlLockTTL; private int dtuCtlLockTTL;
@Autowired
private ISysAgriInfoService sysAgriInfoService;
@Autowired
private ISysDevOperLogService sysDevOperLogService;
/** /**
* 线 * 线
* @param corePoolSize 线 * @param corePoolSize 线
@ -201,8 +213,10 @@ public class MqttAutoOffManager {
// 新增读取最新状态device:latest:{deviceId}若仍为1则下发 {"funcType":0} 到 dtu/{id}/down // 新增读取最新状态device:latest:{deviceId}若仍为1则下发 {"funcType":0} 到 dtu/{id}/down
private void runAutoOff(String deviceId, String funcType) throws MqttException { private void runAutoOff(String deviceId, String funcType) throws MqttException {
String latest = stringRedisTemplate.opsForValue().get("device:latest:" + deviceId); String latest = stringRedisTemplate.opsForValue().get("device:latest:" + deviceId);
String skipReason = "";
if (!StringUtils.hasText(latest)) { if (!StringUtils.hasText(latest)) {
//todo //todo
skipReason = "【自动关任务】无最新状态";
log.warn("【自动关任务】无最新状态跳过deviceId={}, funcType={}", deviceId, funcType); log.warn("【自动关任务】无最新状态跳过deviceId={}, funcType={}", deviceId, funcType);
return; return;
} }
@ -211,11 +225,13 @@ public class MqttAutoOffManager {
try { try {
latestObj = JSON.parseObject(latest); latestObj = JSON.parseObject(latest);
} catch (Exception e) { } catch (Exception e) {
skipReason = "【自动关任务】执行报错-解析异常";
WxUtil.pushText("自动关任务执行报错-解析异常:\n deviceId: " + deviceId + "\n funcType:" + funcType+"\n 异常:"+e.getMessage()+"\n Cause: "+e.getCause()); WxUtil.pushText("自动关任务执行报错-解析异常:\n deviceId: " + deviceId + "\n funcType:" + funcType+"\n 异常:"+e.getMessage()+"\n Cause: "+e.getCause());
log.warn("【自动关任务】最新状态JSON解析失败跳过deviceId={}, funcType={}", deviceId, funcType); log.warn("【自动关任务】最新状态JSON解析失败跳过deviceId={}, funcType={}", deviceId, funcType);
return; return;
} }
if (latestObj == null || latestObj.isEmpty()) { if (latestObj == null || latestObj.isEmpty()) {
skipReason = "【自动关任务】最新状态为空";
return; return;
} }
@ -226,8 +242,23 @@ public class MqttAutoOffManager {
current = latestObj.getIntValue(funcType); current = latestObj.getIntValue(funcType);
} }
} catch (Exception ignore) { } catch (Exception ignore) {
skipReason = "【自动关任务】最新状态功能码获取失败";
} }
sysDevOperLogService.lambdaUpdate()
.eq(SysDevOperLog::getImei, deviceId)
.eq(SysDevOperLog::getFuncCode, funcType)
.eq(SysDevOperLog::getOpType, 1)
.eq(SysDevOperLog::getOpSource, 1)
.eq(SysDevOperLog::getAckSuc, 1)
.eq(SysDevOperLog::getIsTask, 1)
.orderByDesc(SysDevOperLog::getCreateTime)
.last("LIMIT 1")
.set(SysDevOperLog::getExecResult,1)
.set(SysDevOperLog::getLatestState, latest)
.set(!skipReason.isEmpty(), SysDevOperLog::getSkipReason, skipReason)
.update();
if (current != null && current == 1) { if (current != null && current == 1) {
// 新增:自动关也走分布式锁(避免与前端并发控制同一功能导致乱序/互相覆盖) // 新增:自动关也走分布式锁(避免与前端并发控制同一功能导致乱序/互相覆盖)
String lockKey = "lock:" + deviceId + ":" + funcType; String lockKey = "lock:" + deviceId + ":" + funcType;
@ -238,12 +269,28 @@ public class MqttAutoOffManager {
log.info("【自动关任务】{}功能忙锁占用跳过自动关闭deviceId={}, funcType={}", funcType, deviceId, funcType); log.info("【自动关任务】{}功能忙锁占用跳过自动关闭deviceId={}, funcType={}", funcType, deviceId, funcType);
return; return;
} }
String deviceTopic = "dtu/" + deviceId + "/down";
JSONObject down = new JSONObject(); JSONObject down = new JSONObject();
down.put(funcType, 0); down.put(funcType, 0);
String deviceTopic = "dtu/" + deviceId + "/down";
//todo
mqttMessageSender.publish(deviceTopic, down.toJSONString()); mqttMessageSender.publish(deviceTopic, down.toJSONString());
SysAgriInfo agriInfo = sysAgriInfoService.lambdaQuery()
.eq(SysAgriInfo::getImei, deviceId)
.one();
String agriName = (agriInfo!=null && ObjectUtils.isNotEmpty(agriInfo.getAgriName()))?agriInfo.getAgriName():null;
SysDevOperLog logDto = new SysDevOperLog();
logDto.setAgriName(agriName);
logDto.setImei(deviceId);
logDto.setFuncCode(funcType);
logDto.setOpType(0);
logDto.setOpSource(2);
logDto.setPayload(down.toJSONString());
logDto.setLockAcquired(1);
logDto.setLockHolder("autoOff");
logDto.setExecResult(1);
logDto.setLatestState(latest);
logDto.setTaskStatus(getFutureStatus().toString());
sysDevOperLogService.save(logDto);
log.info("【自动关任务】检测仍在运行已下发关闭deviceId={}, funcType={}, payload={}", deviceId, funcType, down.toJSONString()); log.info("【自动关任务】检测仍在运行已下发关闭deviceId={}, funcType={}, payload={}", deviceId, funcType, down.toJSONString());
} else { } else {
log.info("【自动关任务】检测未运行或状态未知跳过关闭deviceId={}, funcType={}, current={}", deviceId, funcType, current); log.info("【自动关任务】检测未运行或状态未知跳过关闭deviceId={}, funcType={}, current={}", deviceId, funcType, current);
@ -293,5 +340,13 @@ public class MqttAutoOffManager {
return autoOffDeviceCnt.size(); return autoOffDeviceCnt.size();
} }
public JSONObject getFutureStatus() {
JSONObject json = new JSONObject();
json.put("isEnabled", true);
json.put("isExecutorInited", autoOffExecutor != null);
json.put("getTotalTaskCount", autoOffFutureMap.size());
json.put("getDeviceTaskCount", autoOffDeviceCnt.size());
return json;
}
} }

View File

@ -0,0 +1,104 @@
package com.agri.system.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.agri.common.annotation.Log;
import com.agri.common.core.controller.BaseController;
import com.agri.common.core.domain.AjaxResult;
import com.agri.common.enums.BusinessType;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysDevOperLogService;
import com.agri.common.utils.poi.ExcelUtil;
import com.agri.common.core.page.TableDataInfo;
/**
* Controller
*
* @author lld
* @date 2026-01-29
*/
@RestController
@RequestMapping("/control/controllog")
public class SysDevOperLogController extends BaseController
{
@Autowired
private ISysDevOperLogService sysDevOperLogService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('control:controllog:list')")
@GetMapping("/list")
public TableDataInfo list(SysDevOperLog sysDevOperLog)
{
startPage();
List<SysDevOperLog> list = sysDevOperLogService.selectSysDevOperLogList(sysDevOperLog);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('control:controllog:export')")
@Log(title = "设备控制操作日志", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysDevOperLog sysDevOperLog)
{
List<SysDevOperLog> list = sysDevOperLogService.selectSysDevOperLogList(sysDevOperLog);
ExcelUtil<SysDevOperLog> util = new ExcelUtil<SysDevOperLog>(SysDevOperLog.class);
util.exportExcel(response, list, "设备控制操作日志数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('control:controllog:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(sysDevOperLogService.selectSysDevOperLogById(id));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('control:controllog:add')")
@Log(title = "设备控制操作日志", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysDevOperLog sysDevOperLog)
{
return toAjax(sysDevOperLogService.insertSysDevOperLog(sysDevOperLog));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('control:controllog:edit')")
@Log(title = "设备控制操作日志", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysDevOperLog sysDevOperLog)
{
return toAjax(sysDevOperLogService.updateSysDevOperLog(sysDevOperLog));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('control:controllog:remove')")
@Log(title = "设备控制操作日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(sysDevOperLogService.deleteSysDevOperLogByIds(ids));
}
}

View File

@ -0,0 +1,297 @@
package com.agri.system.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Builder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.baomidou.mybatisplus.annotation.TableName;
import com.agri.common.annotation.Excel;
import com.agri.common.core.domain.BaseEntity;
/**
* sys_dev_oper_log
*
* @author lld
* @date 2026-01-29
*/
@TableName("sys_dev_oper_log")
public class SysDevOperLog extends BaseEntity
{
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/** 主键ID */
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 大棚名称 */
@Excel(name = "大棚名称")
private String agriName;
/** imei */
@Excel(name = "imei")
private String imei;
/** 功能码 */
@Excel(name = "功能码")
private String funcCode;
/** 操作类型 */
@Excel(name = "操作类型")
private int opType;
/** 操作来源 */
@Excel(name = "操作来源")
private int opSource;
/** 指令 */
@Excel(name = "指令")
private String payload;
/** 是否成功获取锁 */
@Excel(name = "是否成功获取锁")
private int lockAcquired;
/** 锁持有者 */
@Excel(name = "锁持有者")
private String lockHolder;
/** 当前任务队列情况 */
@Excel(name = "当前任务队列情况")
private String taskStatus;
/** 是否收到设备回执 */
@Excel(name = "是否收到设备回执")
private int ackReceived;
/** 设备控制是否成功 */
@Excel(name = "设备控制是否成功")
private int ackSuc;
/** 设备控制锁是否释放成功 */
@Excel(name = "设备控制锁是否释放成功")
private int isLockSuc;
/** 是否触发定时任务 */
@Excel(name = "是否触发定时任务")
private int isTask;
/** 未触发原因 */
@Excel(name = "未触发原因")
private String noTaskReason;
/** 设备回执 */
@Excel(name = "设备回执")
private String ack;
/** 自动关任务最终执行结果 */
@Excel(name = "自动关任务最终执行结果")
private int execResult;
/** 未执行原因锁占用、无最新状态、JSON异常 */
@Excel(name = "未执行原因", readConverterExp = "如=锁占用、无最新状态、JSON异常")
private String skipReason;
/** 执行前读取的状态快照 */
@Excel(name = "执行前读取的状态快照")
private String latestState;
/** 乐观锁版本号 */
@Version
private Long version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAgriName() {
return agriName;
}
public void setAgriName(String agriName) {
this.agriName = agriName;
}
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getFuncCode() {
return funcCode;
}
public void setFuncCode(String funcCode) {
this.funcCode = funcCode;
}
public int getOpType() {
return opType;
}
public void setOpType(int opType) {
this.opType = opType;
}
public int getOpSource() {
return opSource;
}
public void setOpSource(int opSource) {
this.opSource = opSource;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
public int getLockAcquired() {
return lockAcquired;
}
public void setLockAcquired(int lockAcquired) {
this.lockAcquired = lockAcquired;
}
public String getLockHolder() {
return lockHolder;
}
public void setLockHolder(String lockHolder) {
this.lockHolder = lockHolder;
}
public String getTaskStatus() {
return taskStatus;
}
public void setTaskStatus(String taskStatus) {
this.taskStatus = taskStatus;
}
public int getAckReceived() {
return ackReceived;
}
public void setAckReceived(int ackReceived) {
this.ackReceived = ackReceived;
}
public int getAckSuc() {
return ackSuc;
}
public void setAckSuc(int ackSuc) {
this.ackSuc = ackSuc;
}
public int getIsLockSuc() {
return isLockSuc;
}
public void setIsLockSuc(int isLockSuc) {
this.isLockSuc = isLockSuc;
}
public int getIsTask() {
return isTask;
}
public void setIsTask(int isTask) {
this.isTask = isTask;
}
public String getNoTaskReason() {
return noTaskReason;
}
public void setNoTaskReason(String noTaskReason) {
this.noTaskReason = noTaskReason;
}
public String getAck() {
return ack;
}
public void setAck(String ack) {
this.ack = ack;
}
public int getExecResult() {
return execResult;
}
public void setExecResult(int execResult) {
this.execResult = execResult;
}
public String getSkipReason() {
return skipReason;
}
public void setSkipReason(String skipReason) {
this.skipReason = skipReason;
}
public String getLatestState() {
return latestState;
}
public void setLatestState(String latestState) {
this.latestState = latestState;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("agriName", getAgriName())
.append("imei", getImei())
.append("funcCode", getFuncCode())
.append("opType", getOpType())
.append("opSource", getOpSource())
.append("payload", getPayload())
.append("lockAcquired", getLockAcquired())
.append("lockHolder", getLockHolder())
.append("taskStatus", getTaskStatus())
.append("ackReceived", getAckReceived())
.append("ackSuc", getAckSuc())
.append("isLockSuc", getIsLockSuc())
.append("isTask", getIsTask())
.append("noTaskReason", getNoTaskReason())
.append("ack", getAck())
.append("execResult", getExecResult())
.append("skipReason", getSkipReason())
.append("latestState", getLatestState())
.append("remark", getRemark())
.append("version", getVersion())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,62 @@
package com.agri.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.agri.system.domain.SysDevOperLog;
/**
* Mapper
*
* @author lld
* @date 2026-01-29
*/
public interface SysDevOperLogMapper extends BaseMapper<SysDevOperLog>
{
/**
*
*
* @param id
* @return
*/
public SysDevOperLog selectSysDevOperLogById(Long id);
/**
*
*
* @param sysDevOperLog
* @return
*/
public List<SysDevOperLog> selectSysDevOperLogList(SysDevOperLog sysDevOperLog);
/**
*
*
* @param sysDevOperLog
* @return
*/
public int insertSysDevOperLog(SysDevOperLog sysDevOperLog);
/**
*
*
* @param sysDevOperLog
* @return
*/
public int updateSysDevOperLog(SysDevOperLog sysDevOperLog);
/**
*
*
* @param id
* @return
*/
public int deleteSysDevOperLogById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteSysDevOperLogByIds(Long[] ids);
}

View File

@ -0,0 +1,61 @@
package com.agri.system.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.agri.system.domain.SysDevOperLog;
/**
* Service
*
* @author lld
* @date 2026-01-29
*/
public interface ISysDevOperLogService extends IService<SysDevOperLog> {
/**
*
*
* @param id
* @return
*/
public SysDevOperLog selectSysDevOperLogById(Long id);
/**
*
*
* @param sysDevOperLog
* @return
*/
public List<SysDevOperLog> selectSysDevOperLogList(SysDevOperLog sysDevOperLog);
/**
*
*
* @param sysDevOperLog
* @return
*/
public int insertSysDevOperLog(SysDevOperLog sysDevOperLog);
/**
*
*
* @param sysDevOperLog
* @return
*/
public int updateSysDevOperLog(SysDevOperLog sysDevOperLog);
/**
*
*
* @param ids
* @return
*/
public int deleteSysDevOperLogByIds(Long[] ids);
/**
*
*
* @param id
* @return
*/
public int deleteSysDevOperLogById(Long id);
}

View File

@ -0,0 +1,94 @@
package com.agri.system.service.impl;
import java.util.List;
import com.agri.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.agri.system.mapper.SysDevOperLogMapper;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysDevOperLogService;
/**
* Service
*
* @author lld
* @date 2026-01-29
*/
@Service
public class SysDevOperLogServiceImpl extends ServiceImpl<SysDevOperLogMapper, SysDevOperLog> implements ISysDevOperLogService
{
/**
*
*
* @param id
* @return
*/
@Override
public SysDevOperLog selectSysDevOperLogById(Long id)
{
return baseMapper.selectSysDevOperLogById(id);
}
/**
*
*
* @param sysDevOperLog
* @return
*/
@Override
public List<SysDevOperLog> selectSysDevOperLogList(SysDevOperLog sysDevOperLog)
{
return baseMapper.selectSysDevOperLogList(sysDevOperLog);
}
/**
*
*
* @param sysDevOperLog
* @return
*/
@Override
public int insertSysDevOperLog(SysDevOperLog sysDevOperLog)
{
sysDevOperLog.setCreateTime(DateUtils.getNowDate());
return baseMapper.insertSysDevOperLog(sysDevOperLog);
}
/**
*
*
* @param sysDevOperLog
* @return
*/
@Override
public int updateSysDevOperLog(SysDevOperLog sysDevOperLog)
{
sysDevOperLog.setUpdateTime(DateUtils.getNowDate());
return baseMapper.updateSysDevOperLog(sysDevOperLog);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteSysDevOperLogByIds(Long[] ids)
{
return baseMapper.deleteSysDevOperLogByIds(ids);
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteSysDevOperLogById(Long id)
{
return baseMapper.deleteSysDevOperLogById(id);
}
}

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.agri.system.mapper.SysDevOperLogMapper">
<resultMap type="SysDevOperLog" id="SysDevOperLogResult">
<result property="id" column="id" />
<result property="agriName" column="agri_name" />
<result property="imei" column="imei" />
<result property="funcCode" column="func_code" />
<result property="opType" column="op_type" />
<result property="opSource" column="op_source" />
<result property="payload" column="payload" />
<result property="lockAcquired" column="lock_acquired" />
<result property="lockHolder" column="lock_holder" />
<result property="taskStatus" column="task_status" />
<result property="ackReceived" column="ack_received" />
<result property="ackSuc" column="ack_suc" />
<result property="isLockSuc" column="is_lock_suc" />
<result property="isTask" column="is_task" />
<result property="noTaskReason" column="no_task_reason" />
<result property="ack" column="ack" />
<result property="execResult" column="exec_result" />
<result property="skipReason" column="skip_reason" />
<result property="latestState" column="latest_state" />
<result property="remark" column="remark" />
<result property="version" column="version" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectSysDevOperLogVo">
select id, agri_name, imei, func_code, op_type, op_source, payload, lock_acquired, lock_holder, task_status, ack_received, ack_suc, is_lock_suc, is_task, no_task_reason, ack, exec_result, skip_reason, latest_state, remark, version, create_by, create_time, update_by, update_time from sys_dev_oper_log
</sql>
<select id="selectSysDevOperLogList" parameterType="SysDevOperLog" resultMap="SysDevOperLogResult">
<include refid="selectSysDevOperLogVo"/>
<where>
</where>
</select>
<select id="selectSysDevOperLogById" parameterType="Long" resultMap="SysDevOperLogResult">
<include refid="selectSysDevOperLogVo"/>
where id = #{id}
</select>
<insert id="insertSysDevOperLog" parameterType="SysDevOperLog" useGeneratedKeys="true" keyProperty="id">
insert into sys_dev_oper_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="agriName != null">agri_name,</if>
<if test="imei != null">imei,</if>
<if test="funcCode != null">func_code,</if>
<if test="opType != null">op_type,</if>
<if test="opSource != null">op_source,</if>
<if test="payload != null">payload,</if>
<if test="lockAcquired != null">lock_acquired,</if>
<if test="lockHolder != null">lock_holder,</if>
<if test="taskStatus != null">task_status,</if>
<if test="ackReceived != null">ack_received,</if>
<if test="ackSuc != null">ack_suc,</if>
<if test="isLockSuc != null">is_lock_suc,</if>
<if test="isTask != null">is_task,</if>
<if test="noTaskReason != null">no_task_reason,</if>
<if test="ack != null">ack,</if>
<if test="execResult != null">exec_result,</if>
<if test="skipReason != null">skip_reason,</if>
<if test="latestState != null">latest_state,</if>
<if test="remark != null">remark,</if>
<if test="version != null">version,</if>
create_by,
create_time,
update_by,
update_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="agriName != null">#{agriName},</if>
<if test="imei != null">#{imei},</if>
<if test="funcCode != null">#{funcCode},</if>
<if test="opType != null">#{opType},</if>
<if test="opSource != null">#{opSource},</if>
<if test="payload != null">#{payload},</if>
<if test="lockAcquired != null">#{lockAcquired},</if>
<if test="lockHolder != null">#{lockHolder},</if>
<if test="taskStatus != null">#{taskStatus},</if>
<if test="ackReceived != null">#{ackReceived},</if>
<if test="ackSuc != null">#{ackSuc},</if>
<if test="isLockSuc != null">#{isLockSuc},</if>
<if test="isTask != null">#{isTask},</if>
<if test="noTaskReason != null">#{noTaskReason},</if>
<if test="ack != null">#{ack},</if>
<if test="execResult != null">#{execResult},</if>
<if test="skipReason != null">#{skipReason},</if>
<if test="latestState != null">#{latestState},</if>
<if test="remark != null">#{remark},</if>
<if test="version != null">#{version},</if>
#{createBy},
#{createTime},
#{updateBy},
#{updateTime},
</trim>
</insert>
<update id="updateSysDevOperLog" parameterType="SysDevOperLog">
update sys_dev_oper_log
<trim prefix="SET" suffixOverrides=",">
<if test="agriName != null">agri_name = #{agriName},</if>
<if test="imei != null">imei = #{imei},</if>
<if test="funcCode != null">func_code = #{funcCode},</if>
<if test="opType != null">op_type = #{opType},</if>
<if test="opSource != null">op_source = #{opSource},</if>
<if test="payload != null">payload = #{payload},</if>
<if test="lockAcquired != null">lock_acquired = #{lockAcquired},</if>
<if test="lockHolder != null">lock_holder = #{lockHolder},</if>
<if test="taskStatus != null">task_status = #{taskStatus},</if>
<if test="ackReceived != null">ack_received = #{ackReceived},</if>
<if test="ackSuc != null">ack_suc = #{ackSuc},</if>
<if test="isLockSuc != null">is_lock_suc = #{isLockSuc},</if>
<if test="isTask != null">is_task = #{isTask},</if>
<if test="noTaskReason != null">no_task_reason = #{noTaskReason},</if>
<if test="ack != null">ack = #{ack},</if>
<if test="execResult != null">exec_result = #{execResult},</if>
<if test="skipReason != null">skip_reason = #{skipReason},</if>
<if test="latestState != null">latest_state = #{latestState},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="version != null">version = #{version},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSysDevOperLogById" parameterType="Long">
delete from sys_dev_oper_log where id = #{id}
</delete>
<delete id="deleteSysDevOperLogByIds" parameterType="String">
delete from sys_dev_oper_log where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>