This commit is contained in:
2026-07-14 12:43:23 +08:00
parent 8f7a35e3c7
commit 29ecbf321f
52 changed files with 1197 additions and 324 deletions

View File

@@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 区域/场站
*
@@ -23,7 +22,6 @@ public class SysSiteController extends BaseController {
@Autowired
private SysSiteService sysSiteService;
/**
* 查询组织列表
*/
@@ -46,7 +44,7 @@ public class SysSiteController extends BaseController {
try {
return AjaxResult.success(sysSiteService.save(org));
} catch (Exception e) {
return AjaxResult.error("保存组织出错", e.getMessage());
return AjaxResult.error("新增修改场站出错", e.getMessage());
}
}
@@ -58,12 +56,14 @@ public class SysSiteController extends BaseController {
public AjaxResult delete(@RequestBody List<Long> ids) {
try {
if (CollectionUtils.isEmpty(ids)) {
// return error(StringUtils.format(MessageUtils.message("menu.add.failed.name.exists"), menu.getMenuName()));
// return
// error(StringUtils.format(MessageUtils.message("menu.add.failed.name.exists"),
// menu.getMenuName()));
return error("删除id为空");
}
return AjaxResult.success(sysSiteService.delete(ids));
} catch (Exception e) {
return AjaxResult.error("保存组织出错", e.getMessage());
return AjaxResult.error("删除场站出错", e.getMessage());
}
}
@@ -76,7 +76,7 @@ public class SysSiteController extends BaseController {
try {
return AjaxResult.success(sysSiteService.selectById(id));
} catch (Exception e) {
return AjaxResult.error("保存组织出错", e.getMessage());
return AjaxResult.error("查询场站详情出错", e.getMessage());
}
}
@@ -89,7 +89,20 @@ public class SysSiteController extends BaseController {
try {
return AjaxResult.success(sysSiteService.selectByOrgId(id));
} catch (Exception e) {
return AjaxResult.error("保存组织出错", e.getMessage());
return AjaxResult.error("查询组织下所有场站出错", e.getMessage());
}
}
/**
* 查询用户的场站
*/
@GetMapping("/selectByUserId")
public AjaxResult selectByUserId() {
try {
return AjaxResult.success(sysSiteService.selectByUserId(getLoginUser()));
} catch (Exception e) {
return AjaxResult.error("查询用户场站出错", e.getMessage());
}
}
}

View File

@@ -0,0 +1,29 @@
package com.maibu.core.business;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.maibu.core.domain.OrgNoUserDO;
import com.maibu.core.enums.ErrorSource;
import lombok.Data;
import lombok.EqualsAndHashCode;
//记录配置告警是否需要自动生成工单
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "iot_alarm_order_config", autoResultMap = true)
public class AlarmOrderConfig extends OrgNoUserDO {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Long id;
private String ErrorCode;
private ErrorSource sourceType;
private boolean autoGenerateOrder = false;
private Long modelId; // 工单模型
}

View File

