diff --git a/maibu-common/src/main/java/com/maibu/core/business/IOTWorkOrder.java b/maibu-common/src/main/java/com/maibu/core/business/IOTWorkOrder.java new file mode 100644 index 0000000..dbc36f2 --- /dev/null +++ b/maibu-common/src/main/java/com/maibu/core/business/IOTWorkOrder.java @@ -0,0 +1 @@ +package com.maibu.core.business; import com.baomidou.mybatisplus.annotation.*; import com.maibu.core.domain.TenantBaseDO; 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 { @ApiModelProperty("主键 ID") @TableId(type = IdType.AUTO) private Long id; @ApiModelProperty("工单编号") private String orderNo; @ApiModelProperty("工单标题") private String orderTitle; @ApiModelProperty("工单来源:1-AI 诊断 2-无人机巡检 3-清洗优化 4-视频监控 5-装备控制 6-人工创建 7-告警关联") private Integer sourceType; @ApiModelProperty("工单类型:1-巡检 2-检修 3-清洗 4-维修 5-运维") private Integer orderType; @ApiModelProperty("优先级:1-高 2-中 3-低") private Integer priorityLevel; @ApiModelProperty("关联设备 ID") private Long deviceId; @ApiModelProperty("关联设备名称") private String deviceName; @ApiModelProperty("设备类型") private Integer deviceType; @ApiModelProperty("关联场站 ID") private Long siteId; @ApiModelProperty("关联场站名称") private String siteName; @ApiModelProperty("关联组织 ID") private Long orgId; @ApiModelProperty("负责人 ID") private Long assigneeId; @ApiModelProperty("负责人姓名") private String assigneeName; @ApiModelProperty("协同人员 ID 列表 (逗号分隔)") private String collaboratorIds; @ApiModelProperty("协同人员姓名列表 (逗号分隔)") private String collaboratorNames; @ApiModelProperty("计划开始时间") private LocalDateTime planStartTime; @ApiModelProperty("计划结束时间") private LocalDateTime planEndTime; @ApiModelProperty("截止时间") private LocalDateTime deadlineTime; @ApiModelProperty("实际开始时间") private LocalDateTime actualStartTime; @ApiModelProperty("实际完成时间") private LocalDateTime actualEndTime; @ApiModelProperty("工单状态:1-待处理 2-已派发 3-执行中 4-已完成 5-已挂起") private Integer orderStatus; @ApiModelProperty("关联告警 ID") private Long alarmId; @ApiModelProperty("关联告警编号") private String alarmNo; @ApiModelProperty("任务描述") private String taskDescription; @ApiModelProperty("AI 建议") private String aiSuggestion; @ApiModelProperty("建议携带设备") private String requiredEquipment; @ApiModelProperty("预计影响发电量 (%)") private BigDecimal estimatedImpact; @ApiModelProperty("处理结果") private String handleResult; @ApiModelProperty("处理备注") private String handleRemark; } \ No newline at end of file diff --git a/maibu-common/src/main/java/com/maibu/core/business/dto/WorkOrderDispatchDTO.java b/maibu-common/src/main/java/com/maibu/core/business/dto/WorkOrderDispatchDTO.java new file mode 100644 index 0000000..e1cd81e --- /dev/null +++ b/maibu-common/src/main/java/com/maibu/core/business/dto/WorkOrderDispatchDTO.java @@ -0,0 +1,36 @@ +package com.maibu.core.business.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@ApiModel("工单派发参数") +public class WorkOrderDispatchDTO { + + @ApiModelProperty("工单 ID") + private Long orderId; + + @ApiModelProperty("负责人 ID") + private Long assigneeId; + + @ApiModelProperty("负责人姓名") + private String assigneeName; + + @ApiModelProperty("协同人员 ID 列表") + private String collaboratorIds; + + @ApiModelProperty("协同人员姓名列表") + private String collaboratorNames; + + @ApiModelProperty("计划开始时间") + private LocalDateTime planStartTime; + + @ApiModelProperty("计划结束时间") + private LocalDateTime planEndTime; + + @ApiModelProperty("截止时间") + private LocalDateTime deadlineTime; +} diff --git a/maibu-common/src/main/java/com/maibu/core/business/dto/WorkOrderQueryDTO.java b/maibu-common/src/main/java/com/maibu/core/business/dto/WorkOrderQueryDTO.java new file mode 100644 index 0000000..2bb4b5e --- /dev/null +++ b/maibu-common/src/main/java/com/maibu/core/business/dto/WorkOrderQueryDTO.java @@ -0,0 +1,57 @@ +package com.maibu.core.business.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@ApiModel("工单查询参数") +public class WorkOrderQueryDTO { + + @ApiModelProperty("工单编号") + private String orderNo; + + @ApiModelProperty("工单标题") + private String orderTitle; + + @ApiModelProperty("工单来源") + private Integer sourceType; + + @ApiModelProperty("工单类型") + private Integer orderType; + + @ApiModelProperty("优先级") + private Integer priorityLevel; + + @ApiModelProperty("负责人 ID") + private Long assigneeId; + + @ApiModelProperty("设备 ID") + private Long deviceId; + + @ApiModelProperty("场站 ID") + private Long siteId; + + @ApiModelProperty("组织 ID") + private Long orgId; + + @ApiModelProperty("工单状态") + private Integer orderStatus; + + @ApiModelProperty("开始时间") + private LocalDateTime startTime; + + @ApiModelProperty("结束时间") + private LocalDateTime endTime; + + @ApiModelProperty("搜索关键词") + private String keyword; + + @ApiModelProperty("页码") + private Integer pageNum = 1; + + @ApiModelProperty("每页大小") + private Integer pageSize = 10; +} diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/mapper/AlarmMapper.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/mapper/AlarmMapper.java new file mode 100644 index 0000000..6c7da6a --- /dev/null +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/mapper/AlarmMapper.java @@ -0,0 +1 @@ +package com.maibu.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.maibu.core.business.alarm_center.Alarm; import org.apache.ibatis.annotations.Mapper; @Mapper public interface AlarmMapper extends BaseMapper { } \ No newline at end of file diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/mapper/IotWorkOrderMapper.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/mapper/IotWorkOrderMapper.java new file mode 100644 index 0000000..1332293 --- /dev/null +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/mapper/IotWorkOrderMapper.java @@ -0,0 +1,9 @@ +package com.maibu.mapper; + +import com.maibu.core.business.IOTWorkOrder; +import com.maibu.mybatis.mapper.BaseMapperX; +import org.springframework.stereotype.Repository; + +@Repository +public interface IotWorkOrderMapper extends BaseMapperX { +} diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IWorkOrderService.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IWorkOrderService.java new file mode 100644 index 0000000..ced5ea0 --- /dev/null +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IWorkOrderService.java @@ -0,0 +1,39 @@ +package com.maibu.service; + +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.page.TableDataInfo; + +import java.util.List; +import java.util.Map; + +public interface IWorkOrderService extends IService { + + TableDataInfo selectWorkOrderPage(WorkOrderQueryDTO queryDTO); + + List selectWorkOrderList(WorkOrderQueryDTO queryDTO); + + IOTWorkOrder selectWorkOrderById(Long id); + + int insertWorkOrder(IOTWorkOrder workOrder); + + int updateWorkOrder(IOTWorkOrder workOrder); + + int dispatchWorkOrder(WorkOrderDispatchDTO dispatchDTO); + + int startWorkOrder(Long id); + + int completeWorkOrder(IOTWorkOrder workOrder); + + int suspendWorkOrder(Long id); + + int deleteWorkOrderById(Long id); + + int deleteWorkOrderByIds(Long[] ids); + + Map getWorkOrderStatistics(); + + IOTWorkOrder generateWorkOrderFromAlarm(Long alarmId); +} diff --git a/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/WorkOrderServiceImpl.java b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/WorkOrderServiceImpl.java new file mode 100644 index 0000000..425890f --- /dev/null +++ b/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/WorkOrderServiceImpl.java @@ -0,0 +1,476 @@ +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.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; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class WorkOrderServiceImpl extends ServiceImpl implements IWorkOrderService { + + @Autowired + private DeviceMapper deviceMapper; + + @Autowired + private IAlarmService alarmService; + + @Override + public TableDataInfo selectWorkOrderPage(WorkOrderQueryDTO queryDTO) { + validateQueryParams(queryDTO); + + LambdaQueryWrapper wrapper = buildQueryWrapper(queryDTO); + + Page page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); + Page result = baseMapper.selectPage(page, wrapper); + + TableDataInfo tableDataInfo = new TableDataInfo(); + tableDataInfo.setRows(result.getRecords()); + tableDataInfo.setTotal(result.getTotal()); + + return tableDataInfo; + } + + @Override + public List selectWorkOrderList(WorkOrderQueryDTO queryDTO) { + validateQueryParams(queryDTO); + LambdaQueryWrapper wrapper = buildQueryWrapper(queryDTO); + return baseMapper.selectList(wrapper); + } + + private void validateQueryParams(WorkOrderQueryDTO queryDTO) { + Long userId = SecurityUtils.getUserId(); + if (SecurityUtils.isAdmin(userId)) { + return; + } + + if (queryDTO.getSiteId() != null) { + validateSiteAccess(queryDTO.getSiteId()); + } + + if (queryDTO.getDeviceId() != null) { + validateDeviceAccess(queryDTO.getDeviceId()); + } + } + + private void validateSiteAccess(Long siteId) { + if (siteId == null) return; + + Long userId = SecurityUtils.getUserId(); + if (SecurityUtils.isAdmin(userId)) return; + + LoginUser loginUser = SecurityUtils.getLoginUser(); + Long userSiteId = loginUser.getSiteId(); + Long userOrgId = loginUser.getOrgId(); + + if (userSiteId != null) { + if (!userSiteId.equals(siteId)) { + throw new ServiceException("无权访问该场站"); + } + } else if (userOrgId != null) { + Long count = deviceMapper.selectCount( + new LambdaQueryWrapper() + .eq(Device::getSiteId, siteId) + .eq(Device::getOrgId, userOrgId) + ); + if (count == 0) { + throw new ServiceException("无权访问该场站"); + } + } else { + throw new ServiceException("无权访问该场站"); + } + } + + private void validateDeviceAccess(Long deviceId) { + if (deviceId == null) return; + + Long userId = SecurityUtils.getUserId(); + if (SecurityUtils.isAdmin(userId)) return; + + Device device = deviceMapper.selectOne( + new LambdaQueryWrapper() + .eq(Device::getDeviceId, deviceId) + .select(Device::getOrgId, Device::getSiteId) + ); + + if (device == null) { + throw new ServiceException("设备不存在"); + } + + LoginUser loginUser = SecurityUtils.getLoginUser(); + Long userSiteId = loginUser.getSiteId(); + Long userOrgId = loginUser.getOrgId(); + + if (userSiteId != null && !userSiteId.equals(device.getSiteId())) { + throw new ServiceException("无权访问该设备"); + } + + if (userOrgId != null && !userOrgId.equals(device.getOrgId())) { + throw new ServiceException("无权访问该设备"); + } + } + + private LambdaQueryWrapper buildQueryWrapper(WorkOrderQueryDTO queryDTO) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + Long userId = SecurityUtils.getUserId(); + LoginUser loginUser = SecurityUtils.getLoginUser(); + Long userOrgId = loginUser.getOrgId(); + Long userSiteId = loginUser.getSiteId(); + + if (!SecurityUtils.isAdmin(userId)) { + if (queryDTO.getSiteId() != null) { + wrapper.eq(IOTWorkOrder::getSiteId, queryDTO.getSiteId()); + if (userOrgId != null) { + wrapper.eq(IOTWorkOrder::getOrgId, userOrgId); + } + } else if (userSiteId != null) { + wrapper.eq(IOTWorkOrder::getSiteId, userSiteId); + } else if (userOrgId != null) { + wrapper.eq(IOTWorkOrder::getOrgId, userOrgId); + } + + if (queryDTO.getAssigneeId() != null) { + wrapper.eq(IOTWorkOrder::getAssigneeId, queryDTO.getAssigneeId()); + } else { + wrapper.and(w -> w.eq(IOTWorkOrder::getAssigneeId, userId) + .or() + .apply("FIND_IN_SET({0}, collaborator_ids)", userId)); + } + } else { + if (queryDTO.getSiteId() != null) { + wrapper.eq(IOTWorkOrder::getSiteId, queryDTO.getSiteId()); + } + if (queryDTO.getOrgId() != null) { + wrapper.eq(IOTWorkOrder::getOrgId, queryDTO.getOrgId()); + } + if (queryDTO.getAssigneeId() != null) { + wrapper.eq(IOTWorkOrder::getAssigneeId, queryDTO.getAssigneeId()); + } + } + + if (queryDTO.getOrderNo() != null && !queryDTO.getOrderNo().isEmpty()) { + wrapper.like(IOTWorkOrder::getOrderNo, queryDTO.getOrderNo()); + } + if (queryDTO.getOrderTitle() != null && !queryDTO.getOrderTitle().isEmpty()) { + wrapper.like(IOTWorkOrder::getOrderTitle, queryDTO.getOrderTitle()); + } + if (queryDTO.getSourceType() != null) { + wrapper.eq(IOTWorkOrder::getSourceType, queryDTO.getSourceType()); + } + if (queryDTO.getOrderType() != null) { + wrapper.eq(IOTWorkOrder::getOrderType, queryDTO.getOrderType()); + } + if (queryDTO.getPriorityLevel() != null) { + wrapper.eq(IOTWorkOrder::getPriorityLevel, queryDTO.getPriorityLevel()); + } + if (queryDTO.getOrderStatus() != null) { + wrapper.eq(IOTWorkOrder::getOrderStatus, queryDTO.getOrderStatus()); + } + if (queryDTO.getDeviceId() != null) { + wrapper.eq(IOTWorkOrder::getDeviceId, queryDTO.getDeviceId()); + } + if (queryDTO.getStartTime() != null) { + wrapper.ge(IOTWorkOrder::getCreateTime, queryDTO.getStartTime()); + } + if (queryDTO.getEndTime() != null) { + wrapper.le(IOTWorkOrder::getCreateTime, queryDTO.getEndTime()); + } + if (StringUtils.isNotEmpty(queryDTO.getKeyword())) { + wrapper.and(w -> w.like(IOTWorkOrder::getOrderNo, queryDTO.getKeyword()) + .or() + .like(IOTWorkOrder::getOrderTitle, queryDTO.getKeyword())); + } + + wrapper.orderByDesc(IOTWorkOrder::getCreateTime); + return wrapper; + } + + @Override + public IOTWorkOrder selectWorkOrderById(Long id) { + IOTWorkOrder workOrder = baseMapper.selectById(id); + if (workOrder == null) throw new ServiceException("工单不存在"); + + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + validateWorkOrderAccess(workOrder); + } + return workOrder; + } + + private void validateWorkOrderAccess(IOTWorkOrder workOrder) { + Long userId = SecurityUtils.getUserId(); + LoginUser loginUser = SecurityUtils.getLoginUser(); + Long userSiteId = loginUser.getSiteId(); + Long userOrgId = loginUser.getOrgId(); + + if (userSiteId != null && !userSiteId.equals(workOrder.getSiteId())) { + throw new ServiceException("无权访问该工单"); + } + + if (userOrgId != null && !userOrgId.equals(workOrder.getOrgId())) { + throw new ServiceException("无权访问该工单"); + } + + boolean isAssignee = userId.equals(workOrder.getAssigneeId()); + boolean isCollaborator = workOrder.getCollaboratorIds() != null && + workOrder.getCollaboratorIds().contains(userId.toString()); + + if (!isAssignee && !isCollaborator) { + throw new ServiceException("无权访问该工单"); + } + } + + @Override + public int insertWorkOrder(IOTWorkOrder workOrder) { + workOrder.setOrderNo(generateOrderNo()); + workOrder.setTenantId(SecurityUtils.getLoginUser().getOrgId()); + workOrder.setOrgId(SecurityUtils.getLoginUser().getOrgId()); + workOrder.setCreateTime(LocalDateTime.now()); + if (workOrder.getOrderStatus() == null) { + workOrder.setOrderStatus(1); + } + 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 dispatchWorkOrder(WorkOrderDispatchDTO dispatchDTO) { + IOTWorkOrder workOrder = baseMapper.selectById(dispatchDTO.getOrderId()); + if (workOrder == null) throw new ServiceException("工单不存在"); + + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + validateWorkOrderAccess(workOrder); + } + + IOTWorkOrder updateWorkOrder = new IOTWorkOrder(); + updateWorkOrder.setId(dispatchDTO.getOrderId()); + updateWorkOrder.setAssigneeId(dispatchDTO.getAssigneeId()); + updateWorkOrder.setAssigneeName(dispatchDTO.getAssigneeName()); + updateWorkOrder.setCollaboratorIds(dispatchDTO.getCollaboratorIds()); + updateWorkOrder.setCollaboratorNames(dispatchDTO.getCollaboratorNames()); + updateWorkOrder.setPlanStartTime(dispatchDTO.getPlanStartTime()); + updateWorkOrder.setPlanEndTime(dispatchDTO.getPlanEndTime()); + updateWorkOrder.setDeadlineTime(dispatchDTO.getDeadlineTime()); + updateWorkOrder.setOrderStatus(2); + updateWorkOrder.setUpdateTime(LocalDateTime.now()); + updateWorkOrder.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName()); + return baseMapper.updateById(updateWorkOrder); + } + + @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); + } + + 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); + } + + @Override + public int completeWorkOrder(IOTWorkOrder workOrder) { + IOTWorkOrder existWorkOrder = baseMapper.selectById(workOrder.getId()); + if (existWorkOrder == null) throw new ServiceException("工单不存在"); + + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + validateWorkOrderAccess(existWorkOrder); + } + + IOTWorkOrder updateWorkOrder = new IOTWorkOrder(); + updateWorkOrder.setId(workOrder.getId()); + updateWorkOrder.setOrderStatus(4); + updateWorkOrder.setActualEndTime(LocalDateTime.now()); + updateWorkOrder.setHandleResult(workOrder.getHandleResult()); + updateWorkOrder.setHandleRemark(workOrder.getHandleRemark()); + updateWorkOrder.setUpdateTime(LocalDateTime.now()); + updateWorkOrder.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName()); + return baseMapper.updateById(updateWorkOrder); + } + + @Override + public int suspendWorkOrder(Long id) { + IOTWorkOrder workOrder = baseMapper.selectById(id); + if (workOrder == null) throw new ServiceException("工单不存在"); + + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + validateWorkOrderAccess(workOrder); + } + + IOTWorkOrder updateWorkOrder = new IOTWorkOrder(); + updateWorkOrder.setId(id); + updateWorkOrder.setOrderStatus(5); + updateWorkOrder.setUpdateTime(LocalDateTime.now()); + updateWorkOrder.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName()); + return baseMapper.updateById(updateWorkOrder); + } + + @Override + public int deleteWorkOrderById(Long id) { + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + IOTWorkOrder workOrder = baseMapper.selectById(id); + if (workOrder != null) { + validateWorkOrderAccess(workOrder); + } + } + return baseMapper.deleteById(id); + } + + @Override + public int deleteWorkOrderByIds(Long[] ids) { + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId)) { + for (Long id : ids) { + IOTWorkOrder workOrder = baseMapper.selectById(id); + if (workOrder != null) { + validateWorkOrderAccess(workOrder); + } + } + } + return baseMapper.deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public Map getWorkOrderStatistics() { + Long userId = SecurityUtils.getUserId(); + LoginUser loginUser = SecurityUtils.getLoginUser(); + Long userOrgId = loginUser.getOrgId(); + Long userSiteId = loginUser.getSiteId(); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (!SecurityUtils.isAdmin(userId)) { + if (userSiteId != null) { + wrapper.eq(IOTWorkOrder::getSiteId, userSiteId); + } else if (userOrgId != null) { + wrapper.eq(IOTWorkOrder::getOrgId, userOrgId); + } + wrapper.and(w -> w.eq(IOTWorkOrder::getAssigneeId, userId) + .or() + .apply("FIND_IN_SET({0}, collaborator_ids)", userId)); + } + + List workOrders = baseMapper.selectList(wrapper); + Map statistics = new HashMap<>(); + statistics.put("total", workOrders.size()); + statistics.put("pending", workOrders.stream().filter(w -> w.getOrderStatus() == 1).count()); + statistics.put("dispatched", workOrders.stream().filter(w -> w.getOrderStatus() == 2).count()); + statistics.put("executing", workOrders.stream().filter(w -> w.getOrderStatus() == 3).count()); + statistics.put("completed", workOrders.stream().filter(w -> w.getOrderStatus() == 4).count()); + statistics.put("suspended", workOrders.stream().filter(w -> w.getOrderStatus() == 5).count()); + + statistics.put("todayNew", workOrders.stream() + .filter(w -> w.getCreateTime().toLocalDate().equals(LocalDateTime.now().toLocalDate())) + .count()); + + statistics.put("highPriority", workOrders.stream().filter(w -> w.getPriorityLevel() == 1).count()); + + return statistics; + } + + @Override + public IOTWorkOrder generateWorkOrderFromAlarm(Long alarmId) { + com.maibu.core.business.alarm_center.Alarm alarm = alarmService.getById(alarmId); + if (alarm == null) { + throw new ServiceException("告警不存在"); + } + + Long userId = SecurityUtils.getUserId(); + if (!SecurityUtils.isAdmin(userId) && alarm.getDeviceId() != null) { + Device device = deviceMapper.selectOne( + new LambdaQueryWrapper() + .eq(Device::getDeviceId, alarm.getDeviceId()) + .select(Device::getOrgId, Device::getSiteId) + ); + if (device != null) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (!loginUser.getOrgId().equals(device.getOrgId())) { + throw new ServiceException("无权访问该告警"); + } + } + } + + IOTWorkOrder workOrder = new IOTWorkOrder(); + workOrder.setOrderNo(generateOrderNo()); + workOrder.setOrderTitle(alarm.getAlarmTitle()); + workOrder.setSourceType(7); + workOrder.setOrderType(2); + workOrder.setPriorityLevel(determinePriority(alarm.getAlarmLevel())); + workOrder.setDeviceId(alarm.getDeviceId()); + workOrder.setDeviceName(alarm.getDeviceName()); + workOrder.setDeviceType(alarm.getDeviceType()); + workOrder.setOrgId(alarm.getTenantId()); + workOrder.setAlarmId(alarmId); + workOrder.setAlarmNo(alarm.getAlarmNo()); + workOrder.setTaskDescription(alarm.getAlarmContent()); + workOrder.setAiSuggestion(alarm.getHandleSuggestion()); + workOrder.setOrderStatus(1); + workOrder.setCreateTime(LocalDateTime.now()); + workOrder.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName()); + + baseMapper.insert(workOrder); + + return workOrder; + } + + private Integer determinePriority(Integer alarmLevel) { + if (alarmLevel == 1) { + return 1; + } else if (alarmLevel == 2) { + return 2; + } else { + return 3; + } + } + + private String generateOrderNo() { + String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + long count = baseMapper.selectCount(new LambdaQueryWrapper() + .likeRight(IOTWorkOrder::getOrderNo, "WO" + dateStr)); + return "WO" + dateStr + String.format("%04d", count + 1); + } +}