@@ -3,6 +3,7 @@ package com.maibu.core.business;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.maibu.core.domain.OrgBaseDO;
import com.maibu.core.enums.CompareEnum;
import com.maibu.core.enums.ErrorLevel;
import com.maibu.core.enums.ErrorSource;
@@ -10,8 +11,8 @@ import lombok.Data;
@Data
@TableName("error_identification")
public class ErrorIdentificationStandard {
@TableName("iot_error_identification")
public class ErrorIdentificationStandard extends OrgBaseDO {
@TableId(type = IdType.AUTO)
private Long id;
private String field;

View File

@@ -1,23 +1,26 @@
package com.maibu.core.business;
import com.baomidou.mybatisplus.annotation.*;
import com.maibu.core.domain.TenantBaseDO;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.maibu.core.domain.OrgNoUserDO;
import com.maibu.core.enums.ErrorLevel;
import com.maibu.core.enums.ErrorSource;
import com.maibu.core.enums.OrderType;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("iot_work_order")
@ApiModel("工单记录")
public class IOTWorkOrder extends TenantBaseDO {
public class IOTWorkOrder extends OrgNoUserDO {
@ApiModelProperty("主键 ID")
@TableId(type = IdType.AUTO)
@@ -32,10 +35,8 @@ public class IOTWorkOrder extends TenantBaseDO {
@ApiModelProperty("工单来源:1-AI 诊断 2-无人机巡检 3-清洗优化 4-视频监控 5-装备控制 6-人工创建 7-告警关联")
private Integer sourceType;
@ApiModelProperty("工单类型:1-巡检 2-检修 3-清洗 4-维修 5-运维")
private Integer orderType;
private OrderType orderType;
@ApiModelProperty("优先级:1-高 2-中 3-低")
private ErrorLevel priorityLevel;
@ApiModelProperty("关联设备 ID")
@@ -45,17 +46,11 @@ public class IOTWorkOrder extends TenantBaseDO {
private String deviceName;
@ApiModelProperty("设备类型")
private ErrorSource deviceType;
@ApiModelProperty("关联场站 ID")
private Long siteId;
private ErrorSource deviceType;
@ApiModelProperty("关联场站名称")
private String siteName;
@ApiModelProperty("关联组织 ID")
private Long orgId;
@ApiModelProperty("负责人 ID")
private Long assigneeId;
@@ -109,4 +104,8 @@ public class IOTWorkOrder extends TenantBaseDO {
@ApiModelProperty("处理备注")
private String handleRemark;
private Long modelId;
private Long taskId;
}

View File

@@ -0,0 +1,40 @@
package com.maibu.core.business;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.maibu.core.domain.OrgNoUserDO;
import com.maibu.core.enums.ErrorLevel;
import com.maibu.core.enums.OrderType;
import lombok.Data;
import lombok.EqualsAndHashCode;
//自动生成工单配置的模型
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "iot_order_model", autoResultMap = true)
public class OrderModel extends OrgNoUserDO {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Long id;
private String orderName; // 工单名称 这个需要拼上时间
private OrderType orderType;
private ErrorLevel errorLevel;
private boolean autoGenerateTask = false; // 是否自动生成任务
private String deviceId; // 设备Id
private Long routeId; // 路径规划Id
private String waylineId; // 航线ID
private Integer rthAltitude; // 返航高度
private String rthMode; // 返航模式 optimal 智能高度 preset 设定高度
}

View File

@@ -107,4 +107,8 @@ public class Alarm extends TenantBaseDO {
@ApiModelProperty("是否邮件通知:0-否 1-是")
@Excel(name = "邮件通知", readConverterExp = "0=否,1=是")
private Integer notifyEmail;
private Long siteId;
private Long orgId;
}

View File

@@ -40,4 +40,9 @@ public class AlarmMessage {
/** 状态 */
private String status;
private Long siteId;
private Long orgId;
}

View File

@@ -55,6 +55,9 @@ public class NettyDevice extends Connector {
// todo 注册的时候更新 siteId
private Device device;
//todo 假如设置一个当前控制的token
private String currentControlToken;
@JsonIgnore
private DevicePlanTaskMapper devicePlanTaskMapper = SpringUtils.getBean(DevicePlanTaskMapper.class);

View File

@@ -5,6 +5,9 @@ import java.time.LocalDateTime;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.maibu.core.domain.BaseEntity;
import com.maibu.core.enums.ErrorLevel;
import com.maibu.core.enums.ErrorSource;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -12,25 +15,14 @@ import lombok.Data;
@Data
@ApiModel("告警查询参数")
public class AlarmQueryDTO {
public class AlarmQueryDTO extends BaseEntity {
@ApiModelProperty("页码")
private Integer pageNum = 1;
@ApiModelProperty("告警编号")
private String alarmNo;
@ApiModelProperty("每页条数")
private Integer pageSize = 10;
private ErrorSource deviceType;
@ApiModelProperty("告警级别:1-严重 2-重要 3-一般 4-提示")
private Integer alarmLevel;
@ApiModelProperty("告警类型")
private Integer alarmType;
@ApiModelProperty("设备类型")
private Integer deviceType;
@ApiModelProperty("处理状态:1-待处理 2-处理中 3-已关闭 4-已忽略")
private Integer handleStatus;
private ErrorLevel alarmLevel;
@ApiModelProperty("开始时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@@ -42,9 +34,6 @@ public class AlarmQueryDTO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime endTime;
@ApiModelProperty("搜索关键词(告警编号/内容)")
private String keyword;
@ApiModelProperty("设备ID")
private String deviceId;

View File

@@ -1,4 +1,4 @@
package com.maibu.dto;
package com.maibu.core.business.dto;
import lombok.Data;

View File

@@ -6,6 +6,10 @@ import lombok.Data;
import java.time.LocalDateTime;
import javax.lang.model.type.ErrorType;
import com.maibu.core.enums.OrderType;
@Data
@ApiModel("工单查询参数")
public class WorkOrderQueryDTO {
@@ -20,10 +24,10 @@ public class WorkOrderQueryDTO {
private Integer sourceType;
@ApiModelProperty("工单类型")
private Integer orderType;
private OrderType orderType;
@ApiModelProperty("优先级")
private Integer priorityLevel;
private ErrorType priorityLevel;
@ApiModelProperty("负责人 ID")
private Long assigneeId;

View File

@@ -0,0 +1,20 @@
package com.maibu.core.business.dto;
import java.time.LocalDateTime;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@Data
public class WorkOrderStartDTO {
private List<Long> ids;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
private String deviceId;
}

View File

@@ -1,4 +1,4 @@
package com.maibu.uav.dto;
package com.maibu.core.business.dto.uav;
import lombok.Data;

View File

@@ -0,0 +1,26 @@
package com.maibu.core.business.inter.mower;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import com.maibu.core.business.dto.DeviceTaskCommandDTO;
@Component
public class MowerCommandDispather {
@Resource
private ApplicationContext applicationContext;
public void dispathDeviceTask(DeviceTaskCommandDTO dto) {
Map<String, MowerCommandInter> beanMap = applicationContext.getBeansOfType(MowerCommandInter.class);
// 遍历
beanMap.values().forEach(x -> {
x.createDeviceTask(dto);
});
}
}

View File

@@ -0,0 +1,9 @@
package com.maibu.core.business.inter.mower;
import com.maibu.core.business.dto.DeviceTaskCommandDTO;
public interface MowerCommandInter {
void createDeviceTask(DeviceTaskCommandDTO dto);
}

View File

@@ -0,0 +1,26 @@
package com.maibu.core.business.inter.uav;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
@Component
public class UAVCommandDispather {
@Resource
private ApplicationContext applicationContext;
public void dispathFightTask(FlightTaskCreateDTO dto) {
Map<String, UAVCommandInter> beanMap = applicationContext.getBeansOfType(UAVCommandInter.class);
// 遍历
beanMap.values().forEach(x -> {
x.createFlightTask(dto);
});
}
}

View File

@@ -0,0 +1,9 @@
package com.maibu.core.business.inter.uav;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
public interface UAVCommandInter {
void createFlightTask(FlightTaskCreateDTO dto);
}

View File

@@ -0,0 +1,22 @@
package com.maibu.core.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 拓展多租户的 BaseDO 基类
*
* @author fastbee
*/
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class OrgNoUserDO extends BaseDO {
/**
* 多租户编号
*/
private Long orgId;
private Long siteId;
}

View File

@@ -0,0 +1,33 @@
package com.maibu.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum OrderType {
MOWER_ERROR("MOWER_ERROR", "割草机故障", 1),
UAV_ERROR("UAV_ERROR", "无人机故障", 2),
INSPECTION_TASK("INSPECTION_TASK", "巡检", 2),
COMPONENT_DEFECT("COMPONENT_DEFECT", "光伏组件故障", 3),
CLEAN_TASK("CLEAN_TASK", "清洗任务", 2),
MAINTAIN_TASK("MAINTAIN_TASK", "维护任务", 3),
REPAIR_TASK("REPAIR_TASK", "维修任务", 3),
OTHER("OTHER", "其他", 3);
/** 订单类型值(存储在数据库中) */
private final String value;
/** 订单类型名称(用于前端显示) */
private final String name;
// 主体 1-割草机 2 -无人机 3 -其他
private final Integer type;
}

View File

@@ -0,0 +1,14 @@
package com.maibu.mapper;
import org.springframework.stereotype.Repository;
import com.maibu.core.business.AlarmOrderConfig;
import com.maibu.mybatis.mapper.BaseMapperX;
/**
* 设备历史状态
*/
@Repository
public interface AlarmOrderConfigMapper extends BaseMapperX<AlarmOrderConfig> {
}

View File

@@ -0,0 +1,14 @@
package com.maibu.mapper;
import org.springframework.stereotype.Repository;
import com.maibu.core.business.OrderModel;
import com.maibu.mybatis.mapper.BaseMapperX;
/**
* 设备历史状态
*/
@Repository
public interface OrderModelMapper extends BaseMapperX<OrderModel> {
}

View File

@@ -10,12 +10,14 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.maibu.core.business.AlarmOrderConfig;
import com.maibu.core.business.Device;
import com.maibu.core.business.DevicePlan;
import com.maibu.core.business.DevicePlanTask;
import com.maibu.core.business.DeviceRunParam;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.core.business.IoTCommonDevice;
import com.maibu.core.business.OrderModel;
import com.maibu.core.domain.entity.SysSite;
import com.maibu.core.enums.ErrorSource;
@@ -27,12 +29,16 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SiteMemory {
public Map<ErrorSource, List<ErrorIdentificationStandard>> standards = null;
public ConcurrentHashMap<ErrorSource, List<ErrorIdentificationStandard>> standards = null;
public Long siteId;
public SysSite sysSite;
public static final ConcurrentHashMap<Long, OrderModel> ordrModelMap = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<String, AlarmOrderConfig> orderConfigMap = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<String, DeviceRunParam> deviceRunParamMap = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, Device> deviceMap = new ConcurrentHashMap<>();
@@ -73,6 +79,68 @@ public class SiteMemory {
}
}
public void saveErrorIdentificationStandard(ErrorIdentificationStandard errorIdentificationStandard) {
if (standards == null) {
standards = new ConcurrentHashMap<>();
}
List<ErrorIdentificationStandard> list = standards.get(errorIdentificationStandard.getErrorSource());
if (CollectionUtils.isEmpty(list)) {
list = new ArrayList<>();
}
list.add(errorIdentificationStandard);
standards.put(errorIdentificationStandard.getErrorSource(), list);
}
public List<ErrorIdentificationStandard> getErrorIdentificationStandard(ErrorSource errorSource) {
if (errorSource != null && standards != null) {
return standards.get(errorSource);
}
return null;
}
public void removeErrorIdentificationStandard(ErrorIdentificationStandard errorIdentificationStandard) {
if (errorIdentificationStandard != null && standards != null) {
List<ErrorIdentificationStandard> list = standards.get(errorIdentificationStandard.getErrorSource());
if (!CollectionUtils.isEmpty(list)) {
list.removeIf(x -> x.getId().equals(errorIdentificationStandard.getId()));
}
}
}
public void saveOrderModel(OrderModel orderModel) {
ordrModelMap.put(orderModel.getId(), orderModel);
}
public OrderModel getOrderModel(Long id) {
if (id != null) {
return ordrModelMap.get(id);
}
return null;
}
public void removeOrderModel(Long id) {
if (id != null) {
ordrModelMap.remove(id);
}
}
public void saveAlarmOrderConfig(AlarmOrderConfig alarmOrderConfig) {
orderConfigMap.put(alarmOrderConfig.getErrorCode(), alarmOrderConfig);
}
public AlarmOrderConfig getAlarmOrderConfig(String errorCode) {
if (!StringUtils.isEmpty(errorCode)) {
return orderConfigMap.get(errorCode);
}
return null;
}
public void removeAlarmOrderConfig(String errorCode) {
if (!StringUtils.isEmpty(errorCode)) {
orderConfigMap.remove(errorCode);
}
}
public void addDevicePlan(DevicePlan devicePlan) {
if (devicePlan != null && !StringUtils.isEmpty(devicePlan.getDeviceId())) {
String deviceId = devicePlan.getDeviceId();

View File

@@ -1,6 +1,5 @@
package com.maibu.mqtt;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
@@ -83,11 +82,14 @@ public class MqttClientUtil {
int qos)
throws MqttException {
MqttMessage message =
new MqttMessage(payload.getBytes());
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(qos);
if (!client.isConnected()) {
log.warn("MQTT未连接");
return;
}
client.publish(topic, message);
}

View File

@@ -1,5 +1,6 @@
package com.maibu.uav.controller;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
import com.maibu.core.controller.BaseController;
import com.maibu.core.domain.AjaxResult;
import com.maibu.core.page.TableDataInfo;

View File

@@ -0,0 +1,20 @@
package com.maibu.uav.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
import com.maibu.core.business.inter.uav.UAVCommandInter;
@Component
public class UAVCommamdHandler implements UAVCommandInter {
@Autowired
private UAVService uService;
@Override
public void createFlightTask(FlightTaskCreateDTO dto){
uService.createFlightTask(dto);
}
}

View File

@@ -3,6 +3,7 @@ package com.maibu.uav.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
import com.maibu.core.business.uav.IotUAVDevice;
import com.maibu.core.domain.entity.SysRole;
import com.maibu.core.redis.RedisCache;

View File

@@ -13,12 +13,12 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.maibu.core.business.DevicePlan;
import com.maibu.core.business.dto.DeviceTaskCommandDTO;
import com.maibu.core.controller.BaseController;
import com.maibu.core.domain.AjaxResult;
import com.maibu.core.domain.model.LoginUser;
import com.maibu.core.enums.DeviceTaskStaus;
import com.maibu.core.page.TableDataInfo;
import com.maibu.dto.DeviceTaskCommandDTO;
import com.maibu.dto.DeviceTaskQueryDTO;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;

View File

@@ -0,0 +1,23 @@
package com.maibu.handler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.maibu.core.business.dto.DeviceTaskCommandDTO;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
import com.maibu.core.business.inter.mower.MowerCommandInter;
import com.maibu.core.business.inter.uav.UAVCommandInter;
import com.maibu.service.DeviceTaskService;
@Component
public class MowerCommamdHandler implements MowerCommandInter {
@Autowired
private DeviceTaskService dService;
@Override
public void createDeviceTask(DeviceTaskCommandDTO dto) {
dService.createDeviceTask(dto, "system");
}
}

View File

@@ -16,15 +16,21 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.maibu.constant.FastBeeConstant;
import com.maibu.core.business.AlarmOrderConfig;
import com.maibu.core.business.DevicePlan;
import com.maibu.core.business.DevicePlanTask;
import com.maibu.core.business.DeviceRunParam;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.core.business.OrderModel;
import com.maibu.core.domain.entity.SysSite;
import com.maibu.core.enums.DeviceTaskStaus;
import com.maibu.influxdb.util.InfluxDBUtil;
import com.maibu.mapper.AlarmOrderConfigMapper;
import com.maibu.mapper.DevicePlanMapper;
import com.maibu.mapper.DevicePlanTaskMapper;
import com.maibu.mapper.DeviceRunParamMapper;
import com.maibu.mapper.ErrorIdentificationStandardMapper;
import com.maibu.mapper.OrderModelMapper;
import com.maibu.mapper.SysSiteMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
@@ -63,6 +69,12 @@ public class InitThread implements ApplicationRunner {
@Autowired
private DeviceRunParamMapper deviceRunParamMapper;
@Autowired
private ErrorIdentificationStandardMapper errorIdentificationStandardMapper;
@Autowired
private OrderModelMapper orderModelMapper;
@Autowired
private AlarmOrderConfigMapper alarmOrderConfigMapper;
@Value("${influxdb.url}")
private String influxDBUrl;
@@ -157,6 +169,43 @@ public class InitThread implements ApplicationRunner {
}
});
}
List<ErrorIdentificationStandard> standadList = errorIdentificationStandardMapper.selectList();
if (!CollectionUtils.isEmpty(standadList)) {
standadList.forEach(x -> {
Long orgId = x.getOrgId();
Long siteId = x.getId();
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
if (siteMemory != null) {
siteMemory.saveErrorIdentificationStandard(x);
}
});
}
List<OrderModel> orderModelList = orderModelMapper.selectList();
if (!CollectionUtils.isEmpty(orderModelList)) {
orderModelList.forEach(x -> {
Long orgId = x.getOrgId();
Long siteId = x.getId();
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
if (siteMemory != null) {
siteMemory.saveOrderModel(x);
}
});
}
List<AlarmOrderConfig> alarmOrderList = alarmOrderConfigMapper.selectList();
if (!CollectionUtils.isEmpty(alarmOrderList)) {
alarmOrderList.forEach(x -> {
Long orgId = x.getOrgId();
Long siteId = x.getId();
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
if (siteMemory != null) {
siteMemory.saveAlarmOrderConfig(x);
}
});
}
// 未执行完的重复计划
LambdaQueryWrapperX<DevicePlan> query = new LambdaQueryWrapperX<>();
List<String> list = Arrays.asList(DeviceTaskStaus.NEW.getCode(), DeviceTaskStaus.EXECUTING.getCode(),

View File

@@ -1,16 +1,8 @@
package com.maibu.netty.handler;
import com.maibu.common.CommandConstant;
import com.maibu.core.enums.ConnectorType;
import com.maibu.core.business.device.Connector;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.manager.DeviceSessionManager;
import com.maibu.memory.GlobalMemory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.List;
import java.util.Set;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -18,8 +10,17 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Set;
import com.maibu.common.CommandConstant;
import com.maibu.core.business.device.Connector;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.enums.ConnectorType;
import com.maibu.manager.DeviceSessionManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
@Component
@ChannelHandler.Sharable

View File

@@ -4,8 +4,9 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -19,17 +20,19 @@ import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.maibu.core.business.alarm_center.Alarm;
import com.maibu.core.business.AlarmOrderConfig;
import com.maibu.core.business.IOTWorkOrder;
import com.maibu.core.business.alarm_center.AlarmMessage;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.redis.RedisCache;
import com.maibu.dto.DeviceErrorPushDTO;
import com.maibu.dto.DeviceErrorPushDetail;
import com.maibu.manager.DeviceSessionManager;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
import com.maibu.service.impl.AlarmServiceImpl;
import com.maibu.service.impl.WorkOrderServiceImpl;
import com.maibu.utils.DingTalkTemplate;
import com.maibu.utils.SecurityUtils;
import com.maibu.utils.json.JsonUtils;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
@@ -44,6 +47,12 @@ public class AlertPushService {
@Autowired
private AlarmServiceImpl alarmService;
@Autowired
private RedisCache redisCache;
@Autowired
private WorkOrderServiceImpl wService;
public void messagePushHandler(String deviceId, List<DeviceErrorPushDTO> dtos) {
NettyDevice nettyDevice = sessionManager.getDevice(deviceId);
if (nettyDevice != null && nettyDevice.getDevice() != null) {
@@ -58,17 +67,48 @@ public class AlertPushService {
String token = siteMemory.getSysSite().getDingTalkToken();
dtos.forEach(dto -> {
if (!CollectionUtils.isEmpty(dto.getDetails())) {
List<AlarmMessage> newList = new ArrayList<>();
List<IOTWorkOrder> workOrders = new ArrayList<>();
dto.getDetails().forEach(detail -> {
if (dingTalkPush == 1) {
pushDingTalkMessage(secret, token, DingTalkTemplate.buildText(detail));
String pushKey = "alarm:" + "dingtalk:" + deviceId + ":" + detail.getNo();
Boolean exists = redisCache.hasKey(pushKey);
if (exists != null && !exists) {
pushDingTalkMessage(secret, token, DingTalkTemplate.buildText(detail));
redisCache.setCacheObject(pushKey, JsonUtils.toJsonString(detail), 10,
TimeUnit.MINUTES);
}
}
if (emailPush == 1) {
pushEmailMessage(null, null);
String pushKey = "alarm:" + "email:" + deviceId + ":" + detail.getNo();
Boolean exists = redisCache.hasKey(pushKey);
if (exists != null && !exists) {
pushEmailMessage(null, null);
redisCache.setCacheObject(pushKey, JsonUtils.toJsonString(detail), 10,
TimeUnit.MINUTES);
}
}
if (alertPush == 1) {
String pushKey = "alarm:" + "mqtt:" + deviceId + ":" + detail.getNo();
Boolean exists = redisCache.hasKey(pushKey);
if (exists != null && !exists) {
newList.add(detail);
redisCache.setCacheObject(pushKey, JsonUtils.toJsonString(detail), 10,
TimeUnit.MINUTES);
}
}
AlarmOrderConfig config = siteMemory.getAlarmOrderConfig(detail.getNo());
if (config != null && config.isAutoGenerateOrder()) {
IOTWorkOrder workOrder = wService.generateWorkOrders(siteId, deviceId, orgId, orgId);
workOrders.add(workOrder);
}
});
if (alertPush == 1) {
alarmService.pushAlertMes(dto.getDetails());
}
if (!CollectionUtils.isEmpty(workOrders)) {
wService.saveAll(workOrders);
}
}
});

View File

@@ -1,13 +0,0 @@
package com.maibu.service;
import org.springframework.stereotype.Service;
@Service
public class DevicePathService {
}

View File

@@ -21,12 +21,12 @@ import com.maibu.core.business.DevicePlanTask;
import com.maibu.core.business.DeviceTaskPlanRule;
import com.maibu.core.business.WorkRecord;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.business.dto.DeviceTaskCommandDTO;
import com.maibu.core.domain.entity.SysSite;
import com.maibu.core.domain.model.LoginUser;
import com.maibu.core.enums.DeviceTaskStaus;
import com.maibu.dto.DevicePlanStatisticsDTO;
import com.maibu.dto.DevicePlanTaskStatisticsDTO;
import com.maibu.dto.DeviceTaskCommandDTO;
import com.maibu.dto.DeviceTaskQueryDTO;
import com.maibu.dto.DeviceWorkStatisticsDTO;
import com.maibu.manager.DeviceSessionManager;

View File

@@ -1,41 +1,5 @@
package com.maibu.service;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson2.JSON;
import com.maibu.common.CommandConstant;
import com.maibu.common.NettyCacheKey;
import com.maibu.core.business.DeviceRunningStatusHistory;
import com.maibu.core.business.DeviceStatusRecordDTO;
import com.maibu.core.enums.CompareEnum;
import com.maibu.core.enums.ErrorSource;
import com.maibu.core.enums.RespondCode;
import com.maibu.core.redis.RedisCache;
import com.maibu.dto.DeviceErrorPushDTO;
import com.maibu.dto.DeviceErrorPushDetail;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.business.inter.WebsocketMesDispather;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.core.business.alarm_center.AlarmMessage;
import com.maibu.manager.DeviceSessionManager;
import com.maibu.mapper.ErrorIdentificationStandardMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
import com.maibu.mqtt.MqttTopic;
import com.maibu.utils.CommandUtils;
import com.maibu.utils.CompareUtils;
import com.maibu.utils.json.JsonUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
@@ -44,9 +8,44 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.common.NettyCacheKey;
import com.maibu.core.business.DeviceRunningStatusHistory;
import com.maibu.core.business.DeviceStatusRecordDTO;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.core.business.alarm_center.AlarmMessage;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.business.inter.WebsocketMesDispather;
import com.maibu.core.enums.CompareEnum;
import com.maibu.core.enums.ErrorSource;
import com.maibu.core.enums.RespondCode;
import com.maibu.core.redis.RedisCache;
import com.maibu.dto.DeviceErrorPushDTO;
import com.maibu.manager.DeviceSessionManager;
import com.maibu.mapper.ErrorIdentificationStandardMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
import com.maibu.mqtt.MqttTopic;
import com.maibu.utils.CompareUtils;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@@ -55,9 +54,6 @@ public class DeviceThreadService {
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private SiteMemory siteMemory;
@Autowired
private RedisCache redisCache;
@@ -76,6 +72,9 @@ public class DeviceThreadService {
public void deviceErrorMonitor() throws InterruptedException, IOException {
initStandard();
// TODO fix 后续是否分多个线程 一个site一个线程
// 有还需要更新接受故障方式。
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleWithFixedDelay(() -> {
try {
@@ -89,11 +88,16 @@ public class DeviceThreadService {
recordDTO.getHistories()
.sort(Comparator.comparing(DeviceRunningStatusHistory::getCreateTime).reversed());
DeviceRunningStatusHistory history = recordDTO.getHistories().get(0);
List<AlarmMessage> compared = compareErrorStandard(history,
siteMemory.standards.get(ErrorSource.MOWER));
String[] parts = k.split(":");
String deviceId = parts[1];
NettyDevice slaveDevice = sessionManager.getDevice(deviceId);
Long siteId = slaveDevice != null ? slaveDevice.getDevice().getSiteId() : null;
Long orgId = slaveDevice != null ? slaveDevice.getDevice().getOrgId() : null;
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
List<AlarmMessage> compared = compareErrorStandard(siteId, orgId, history,
siteMemory.standards.get(ErrorSource.MOWER));
DeviceErrorPushDTO pushDTO = new DeviceErrorPushDTO();
pushDTO.setDeviceId(deviceId);
@@ -116,30 +120,55 @@ public class DeviceThreadService {
} catch (Exception e) {
log.error("执行监测错误线程错误:{}", e.getMessage());
}
}, 0, 2, TimeUnit.MINUTES);
}, 0, 5, TimeUnit.SECONDS);
}
public void initStandard() throws IOException {
if (siteMemory.standards == null) {
List<ErrorIdentificationStandard> list = standardMapper.selectList();
if (CollectionUtils.isEmpty(list)) {
// 读取resource目录下的device-config.json文件
Resource resource = resourceLoader.getResource("classpath:errorStandard.json");
// 使用fastjson2转换为DeviceConfig对象
String jsonContent = IoUtil.readUtf8(resource.getInputStream());
List<ErrorIdentificationStandard> newStandards = JSON.parseArray(jsonContent,
ErrorIdentificationStandard.class);
if (!CollectionUtils.isEmpty(newStandards)) {
standardMapper.insertBatch(newStandards);
siteMemory.standards = newStandards.stream()
.collect(java.util.stream.Collectors
.groupingBy(ErrorIdentificationStandard::getErrorSource));
GlobalMemory.getAllSiteMemory().forEach(siteMemory -> {
if (siteMemory != null && siteMemory.standards == null) {
LambdaQueryWrapper<ErrorIdentificationStandard> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrorIdentificationStandard::getSiteId, siteMemory.sysSite.getId());
List<ErrorIdentificationStandard> list = standardMapper.selectList(queryWrapper);
if (CollectionUtils.isEmpty(list)) {
try {
// 读取resource目录下的device-config.json文件
Resource resource = resourceLoader.getResource("classpath:errorStandard.json");
// 使用fastjson2转换为DeviceConfig对象
String jsonContent;
jsonContent = IoUtil.readUtf8(resource.getInputStream());
List<ErrorIdentificationStandard> newStandards = JSON.parseArray(jsonContent,
ErrorIdentificationStandard.class);
if (!CollectionUtils.isEmpty(newStandards)) {
newStandards.forEach(x -> {
x.setOrgId(siteMemory.sysSite.getOrgId());
x.setSiteId(siteMemory.sysSite.getId());
});
standardMapper.insertBatch(newStandards);
siteMemory.standards = newStandards.stream()
.filter(e -> e.getErrorSource() != null)
.collect(Collectors.groupingBy(
ErrorIdentificationStandard::getErrorSource,
ConcurrentHashMap::new,
Collectors.toList()));
}
} catch (IORuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
siteMemory.standards = list.stream()
.filter(e -> e.getErrorSource() != null)
.collect(Collectors.groupingBy(
ErrorIdentificationStandard::getErrorSource,
ConcurrentHashMap::new,
Collectors.toList()));
}
} else {
siteMemory.standards = list.stream()
.collect(java.util.stream.Collectors.groupingBy(ErrorIdentificationStandard::getErrorSource));
}
}
});
}
public void pushErrorMessage(String deviceId, String dto) {
@@ -165,7 +194,7 @@ public class DeviceThreadService {
}
}
public List<AlarmMessage> compareErrorStandard(DeviceRunningStatusHistory history,
public List<AlarmMessage> compareErrorStandard(Long siteId, Long orgId, DeviceRunningStatusHistory history,
List<ErrorIdentificationStandard> standards) {
if (history == null || CollectionUtils.isEmpty(standards))
return null;
@@ -189,6 +218,8 @@ public class DeviceThreadService {
alarm.setSuggestion(standard.getSuggestion());
alarm.setStatus("未处理");
alarm.setTime(LocalDateTime.now());
alarm.setOrgId(orgId);
alarm.setSiteId(siteId);
list.add(alarm);
}
}

View File

@@ -35,7 +35,7 @@ import lombok.extern.slf4j.Slf4j;
@RestController
@Slf4j
@RequestMapping("/iot/alarm")
public class AlarmController extends BaseController{
public class AlarmController extends BaseController {
@Autowired
@@ -45,9 +45,9 @@ public class AlarmController extends BaseController{
@GetMapping("/list")
@ApiOperation("告警分页列表")
public TableDataInfo list(AlarmQueryDTO queryDTO) {
// startPage();
// return alarmService.selectAlarmPage(queryDTO);
return alarmService.selectAlarmPage(queryDTO);
startPage();
return getDataTable(alarmService.selectAlarmPage(queryDTO));
}
// @PreAuthorize("@ss.hasPermi('iot:alarm:query')")

View File

@@ -0,0 +1,42 @@
package com.maibu.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.maibu.core.business.AlarmOrderConfig;
import com.maibu.core.controller.BaseController;
import com.maibu.core.domain.AjaxResult;
import com.maibu.core.page.TableDataInfo;
import com.maibu.dto.BaseQueryDTO;
import com.maibu.service.impl.AlarmOrderConfigService;
@RestController
@RequestMapping("/iot/alarmOrderConfig")
public class AlarmOrderConfigController extends BaseController {
@Autowired
private AlarmOrderConfigService service;
@PostMapping("/save")
public AjaxResult save(@RequestBody AlarmOrderConfig config) {
return AjaxResult.success(service.save(config));
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody BaseQueryDTO dto) {
startPage();
return getDataTable(service.list(dto));
}
@PostMapping("/delete")
public AjaxResult delete(@RequestBody List<Long> ids) {
return AjaxResult.success(service.delete(ids));
}
}

View File

@@ -14,7 +14,7 @@ import com.maibu.core.business.DeviceRunParam;
import com.maibu.core.controller.BaseController;
import com.maibu.core.domain.AjaxResult;
import com.maibu.core.page.TableDataInfo;
import com.maibu.dto.DeviceRunParamQueryDTO;
import com.maibu.dto.BaseQueryDTO;
import com.maibu.service.impl.DeviceRunParamService;
@RestController
@@ -31,7 +31,7 @@ public class DeviceRunParamController extends BaseController {
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody DeviceRunParamQueryDTO dto) {
public TableDataInfo list(@RequestBody BaseQueryDTO dto) {
startPage();
return getDataTable(service.list(dto));
}

View File

@@ -3,7 +3,6 @@ package com.maibu.controller;
import java.util.List;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@@ -19,6 +19,7 @@ import com.maibu.annotation.Log;
import com.maibu.core.business.IOTWorkOrder;
import com.maibu.core.business.dto.WorkOrderDispatchDTO;
import com.maibu.core.business.dto.WorkOrderQueryDTO;
import com.maibu.core.business.dto.WorkOrderStartDTO;
import com.maibu.core.controller.BaseController;
import com.maibu.core.domain.AjaxResult;
import com.maibu.core.page.TableDataInfo;
@@ -77,12 +78,11 @@ public class IOTWorkOrderController extends BaseController {
return toAjax(workOrderService.dispatchWorkOrder(dispatchDTO));
}
//@PreAuthorize("@ss.hasPermi('iot:workOrder:start')")
@Log(title = "工单开始", businessType = BusinessType.UPDATE)
@PutMapping("/start/{id}")
@PostMapping("/start")
@ApiOperation("开始执行工单")
public AjaxResult start(@PathVariable Long id) {
return toAjax(workOrderService.startWorkOrder(id));
public AjaxResult start(@RequestBody WorkOrderStartDTO dto) {
return toAjax(workOrderService.startWorkOrder(dto));
}
// @PreAuthorize("@ss.hasPermi('iot:workOrder:complete')")

View File

@@ -0,0 +1,45 @@
package com.maibu.controller;
import java.util.List;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.maibu.core.business.DeviceRunParam;
import com.maibu.core.business.OrderModel;
import com.maibu.core.controller.BaseController;
import com.maibu.core.domain.AjaxResult;
import com.maibu.core.page.TableDataInfo;
import com.maibu.dto.BaseQueryDTO;
import com.maibu.service.impl.OrderModelService;
@RestController
@RequestMapping("/iot/orderModel")
public class OrderModelController extends BaseController {
@Autowired
private OrderModelService service;
@PostMapping("/save")
public AjaxResult save(@RequestBody OrderModel orderModel) {
return AjaxResult.success(service.save(orderModel));
}
@PostMapping("/list")
public TableDataInfo list(@RequestBody BaseQueryDTO dto) {
startPage();
return getDataTable(service.list(dto));
}
@PostMapping("/delete")
public AjaxResult delete(@RequestBody List<Long> ids) {
return AjaxResult.success(service.delete(ids));
}
}

View File

@@ -5,7 +5,8 @@ import com.maibu.core.domain.BaseEntity;
import lombok.Data;
@Data
public class DeviceRunParamQueryDTO extends BaseEntity {
public class BaseQueryDTO extends BaseEntity {
private Long siteId;
private String deviceId;
private Long orgId;
}

View File

@@ -12,4 +12,6 @@ public class ErrorQueryDTO extends BaseEntity {
private ErrorSource errorSource;
private String errorCode;
private ErrorLevel errorLevel;
private Long orgId;
private Long siteId;
}

View File

@@ -1 +1,36 @@
package com.maibu.service;
package com.maibu.service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.IService;
import com.maibu.core.business.alarm_center.Alarm;
import com.maibu.core.business.dto.AlarmHandleDTO;
import com.maibu.core.business.dto.AlarmQueryDTO;
public interface IAlarmService extends IService<Alarm> {
List<Alarm> selectAlarmPage(AlarmQueryDTO queryDTO);
List<Alarm> selectAlarmList(AlarmQueryDTO queryDTO);
Alarm selectAlarmById(Long id);
int insertAlarm(Alarm alarm);
int updateAlarm(Alarm alarm);
int handleAlarm(AlarmHandleDTO handleDTO);
int deleteAlarmById(Long id);
int deleteAlarmByIds(Long[] ids);
Map<String, Object> getAlarmStatistics();
Map<String, Object> getAlarmStatistics(AlarmQueryDTO queryDTO);
}

View File

@@ -1,5 +0,0 @@
package com.maibu.service;
public interface IWebRtcService {
}

View File

@@ -1,14 +1,15 @@
package com.maibu.service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.IService;
import com.maibu.core.business.IOTWorkOrder;
import com.maibu.core.business.dto.WorkOrderDispatchDTO;
import com.maibu.core.business.dto.WorkOrderQueryDTO;
import com.maibu.core.business.dto.WorkOrderStartDTO;
import com.maibu.core.page.TableDataInfo;
import java.util.List;
import java.util.Map;
public interface IWorkOrderService extends IService<IOTWorkOrder> {
TableDataInfo selectWorkOrderPage(WorkOrderQueryDTO queryDTO);
@@ -23,7 +24,7 @@ public interface IWorkOrderService extends IService<IOTWorkOrder> {
int dispatchWorkOrder(WorkOrderDispatchDTO dispatchDTO);
int startWorkOrder(Long id);
boolean startWorkOrder(WorkOrderStartDTO dto);
int completeWorkOrder(IOTWorkOrder workOrder);

View File

@@ -0,0 +1,56 @@
package com.maibu.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.core.business.AlarmOrderConfig;
import com.maibu.dto.BaseQueryDTO;
import com.maibu.mapper.AlarmOrderConfigMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
@Service
public class AlarmOrderConfigService {
@Autowired
private AlarmOrderConfigMapper alarmOrderConfigMapper;
public boolean save(AlarmOrderConfig alarmOrderConfig) {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(alarmOrderConfig.getOrgId(),
alarmOrderConfig.getSiteId());
if (siteMemory != null) {
siteMemory.saveAlarmOrderConfig(alarmOrderConfig);
}
return alarmOrderConfigMapper.saveOrUpdate(alarmOrderConfig);
}
public List<AlarmOrderConfig> list(BaseQueryDTO dto) {
LambdaQueryWrapper<AlarmOrderConfig> queryWrapper = new LambdaQueryWrapper<>();
if (dto != null) {
if (dto.getSiteId() != null) {
queryWrapper.eq(AlarmOrderConfig::getSiteId, dto.getSiteId());
}
}
return alarmOrderConfigMapper.selectList(queryWrapper);
}
public int delete(List<Long> ids) {
List<AlarmOrderConfig> alarmOrderConfigs = alarmOrderConfigMapper
.selectBatchIds(ids);
if (!CollectionUtils.isEmpty(alarmOrderConfigs)) {
alarmOrderConfigs.forEach(x -> {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(x.getOrgId(), x.getSiteId());
if (siteMemory != null) {
siteMemory.removeAlarmOrderConfig(x.getErrorCode());
}
});
}
int i = alarmOrderConfigMapper.deleteBatchIds(ids);
return i;
}
}

View File

@@ -1,12 +1,23 @@
package com.maibu.service.impl;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maibu.core.business.Device;
import com.maibu.core.business.alarm_center.Alarm;
import com.maibu.core.business.alarm_center.AlarmMessage;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.business.dto.AlarmHandleDTO;
import com.maibu.core.business.dto.AlarmQueryDTO;
import com.maibu.core.domain.model.LoginUser;
@@ -24,18 +35,6 @@ import com.maibu.utils.json.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements IAlarmService {
@@ -43,27 +42,23 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private AlarmMapper alarmMapper;
@Override
public TableDataInfo selectAlarmPage(AlarmQueryDTO queryDTO) {
validateQueryParams(queryDTO);
public List<Alarm> selectAlarmPage(AlarmQueryDTO queryDTO) {
// validateQueryParams(queryDTO);
LambdaQueryWrapper<Alarm> wrapper = buildQueryWrapper(queryDTO);
Page<Alarm> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
Page<Alarm> result = baseMapper.selectPage(page, wrapper);
TableDataInfo tableDataInfo = new TableDataInfo();
tableDataInfo.setRows(result.getRecords());
tableDataInfo.setTotal(result.getTotal());
return tableDataInfo;
List<Alarm> list = alarmMapper.selectList(wrapper);
return list;
}
@Override
public List<Alarm> selectAlarmList(AlarmQueryDTO queryDTO) {
validateQueryParams(queryDTO);
LambdaQueryWrapper<Alarm> wrapper = buildQueryWrapper(queryDTO);
return baseMapper.selectList(wrapper);
return alarmMapper.selectList(wrapper);
}
@Override
@@ -72,7 +67,7 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
LambdaQueryWrapper<Alarm> wrapper = buildQueryWrapper(queryDTO);
List<Alarm> alarms = baseMapper.selectList(wrapper);
List<Alarm> alarms = alarmMapper.selectList(wrapper);
Map<String, Object> statistics = new HashMap<>();
statistics.put("total", alarms.size());
statistics.put("pending", alarms.stream().filter(a -> a.getHandleStatus() == 1).count());
@@ -172,70 +167,63 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
private LambdaQueryWrapper<Alarm> buildQueryWrapper(AlarmQueryDTO queryDTO) {
LambdaQueryWrapper<Alarm> wrapper = new LambdaQueryWrapper<>();
Long userId = SecurityUtils.getUserId();
LoginUser loginUser = SecurityUtils.getLoginUser();
Long userOrgId = loginUser.getOrgId();
Long userSiteId = loginUser.getSiteId();
// Long userId = SecurityUtils.getUserId();
// LoginUser loginUser = SecurityUtils.getLoginUser();
// Long userOrgId = loginUser.getOrgId();
// Long userSiteId = loginUser.getSiteId();
// 数据权限过滤(核心修复:防止组织管理员越权)
if (!SecurityUtils.isAdmin(userId)) {
if (queryDTO.getSiteId() != null) {
// 修复:组织管理员指定场站查询时,必须同时满足 orgId 匹配
String sql = "SELECT 1 FROM iot_device d WHERE d.device_id = iot_alarm.device_id AND d.site_id = {0}";
if (userOrgId != null) {
sql += " AND d.org_id = " + userOrgId;
}
wrapper.exists(sql, queryDTO.getSiteId());
} else if (userSiteId != null) {
wrapper.exists("SELECT 1 FROM iot_device d WHERE d.device_id = iot_alarm.device_id AND d.site_id = {0}",
userSiteId);
} else if (userOrgId != null) {
wrapper.exists("SELECT 1 FROM iot_device d WHERE d.device_id = iot_alarm.device_id AND d.org_id = {0}",
userOrgId);
}
}
// if (!SecurityUtils.isAdmin(userId)) {
// if (queryDTO.getSiteId() != null) {
// // 修复:组织管理员指定场站查询时,必须同时满足 orgId 匹配
// String sql = "SELECT 1 FROM iot_device d WHERE d.device_id =
// iot_alarm.device_id AND d.site_id = {0}";
// if (userOrgId != null) {
// sql += " AND d.org_id = " + userOrgId;
// }
// wrapper.exists(sql, queryDTO.getSiteId());
// } else if (userSiteId != null) {
// wrapper.exists("SELECT 1 FROM iot_device d WHERE d.device_id =
// iot_alarm.device_id AND d.site_id = {0}",
// userSiteId);
// } else if (userOrgId != null) {
// wrapper.exists("SELECT 1 FROM iot_device d WHERE d.device_id =
// iot_alarm.device_id AND d.org_id = {0}",
// userOrgId);
// }
// }
if (queryDTO.getDeviceId() != null) {
if (!StringUtils.isEmpty(queryDTO.getAlarmNo())) {
wrapper.like(Alarm::getAlarmNo, queryDTO.getAlarmNo());
}
if (!StringUtils.isEmpty(queryDTO.getDeviceId())) {
wrapper.eq(Alarm::getDeviceId, queryDTO.getDeviceId());
}
if (queryDTO.getSiteId() != null) {
wrapper.eq(Alarm::getSiteId, queryDTO.getSiteId());
}
if (!StringUtils.isEmpty(queryDTO.getDeviceId())) {
wrapper.eq(Alarm::getDeviceId, queryDTO.getDeviceId());
}
if (queryDTO.getAlarmLevel() != null) {
wrapper.eq(Alarm::getAlarmLevel, queryDTO.getAlarmLevel());
}
if (queryDTO.getAlarmType() != null) {
wrapper.eq(Alarm::getAlarmType, queryDTO.getAlarmType());
}
if (queryDTO.getDeviceType() != null) {
wrapper.eq(Alarm::getDeviceType, queryDTO.getDeviceType());
}
if (queryDTO.getHandleStatus() != null) {
wrapper.eq(Alarm::getHandleStatus, queryDTO.getHandleStatus());
}
// if (queryDTO.getStartTime() != null) {
// wrapper.ge(Alarm::getAlarmTime, queryDTO.getStartTime());
// }
// if (queryDTO.getEndTime() != null) {
// wrapper.le(Alarm::getAlarmTime, queryDTO.getEndTime());
// }
if (queryDTO.getStartTime() != null) {
wrapper.ge(Alarm::getAlarmTime, queryDTO.getStartTime());
}
if (queryDTO.getEndTime() != null) {
wrapper.le(Alarm::getAlarmTime, queryDTO.getEndTime());
}
if (StringUtils.isNotEmpty(queryDTO.getKeyword())) {
wrapper.and(w -> w.like(Alarm::getAlarmNo, queryDTO.getKeyword())
.or()
.like(Alarm::getAlarmContent, queryDTO.getKeyword()));
}
wrapper.orderByDesc(Alarm::getAlarmTime);
return wrapper;
}
@Override
public Alarm selectAlarmById(Long id) {
Alarm alarm = baseMapper.selectById(id);
Alarm alarm = alarmMapper.selectById(id);
if (alarm == null)
throw new ServiceException("告警不存在");
@@ -255,24 +243,24 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
alarm.setTenantId(SecurityUtils.getLoginUser().getOrgId());
alarm.setAlarmTime(LocalDateTime.now());
alarm.setHandleStatus(1);
return baseMapper.insert(alarm);
return alarmMapper.insert(alarm);
}
@Override
public int updateAlarm(Alarm alarm) {
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId) && alarm.getId() != null) {
Alarm existAlarm = baseMapper.selectById(alarm.getId());
Alarm existAlarm = alarmMapper.selectById(alarm.getId());
if (existAlarm != null && existAlarm.getDeviceId() != null) {
validateDeviceAccess(existAlarm.getDeviceId());
}
}
return baseMapper.updateById(alarm);
return alarmMapper.updateById(alarm);
}
@Override
public int handleAlarm(AlarmHandleDTO handleDTO) {
Alarm alarm = baseMapper.selectById(handleDTO.getAlarmId());
Alarm alarm = alarmMapper.selectById(handleDTO.getAlarmId());
if (alarm == null)
throw new ServiceException("告警不存在");
@@ -292,19 +280,19 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
if (handleDTO.getHandleStatus() == 3) {
updateAlarm.setRecoverTime(LocalDateTime.now());
}
return baseMapper.updateById(updateAlarm);
return alarmMapper.updateById(updateAlarm);
}
@Override
public int deleteAlarmById(Long id) {
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
Alarm alarm = baseMapper.selectById(id);
Alarm alarm = alarmMapper.selectById(id);
if (alarm != null && alarm.getDeviceId() != null) {
validateDeviceAccess(alarm.getDeviceId());
}
}
return baseMapper.deleteById(id);
return alarmMapper.deleteById(id);
}
@Override
@@ -312,13 +300,13 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
for (Long id : ids) {
Alarm alarm = baseMapper.selectById(id);
Alarm alarm = alarmMapper.selectById(id);
if (alarm != null && alarm.getDeviceId() != null) {
validateDeviceAccess(alarm.getDeviceId());
}
}
}
return baseMapper.deleteBatchIds(Arrays.asList(ids));
return alarmMapper.deleteBatchIds(Arrays.asList(ids));
}
@Override
@@ -341,7 +329,7 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
}
wrapper.ge(Alarm::getAlarmTime, LocalDateTime.now().minusDays(7));
List<Alarm> alarms = baseMapper.selectList(wrapper);
List<Alarm> alarms = alarmMapper.selectList(wrapper);
Map<String, Object> statistics = new HashMap<>();
statistics.put("total", alarms.size());
statistics.put("pending", alarms.stream().filter(a -> a.getHandleStatus() == 1).count());
@@ -372,22 +360,26 @@ public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements
alarm.setDeviceName(alarmMessage.getDeviceName());
alarm.setDeviceType(ErrorSource.MOWER);
alarm.setAlarmTime(LocalDateTime.now());
alarm.setOrgId(alarmMessage.getOrgId());
alarm.setSiteId(alarmMessage.getSiteId());
alarm.setAlarmTime(LocalDateTime.now());
pushErrorMessage(alarmMessage.getDeviceName(), JsonUtils.toJsonString(alarm));
list.add(alarm);
}
baseMapper.insertBatch(list);
alarmMapper.saveOrUpdateBatch(list);
// todo 推送websocket?
}
public void pushErrorMessage(String deviceId, String dto) {
try {
GlobalMemory.mqttClientUtil.publish(String.format(MqttTopic.DEVICE_ERROR_PUSH_TOPIC, deviceId), dto);
// List<NettyDevice> controlMasters = sessionManager.getAllSlaveControl(deviceId);
// List<NettyDevice> controlMasters =
// sessionManager.getAllSlaveControl(deviceId);
// if (!CollectionUtils.isEmpty(controlMasters)) {
// controlMasters.forEach(x -> {
// websocketMesDispather.dispather(x.getConnectorId(), dto);
// log.info("推送错误信息 device:{},content:{}", deviceId, dto);
// });
// controlMasters.forEach(x -> {
// websocketMesDispather.dispather(x.getConnectorId(), dto);
// log.info("推送错误信息 device:{},content:{}", deviceId, dto);
// });
// }
} catch (MqttException e) {
log.error("推送错误信息失败 device:{}error:{}", deviceId, e.getMessage());

View File

@@ -1,6 +1,5 @@
package com.maibu.service.impl;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@@ -10,7 +9,7 @@ import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.core.business.DeviceRunParam;
import com.maibu.dto.DeviceRunParamQueryDTO;
import com.maibu.dto.BaseQueryDTO;
import com.maibu.mapper.DeviceRunParamMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
@@ -29,7 +28,7 @@ public class DeviceRunParamService {
return deviceRunParamMapper.saveOrUpdate(deviceRunParam);
}
public List<DeviceRunParam> list(DeviceRunParamQueryDTO dto) {
public List<DeviceRunParam> list(BaseQueryDTO dto) {
LambdaQueryWrapper<DeviceRunParam> queryWrapper = new LambdaQueryWrapper<>();
if (dto != null) {
if (dto.getSiteId() != null) {
@@ -65,3 +64,4 @@ public class DeviceRunParamService {
}
}

View File

@@ -5,11 +5,14 @@ import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.dto.ErrorQueryDTO;
import com.maibu.mapper.ErrorIdentificationStandardMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
@Service
public class ErrorIdentificationService {
@@ -18,6 +21,12 @@ public class ErrorIdentificationService {
private ErrorIdentificationStandardMapper errorIdentificationStandardMapper;
public boolean save(ErrorIdentificationStandard errorIdentificationStandard) {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(errorIdentificationStandard.getOrgId(),
errorIdentificationStandard.getSiteId());
if (siteMemory != null) {
siteMemory.saveErrorIdentificationStandard(errorIdentificationStandard);
}
return errorIdentificationStandardMapper.saveOrUpdate(errorIdentificationStandard);
}
@@ -36,11 +45,27 @@ public class ErrorIdentificationService {
if (dto.getErrorSource() != null) {
queryWrapper.eq(ErrorIdentificationStandard::getErrorSource, dto.getErrorSource());
}
if (dto.getOrgId() != null) {
queryWrapper.eq(ErrorIdentificationStandard::getOrgId, dto.getOrgId());
}
if (dto.getSiteId() != null) {
queryWrapper.eq(ErrorIdentificationStandard::getSiteId, dto.getSiteId());
}
}
return errorIdentificationStandardMapper.selectList(queryWrapper);
}
public int delete(List<Long> ids) {
List<ErrorIdentificationStandard> errorIdentificationStandards = errorIdentificationStandardMapper
.selectBatchIds(ids);
if (!CollectionUtils.isEmpty(errorIdentificationStandards)) {
errorIdentificationStandards.forEach(x -> {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(x.getOrgId(), x.getSiteId());
if (siteMemory != null) {
siteMemory.removeErrorIdentificationStandard(x);
}
});
}
int i = errorIdentificationStandardMapper.deleteBatchIds(ids);
return i;
}

View File

@@ -0,0 +1,111 @@
package com.maibu.service.impl;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.core.business.OrderModel;
import com.maibu.core.business.dto.DeviceTaskCommandDTO;
import com.maibu.core.business.dto.uav.FlightTaskCreateDTO;
import com.maibu.core.business.inter.mower.MowerCommandDispather;
import com.maibu.core.business.inter.uav.UAVCommandDispather;
import com.maibu.core.enums.OrderType;
import com.maibu.dto.BaseQueryDTO;
import com.maibu.mapper.OrderModelMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
@Service
public class OrderModelService {
@Autowired
private OrderModelMapper orderModelMapper;
@Autowired
private UAVCommandDispather dispather;
@Autowired
private MowerCommandDispather mowerDispather;
public boolean save(OrderModel orderModel) {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orderModel.getOrgId(),
orderModel.getSiteId());
if (siteMemory != null) {
siteMemory.saveOrderModel(orderModel);
}
return orderModelMapper.saveOrUpdate(orderModel);
}
public List<OrderModel> list(BaseQueryDTO dto) {
LambdaQueryWrapper<OrderModel> queryWrapper = new LambdaQueryWrapper<>();
if (dto != null && dto.getSiteId() != null) {
queryWrapper.eq(OrderModel::getSiteId, dto.getSiteId());
}
return orderModelMapper.selectList(queryWrapper);
}
public OrderModel selectByDeviceId(String deviceId) {
LambdaQueryWrapper<OrderModel> queryWrapper = new LambdaQueryWrapper<>();
if (!StringUtils.isEmpty(deviceId)) {
queryWrapper.eq(OrderModel::getDeviceId, deviceId);
}
return orderModelMapper.selectOne(queryWrapper);
}
public int delete(List<Long> ids) {
List<OrderModel> orderModels = orderModelMapper
.selectBatchIds(ids);
if (!CollectionUtils.isEmpty(orderModels)) {
orderModels.forEach(x -> {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(x.getOrgId(), x.getSiteId());
if (siteMemory != null) {
siteMemory.removeOrderModel(x.getId());
}
});
}
int i = orderModelMapper.deleteBatchIds(ids);
return i;
}
public void createTask(String deviceId, Long siteId, Long orgId, Long modelId) {
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
OrderModel orderModel = siteMemory.getOrderModel(modelId);
OrderType orderType = orderModel.getOrderType();
// 割草机
if (orderType != null && orderType.getType() == 1) {
Long routeId = orderModel.getRouteId();
DeviceTaskCommandDTO dto = new DeviceTaskCommandDTO();
dto.setDeviceId(deviceId);
dto.setRouteId(routeId);
dto.setOrgId(orgId);
dto.setSiteId(siteId);
dto.setStartTime(LocalDateTime.now());
mowerDispather.dispathDeviceTask(dto);
}
// 无人机
if (orderType != null && orderType.getType() == 2) {
String waylineId = orderModel.getWaylineId();
FlightTaskCreateDTO dto = new FlightTaskCreateDTO();
dto.setWayline_uuid(waylineId);
dto.setSn(deviceId);
String name = orderType.getValue() + "-"
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
dto.setName(name);
dto.setRth_altitude(orderModel.getRthAltitude());
dto.setRth_mode(orderModel.getRthMode());
dispather.dispathFightTask(dto);
}
// 其他
if (orderType != null && orderType.getType() == 3) {
}
}
}

View File

@@ -1,25 +1,5 @@
package com.maibu.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maibu.core.business.Device;
import com.maibu.core.business.IOTWorkOrder;
import com.maibu.core.business.dto.WorkOrderDispatchDTO;
import com.maibu.core.business.dto.WorkOrderQueryDTO;
import com.maibu.core.domain.model.LoginUser;
import com.maibu.core.enums.ErrorLevel;
import com.maibu.core.page.TableDataInfo;
import com.maibu.exception.ServiceException;
import com.maibu.mapper.DeviceMapper;
import com.maibu.mapper.IotWorkOrderMapper;
import com.maibu.service.IAlarmService;
import com.maibu.service.IWorkOrderService;
import com.maibu.utils.SecurityUtils;
import com.maibu.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
@@ -27,6 +7,32 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maibu.core.business.Device;
import com.maibu.core.business.IOTWorkOrder;
import com.maibu.core.business.OrderModel;
import com.maibu.core.business.dto.WorkOrderDispatchDTO;
import com.maibu.core.business.dto.WorkOrderQueryDTO;
import com.maibu.core.business.dto.WorkOrderStartDTO;
import com.maibu.core.domain.model.LoginUser;
import com.maibu.core.enums.ErrorLevel;
import com.maibu.core.enums.OrderType;
import com.maibu.core.page.TableDataInfo;
import com.maibu.exception.ServiceException;
import com.maibu.mapper.DeviceMapper;
import com.maibu.mapper.IotWorkOrderMapper;
import com.maibu.mapper.OrderModelMapper;
import com.maibu.service.IAlarmService;
import com.maibu.service.IWorkOrderService;
import com.maibu.utils.SecurityUtils;
import com.maibu.utils.StringUtils;
@Service
public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWorkOrder> implements IWorkOrderService {
@@ -36,6 +42,15 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
@Autowired
private IAlarmService alarmService;
@Autowired
private IotWorkOrderMapper iotWorkOrderMapper;
@Autowired
private OrderModelMapper orderModelMapper;
@Autowired
private OrderModelService orderModelService;
@Override
public TableDataInfo selectWorkOrderPage(WorkOrderQueryDTO queryDTO) {
validateQueryParams(queryDTO);
@@ -75,10 +90,12 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
}
private void validateSiteAccess(Long siteId) {
if (siteId == null) return;
if (siteId == null)
return;
Long userId = SecurityUtils.getUserId();
if (SecurityUtils.isAdmin(userId)) return;
if (SecurityUtils.isAdmin(userId))
return;
LoginUser loginUser = SecurityUtils.getLoginUser();
Long userSiteId = loginUser.getSiteId();
@@ -92,8 +109,7 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
Long count = deviceMapper.selectCount(
new LambdaQueryWrapper<Device>()
.eq(Device::getSiteId, siteId)
.eq(Device::getOrgId, userOrgId)
);
.eq(Device::getOrgId, userOrgId));
if (count == 0) {
throw new ServiceException("无权访问该场站");
}
@@ -103,16 +119,17 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
}
private void validateDeviceAccess(Long deviceId) {
if (deviceId == null) return;
if (deviceId == null)
return;
Long userId = SecurityUtils.getUserId();
if (SecurityUtils.isAdmin(userId)) return;
if (SecurityUtils.isAdmin(userId))
return;
Device device = deviceMapper.selectOne(
new LambdaQueryWrapper<Device>()
.eq(Device::getDeviceId, deviceId)
.select(Device::getOrgId, Device::getSiteId)
);
.select(Device::getOrgId, Device::getSiteId));
if (device == null) {
throw new ServiceException("设备不存在");
@@ -210,7 +227,8 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
@Override
public IOTWorkOrder selectWorkOrderById(Long id) {
IOTWorkOrder workOrder = baseMapper.selectById(id);
if (workOrder == null) throw new ServiceException("工单不存在");
if (workOrder == null)
throw new ServiceException("工单不存在");
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
@@ -245,7 +263,7 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
@Override
public int insertWorkOrder(IOTWorkOrder workOrder) {
workOrder.setOrderNo(generateUniqueOrderNo());
workOrder.setTenantId(SecurityUtils.getLoginUser().getOrgId());
// workOrder.setTenantId(SecurityUtils.getLoginUser().getOrgId());
workOrder.setOrgId(SecurityUtils.getLoginUser().getOrgId());
workOrder.setCreateTime(LocalDateTime.now());
if (workOrder.getOrderStatus() == null) {
@@ -254,18 +272,20 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
return baseMapper.insert(workOrder);
}
/* @Override
public int updateWorkOrder(IOTWorkOrder workOrder) {
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
IOTWorkOrder existWorkOrder = baseMapper.selectById(workOrder.getId());
if (existWorkOrder != null) {
validateWorkOrderAccess(existWorkOrder);
}
}
workOrder.setUpdateTime(LocalDateTime.now());
return baseMapper.updateById(workOrder);
}*/
/*
* @Override
* public int updateWorkOrder(IOTWorkOrder workOrder) {
* Long userId = SecurityUtils.getUserId();
* if (!SecurityUtils.isAdmin(userId)) {
* IOTWorkOrder existWorkOrder = baseMapper.selectById(workOrder.getId());
* if (existWorkOrder != null) {
* validateWorkOrderAccess(existWorkOrder);
* }
* }
* workOrder.setUpdateTime(LocalDateTime.now());
* return baseMapper.updateById(workOrder);
* }
*/
@Override
public int updateWorkOrder(IOTWorkOrder workOrder) {
@@ -310,11 +330,11 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
return baseMapper.updateById(updateEntity);
}
@Override
public int dispatchWorkOrder(WorkOrderDispatchDTO dispatchDTO) {
IOTWorkOrder workOrder = baseMapper.selectById(dispatchDTO.getOrderId());
if (workOrder == null) throw new ServiceException("工单不存在");
if (workOrder == null)
throw new ServiceException("工单不存在");
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
@@ -337,28 +357,36 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
}
@Override
public int startWorkOrder(Long id) {
IOTWorkOrder workOrder = baseMapper.selectById(id);
if (workOrder == null) throw new ServiceException("工单不存在");
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
validateWorkOrderAccess(workOrder);
public boolean startWorkOrder(WorkOrderStartDTO dto) {
List<Long> ids = dto.getIds();
List<IOTWorkOrder> workOrders = baseMapper.selectBatchIds(ids);
if (CollectionUtils.isEmpty(workOrders)) {
throw new ServiceException("工单不存在");
}
IOTWorkOrder updateWorkOrder = new IOTWorkOrder();
updateWorkOrder.setId(id);
updateWorkOrder.setOrderStatus(3);
updateWorkOrder.setActualStartTime(LocalDateTime.now());
updateWorkOrder.setUpdateTime(LocalDateTime.now());
updateWorkOrder.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
return baseMapper.updateById(updateWorkOrder);
Long userId = SecurityUtils.getUserId();
String userName = SecurityUtils.getUsername();
workOrders.forEach(workOrder -> {
workOrder.setOrderStatus(3);
workOrder.setActualStartTime(LocalDateTime.now());
workOrder.setUpdateTime(LocalDateTime.now());
workOrder.setUpdateBy(userName);
workOrder.setAssigneeId(userId);
workOrder.setAssigneeName(userName);
// todo 派发自定义的路径规划任务
Long modelId = workOrder.getModelId();
if (modelId == null) return;
Long siteId = workOrder.getSiteId();
Long orgId = workOrder.getOrgId();
orderModelService.createTask(dto.getDeviceId(), siteId, orgId, modelId);
});
return baseMapper.saveOrUpdateBatch(workOrders);
}
@Override
public int completeWorkOrder(IOTWorkOrder workOrder) {
IOTWorkOrder existWorkOrder = baseMapper.selectById(workOrder.getId());
if (existWorkOrder == null) throw new ServiceException("工单不存在");
if (existWorkOrder == null)
throw new ServiceException("工单不存在");
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
@@ -379,7 +407,8 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
@Override
public int suspendWorkOrder(Long id) {
IOTWorkOrder workOrder = baseMapper.selectById(id);
if (workOrder == null) throw new ServiceException("工单不存在");
if (workOrder == null)
throw new ServiceException("工单不存在");
Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) {
@@ -452,7 +481,8 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
.filter(w -> w.getCreateTime().toLocalDate().equals(LocalDateTime.now().toLocalDate()))
.count());
statistics.put("highPriority", workOrders.stream().filter(w -> w.getPriorityLevel().equals(ErrorLevel.ERROR)).count());
statistics.put("highPriority",
workOrders.stream().filter(w -> w.getPriorityLevel().equals(ErrorLevel.ERROR)).count());
return statistics;
}
@@ -469,8 +499,7 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
Device device = deviceMapper.selectOne(
new LambdaQueryWrapper<Device>()
.eq(Device::getDeviceId, alarm.getDeviceId())
.select(Device::getOrgId, Device::getSiteId)
);
.select(Device::getOrgId, Device::getSiteId));
if (device != null) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (!loginUser.getOrgId().equals(device.getOrgId())) {
@@ -483,7 +512,7 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
workOrder.setOrderNo(generateUniqueOrderNo());
workOrder.setOrderTitle(alarm.getAlarmTitle());
workOrder.setSourceType(7);
workOrder.setOrderType(2);
workOrder.setOrderType(OrderType.MOWER_ERROR);
workOrder.setPriorityLevel(alarm.getAlarmLevel());
workOrder.setDeviceId(alarm.getDeviceId());
workOrder.setDeviceName(alarm.getDeviceName());
@@ -512,10 +541,9 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
}
}
private String generateOrderNo() {
String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
return "WO" + dateStr + String.format("%04d", (int)(Math.random() * 10000));
return "WO" + dateStr + String.format("%04d", (int) (Math.random() * 10000));
}
private synchronized String generateUniqueOrderNo() {
@@ -537,5 +565,35 @@ public class WorkOrderServiceImpl extends ServiceImpl<IotWorkOrderMapper, IOTWor
throw new ServiceException("生成工单号失败,请稍后重试");
}
}
// 生成工单的方法
public IOTWorkOrder generateWorkOrders(Long siteId, String deviceId, Long orgId, Long modelId) {
OrderModel orderModel = orderModelMapper.selectById(modelId);
if (orderModel == null) {
throw new ServiceException("工单模板不存在");
}
IOTWorkOrder workOrder = new IOTWorkOrder();
workOrder.setOrderNo(generateOrderNo(orderModel.getOrderType().getValue()));
workOrder.setOrderTitle(workOrder.getOrderNo());
// workOrder.setSourceType(orderModel.ge());
workOrder.setOrderType(orderModel.getOrderType());
workOrder.setPriorityLevel(orderModel.getErrorLevel());
workOrder.setDeviceId(deviceId);
workOrder.setSiteId(siteId);
workOrder.setOrgId(orgId);
workOrder.setOrderStatus(1);
workOrder.setCreateTime(LocalDateTime.now());
workOrder.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
return workOrder;
}
private String generateOrderNo(String prefix) {
String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
return prefix + "-" + dateStr;
}
public boolean saveAll(List<IOTWorkOrder> list) {
return iotWorkOrderMapper.saveOrUpdateBatch(list);
}
}

View File

@@ -1,7 +1,10 @@
package com.maibu.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.core.business.Device;
import com.maibu.core.domain.entity.SysRole;
import com.maibu.core.domain.entity.SysSite;
import com.maibu.core.domain.model.LoginUser;
import com.maibu.exception.ServiceException;
import com.maibu.mapper.SysRegionMapper;
import com.maibu.mapper.SysSiteMapper;
@@ -14,6 +17,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
@Service
@@ -25,6 +29,9 @@ public class SysSiteService {
@Autowired
private SysRegionService sysRegionService;
@Autowired
private ISysRoleService roleService;
public List<SysSite> list(SysSite site) {
LambdaQueryWrapper<SysSite> queryWrapper = new LambdaQueryWrapper<>();
if (site != null && !StringUtils.isEmpty(site.getSiteName())) {
@@ -72,4 +79,25 @@ public class SysSiteService {
return sysSiteMapper.selectList(queryWrapper);
}
public List<SysSite> selectByUserId(LoginUser loginUser) {
SysRole sysRole = roleService.selectRoleById(loginUser.getRoleId());
if (sysRole != null) {
String roleKey = sysRole.getRoleKey();
LambdaQueryWrapper<SysSite> queryWrapper = new LambdaQueryWrapper<>();
if (!StringUtils.isEmpty(roleKey)) {
if ("manager".equals(roleKey)) {
queryWrapper.eq(SysSite::getOrgId, loginUser.getOrgId());
} else if ("siteManager".equals(roleKey)) {
queryWrapper.eq(SysSite::getId, loginUser.getSiteId());
} else if ("admin".equals(roleKey)) {
} else {
queryWrapper.eq(SysSite::getId, loginUser.getSiteId());
}
return sysSiteMapper.selectList(queryWrapper);
}
}
return null;
}
}