package com.ycl.platform.service.impl;
|
|
import com.alibaba.excel.annotation.format.DateTimeFormat;
|
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ycl.config.PlatformConfig;
|
import com.ycl.config.ServerConfig;
|
import com.ycl.exception.ServiceException;
|
import com.ycl.platform.domain.entity.*;
|
import com.ycl.platform.domain.form.*;
|
import com.ycl.platform.domain.query.*;
|
import com.ycl.platform.domain.vo.*;
|
import com.ycl.platform.domain.vo.screen.ScreenWorkOrderVO;
|
import com.ycl.platform.domain.vo.screen.WorkOrderRegionVO;
|
import com.ycl.platform.domain.vo.screen.WorkOrderTotalVO;
|
import com.ycl.platform.mapper.*;
|
import com.ycl.platform.service.NotifyService;
|
import com.ycl.platform.service.WorkOrderAuditingRecordService;
|
import com.ycl.platform.service.WorkOrderService;
|
import com.ycl.platform.service.YwPointService;
|
import com.ycl.platform.wvp.StreamContent;
|
import com.ycl.platform.wvp.WVPResult;
|
import com.ycl.system.Result;
|
import com.ycl.system.domain.SysConfig;
|
import com.ycl.system.entity.SysDictData;
|
import com.ycl.system.mapper.SysConfigMapper;
|
import com.ycl.system.mapper.SysDictDataMapper;
|
import com.ycl.system.model.LoginUser;
|
import com.ycl.system.page.PageUtil;
|
import com.ycl.utils.DateUtils;
|
import com.ycl.utils.SecurityUtils;
|
import com.ycl.utils.http.HttpUtils;
|
import com.ycl.utils.redis.RedisCache;
|
import com.ycl.utils.uuid.IdUtils;
|
import constant.Constants;
|
import constant.RedisConstant;
|
import enumeration.general.*;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.ObjectUtils;
|
import org.bytedeco.javacv.*;
|
import org.bytedeco.opencv.global.opencv_imgcodecs;
|
import org.bytedeco.opencv.opencv_core.Mat;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.Assert;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.StringUtils;
|
|
import javax.swing.*;
|
import java.io.IOException;
|
import java.net.HttpURLConnection;
|
import java.net.URL;
|
import java.net.URLDecoder;
|
import java.net.URLEncoder;
|
import java.nio.charset.StandardCharsets;
|
import java.text.SimpleDateFormat;
|
import java.time.LocalDateTime;
|
import java.time.ZoneId;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
import java.util.stream.Collectors;
|
|
/**
|
* 工单 服务实现类
|
*
|
* @author xp
|
* @since 2024-03-05
|
*/
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder> implements WorkOrderService {
|
|
private final YwPointService ywPointService;
|
private final WorkOrderAuditingRecordMapper workOrderAuditingRecordMapper;
|
private final WorkOrderAuditingRecordService workOrderAuditingRecordService;
|
private final WorkOrderYwConditionRecordMapper workOrderYwConditionRecordMapper;
|
private final NotifyService notifyService;
|
private final WorkOrderDistributeRecordMapper workOrderDistributeRecordMapper;
|
private final WorkOrderErrorTypeServiceImpl workOrderErrorTypeService;
|
private final SysConfigMapper configMapper;
|
private final ReportMapper reportMapper;
|
private final WorkOrderCheckImgMapper workOrderCheckImgMapper;
|
@Value("${rtsp.server:http://127.0.0.1:7788}")
|
private String rtspServer;
|
|
private final String DISTRIBUTE_LOCK_KEY = "distributeLock";
|
private final static String IMPORTANT = "important";
|
|
@Autowired
|
private RedisCache redisCache;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public synchronized Boolean innerAddWorkOrder(List<WorkOrder> workOrderList) {
|
int total = workOrderList.size();
|
workOrderList.stream().filter(item -> {
|
return StringUtils.hasText(item.getSerialNumber()) && Objects.nonNull(item.getStatus()) && !CollectionUtils.isEmpty(item.getErrorTypeList());
|
});
|
if (CollectionUtils.isEmpty(workOrderList)) {
|
return Boolean.TRUE;
|
}
|
// 根据国标码去重
|
workOrderList = workOrderList.stream()
|
.collect(Collectors.toMap(
|
WorkOrder::getSerialNumber,
|
p -> p,
|
(existing, replacement) -> existing // 冲突时保留第一个
|
)).values().stream().collect(Collectors.toList());
|
List<String> serialNumberList = workOrderList.stream().map(WorkOrder::getSerialNumber).collect(Collectors.toList());
|
// 查出数据库中国标码对应的未完成的工单
|
List<WorkOrder> inDatabaseWorkOrderList = baseMapper.getNotFinishedWorkOrders(serialNumberList);
|
inDatabaseWorkOrderList.stream().forEach(item -> {
|
if (StringUtils.hasText(item.getErrorType())) {
|
item.setErrorTypeList(List.of(item.getErrorType().split(",")));
|
} else {
|
item.setErrorTypeList(new ArrayList<>(1));
|
}
|
});
|
Map<String, WorkOrder> mapping = inDatabaseWorkOrderList.stream().collect((Collectors.toMap(WorkOrder::getSerialNumber, workOrder -> workOrder)));
|
List<WorkOrder> waitAddList = new ArrayList<>(48);
|
List<WorkOrderErrorType> waitAddErrorTypeList = new ArrayList<>(48);
|
Integer updateNum = 0;
|
Date now = new Date();
|
// 因故障类型不一致而要更新状态的工单
|
List<WorkOrder> willUpdateStatusWorkOrderList = new ArrayList<>(48);
|
// 更改工单类型而要增加的系统运维处理信息
|
List<WorkOrderYwConditionRecord> willAddMsg = new ArrayList<>(48);
|
// 即将要添加的错误类型
|
List<WorkOrderErrorType> willAddErrorType = new ArrayList<>(96);
|
for (WorkOrder workOrder : workOrderList) {
|
WorkOrder databaseWorkOrder = mapping.get(workOrder.getSerialNumber());
|
if (Objects.nonNull(databaseWorkOrder)) {
|
List<String> errorNameList = databaseWorkOrder.getErrorTypeList();
|
List<String> errorTypes = workOrder.getErrorTypeList();
|
if (errorNameList.containsAll(errorTypes)) {
|
// 如果,国标码、故障类型都一样,则跳过不处理
|
continue;
|
} else {
|
for (String errorType : errorTypes) {
|
if (!errorNameList.contains(errorType)) {
|
// 错误类型不一样,就新增一个错误类型,并且重置工单状态为待处理
|
WorkOrderErrorType workOrderErrorType = new WorkOrderErrorType();
|
workOrderErrorType.setWorkOrderNo(databaseWorkOrder.getWorkOrderNo());
|
workOrderErrorType.setCreateTime(now);
|
workOrderErrorType.setUpdateTime(now);
|
workOrderErrorType.setErrorName(errorType);
|
willAddErrorType.add(workOrderErrorType);
|
}
|
}
|
databaseWorkOrder.setStatus(WorkOrderStatusEnum.DISTRIBUTED);
|
databaseWorkOrder.setUpdateTime(now);
|
willUpdateStatusWorkOrderList.add(databaseWorkOrder);
|
updateNum++;
|
// 同时新增一个运维处理信息,表明此工单被调整
|
WorkOrderYwConditionRecord ywRecord = new WorkOrderYwConditionRecord();
|
ywRecord.setWorkOrderNo(databaseWorkOrder.getWorkOrderNo());
|
ywRecord.setCommitUser(1);
|
ywRecord.setYwCondition("故障类型更新,工单状态调整为待处理");
|
ywRecord.setCreateTime(new Date());
|
ywRecord.setSysMsg(Boolean.TRUE);
|
willAddMsg.add(ywRecord);
|
}
|
} else {
|
workOrder.setCreateTime(new Date());
|
workOrder.setUpdateTime(new Date());
|
// // 如果报备过,使用最新报备的错误类型
|
// Report report = reportMapper.checkPointReported(workOrder.getSerialNumber());
|
// if (Objects.nonNull(report)) {
|
// workOrder.setErrorType(report.getErrorType());
|
// }
|
waitAddList.add(workOrder);
|
}
|
}
|
if (willAddErrorType.size() > 0) {
|
workOrderErrorTypeService.getBaseMapper().addMany(willAddErrorType);
|
}
|
if (willAddMsg.size() > 0) {
|
workOrderYwConditionRecordMapper.insertMany(willAddMsg);
|
}
|
log.info("将要更新的工单数:" + willUpdateStatusWorkOrderList.size());
|
if (willUpdateStatusWorkOrderList.size() > 0) {
|
this.baseMapper.updateMany(willUpdateStatusWorkOrderList);
|
}
|
if (CollectionUtils.isEmpty(waitAddList)) {
|
return Boolean.TRUE;
|
}
|
List<String> willAddSerialNumber = waitAddList.stream().map(WorkOrder::getSerialNumber).collect(Collectors.toList());
|
List<YwPoint> pointList = new LambdaQueryChainWrapper<>(ywPointService.getBaseMapper())
|
.select(YwPoint::getUnitId, YwPoint::getSerialNumber, YwPoint::getImportantTag, YwPoint::getImportantTag, YwPoint::getProvinceTag, YwPoint::getImportantCommandImageTag)
|
.in(YwPoint::getSerialNumber, willAddSerialNumber)
|
.list();
|
Map<String, YwPoint> pointMapping = pointList.stream().collect(Collectors.toMap(YwPoint::getSerialNumber, point -> point));
|
// 查出重点点位、普通点位的处理时间
|
SysConfig important = configMapper.checkConfigKeyUnique("important.wordkorder.time");
|
SysConfig normal = configMapper.checkConfigKeyUnique("normal.wordkorder.alarm.time");
|
// 如果即将生成工单,但是设备国标码查不到点位,则不添加?
|
List<WorkOrder> notAddList = new ArrayList<>();
|
//查redis今日工单数量
|
int workOrderNum = 0;
|
//UUID作为value,保证上锁的线程自己解锁
|
String requestId = IdUtils.fastSimpleUUID();
|
try {
|
for (int i = 0; i < 3; i++) {
|
boolean result = redisCache.acquireLock(RedisConstant.WORKORDER_NUM_LOCK, requestId, 10000);
|
if (result) {
|
//查今日工单量
|
Object redisNum = redisCache.getCacheObject(RedisConstant.WORKORDER_NUM);
|
workOrderNum = redisNum == null ? 0 : (Integer) redisNum;
|
break;
|
} else {
|
if (i == 2) {
|
log.error("锁被占用");
|
return Boolean.FALSE;
|
}
|
//等待一段时间后继续
|
Thread.sleep(5000);
|
}
|
}
|
} catch (InterruptedException e) {
|
log.error("获取锁异常");
|
return Boolean.FALSE;
|
}
|
for (WorkOrder workOrder : waitAddList) {
|
YwPoint point = pointMapping.get(workOrder.getSerialNumber());
|
if (Objects.isNull(point)) {
|
notAddList.add(workOrder);
|
continue;
|
}
|
//数字前面补0
|
workOrderNum++;
|
workOrder.setWorkOrderNo(IdUtils.workOrderNO(now, String.format("%05d", workOrderNum)));
|
if (Objects.nonNull(point.getUnitId())) {
|
workOrder.setUnitId(Math.toIntExact(point.getUnitId()));
|
}
|
if (point.getImportantTag() || point.getImportantCommandImageTag()) {
|
workOrder.setProcessingPeriod(Integer.valueOf(important.getConfigValue()));
|
} else {
|
workOrder.setProcessingPeriod(Integer.valueOf(normal.getConfigValue()));
|
}
|
// 保存错误类型
|
for (String errorType : workOrder.getErrorTypeList()) {
|
WorkOrderErrorType workOrderErrorType = new WorkOrderErrorType();
|
workOrderErrorType.setWorkOrderNo(workOrder.getWorkOrderNo());
|
workOrderErrorType.setCreateTime(now);
|
workOrderErrorType.setUpdateTime(now);
|
workOrderErrorType.setErrorName(errorType);
|
waitAddErrorTypeList.add(workOrderErrorType);
|
}
|
}
|
waitAddList.removeAll(notAddList);
|
if (CollectionUtils.isEmpty(waitAddList)) {
|
return Boolean.TRUE;
|
}
|
//记录工单数
|
redisCache.setCacheObject(RedisConstant.WORKORDER_NUM, workOrderNum);
|
redisCache.releaseLock(RedisConstant.WORKORDER_NUM_LOCK, requestId);
|
// 保存工单和故障类型
|
baseMapper.addMany(waitAddList);
|
if (!CollectionUtils.isEmpty(waitAddErrorTypeList)) {
|
workOrderErrorTypeService.getBaseMapper().addMany(waitAddErrorTypeList);
|
}
|
// 如果是直接下发,添加下发记录
|
if (WorkOrderStatusEnum.DISTRIBUTED.equals(waitAddList.get(0).getStatus())) {
|
ArrayList<String> list = new ArrayList<>();
|
List<WorkOrderDistributeRecord> distributedRecordList = waitAddList.stream().map(item -> {
|
list.add(item.getSerialNumber());
|
WorkOrderDistributeRecord workOrderDistributeRecord = new WorkOrderDistributeRecord();
|
workOrderDistributeRecord.setWorkOrderNo(item.getWorkOrderNo());
|
workOrderDistributeRecord.setDistributeWay(WorkOrderDistributeWayEnum.DIRECT_DISTRIBUTE);
|
workOrderDistributeRecord.setUserId(1L);
|
workOrderDistributeRecord.setCreateTime(now);
|
workOrderDistributeRecord.setUpdateTime(now);
|
return workOrderDistributeRecord;
|
}).collect(Collectors.toList());
|
workOrderDistributeRecordMapper.insertBatch(distributedRecordList);
|
// 同步点位状态
|
ywPointService.updateRecovery(list, 1);
|
}
|
log.info("传入工单总数: {},实际添加工单数:{}, 实际修改工单数:{}", total, waitAddList.size(), updateNum);
|
return Boolean.TRUE;
|
}
|
|
/**
|
* 添加
|
*
|
* @param form
|
* @return
|
*/
|
@Override
|
public Result add(WorkOrderForm form) {
|
//查redis今日工单数量
|
int workOrderNum = 0;
|
//UUID作为value,保证上锁的线程自己解锁
|
String requestId = IdUtils.fastSimpleUUID();
|
boolean result = redisCache.acquireLock(RedisConstant.WORKORDER_NUM_LOCK, requestId, 10000);
|
if (result) {
|
//查今日工单量
|
Object redisNum = redisCache.getCacheObject(RedisConstant.WORKORDER_NUM);
|
workOrderNum = redisNum == null ? 0 : (Integer) redisNum;
|
workOrderNum++;
|
redisCache.setCacheObject(RedisConstant.WORKORDER_NUM, workOrderNum);
|
redisCache.releaseLock(RedisConstant.WORKORDER_NUM_LOCK, requestId);
|
} else {
|
return Result.error("工单正在添加,请稍后再试");
|
}
|
WorkOrder entity = WorkOrderForm.getEntityByForm(form, null);
|
entity.setCreateTime(DateUtils.getNowDate());
|
entity.setStatus(WorkOrderStatusEnum.WAIT_DISTRIBUTE);
|
Date now = new Date();
|
entity.setCreateTime(now);
|
entity.setUpdateTime(now);
|
entity.setWorkOrderNo(IdUtils.workOrderNO(now, String.format("%05d", workOrderNum)));
|
entity.setErrorType(String.join(",", form.getErrorType()));
|
List<WorkOrderErrorType> workOrderErrorTypes = form.getErrorType().stream().map(errorType -> new WorkOrderErrorType(entity.getWorkOrderNo(), errorType)).toList();
|
workOrderErrorTypeService.getBaseMapper().insertWorkOrderErrorTypeList(workOrderErrorTypes);
|
if (baseMapper.insert(entity) > 0) {
|
return Result.ok("添加成功");
|
}
|
return Result.error("添加失败");
|
}
|
|
/**
|
* 修改
|
*
|
* @param form
|
* @return
|
*/
|
@Override
|
public Result update(WorkOrderForm form) {
|
|
WorkOrder entity = baseMapper.selectById(form.getId());
|
// 为空抛IllegalArgumentException,做全局异常处理
|
Assert.notNull(entity, "记录不存在");
|
BeanUtils.copyProperties(form, entity);
|
Date now = new Date();
|
entity.setUpdateTime(now);
|
if (baseMapper.updateById(entity) > 0) {
|
return Result.ok("修改成功");
|
}
|
return Result.error("修改失败");
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result auditing(WorkOrderAuditingForm form) {
|
WorkOrder workOrder = baseMapper.selectById(form.getId());
|
// 工单状态
|
workOrder.setStatus(form.getAuditingResult());
|
baseMapper.updateById(workOrder);
|
// 添加一条审核记录
|
WorkOrderAuditingRecord workOrderAuditingRecord = new WorkOrderAuditingRecord();
|
workOrderAuditingRecord.setWorkOrderNo(workOrder.getWorkOrderNo());
|
workOrderAuditingRecord.setAuditingUser(SecurityUtils.getLoginUser().getUserId().intValue());
|
workOrderAuditingRecord.setResult(form.getAuditingResult().getDesc());
|
workOrderAuditingRecord.setRemark(form.getAuditingRemark());
|
workOrderAuditingRecordMapper.insert(workOrderAuditingRecord);
|
// 添加新通知
|
Notify notify = Notify.genEntityByUnit(NotifyTypeEnum.WORK_ORDER,
|
form.getAuditingResult().getDesc(),
|
workOrder.getUnitId(),
|
UrgentLevelEnum.WARNING,
|
workOrder.getWorkOrderNo());
|
notifyService.save(notify);
|
// 同步点位状态
|
if (form.getAuditingResult() == WorkOrderStatusEnum.AUDITING_SUCCESS) {
|
ywPointService.updateRecovery(Collections.singletonList(workOrder.getSerialNumber()), 0);
|
}
|
return Result.ok("操作成功");
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result batchAuditing(WorkOrderBatchAuditingForm form) {
|
// 根据故障类型获取列表
|
List<WorkOrder> list = new LambdaQueryChainWrapper<>(baseMapper)
|
.in(WorkOrder::getStatus, WorkOrderStatusEnum.YW_HANDLE.getValue())
|
.in(WorkOrder::getErrorType, form.getErrorTypes())
|
.select(WorkOrder::getId, WorkOrder::getUnitId, WorkOrder::getWorkOrderNo, WorkOrder::getSerialNumber)
|
.list();
|
if (list.isEmpty()) {
|
return Result.error("没有工单可以审核");
|
}
|
List<String> workOrderNoList = list.stream().map(WorkOrder::getWorkOrderNo).collect(Collectors.toList());
|
List<String> serialNumbers = list.stream().map(WorkOrder::getSerialNumber).toList();
|
// 工单状态
|
LambdaUpdateWrapper<WorkOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
lambdaUpdateWrapper.in(WorkOrder::getWorkOrderNo, workOrderNoList);
|
lambdaUpdateWrapper.set(WorkOrder::getStatus, form.getAuditingResult());
|
baseMapper.update(lambdaUpdateWrapper);
|
// 添加多条审核记录
|
List<WorkOrderAuditingRecord> workOrderAuditingRecords = new ArrayList<>();
|
for (String workOrderNo : workOrderNoList) {
|
WorkOrderAuditingRecord workOrderAuditingRecord = new WorkOrderAuditingRecord();
|
workOrderAuditingRecord.setWorkOrderNo(workOrderNo);
|
workOrderAuditingRecord.setAuditingUser(SecurityUtils.getLoginUser().getUserId().intValue());
|
workOrderAuditingRecord.setResult(form.getAuditingResult().getDesc());
|
workOrderAuditingRecord.setRemark(form.getAuditingRemark());
|
workOrderAuditingRecords.add(workOrderAuditingRecord);
|
}
|
workOrderAuditingRecordService.saveBatch(workOrderAuditingRecords);
|
// 添加新通知
|
List<Notify> notifies = new ArrayList<>();
|
for (WorkOrder workOrder : list) {
|
Notify notify = Notify.genEntityByUnit(NotifyTypeEnum.WORK_ORDER,
|
form.getAuditingResult().getDesc(),
|
workOrder.getUnitId(),
|
UrgentLevelEnum.WARNING,
|
workOrder.getWorkOrderNo());
|
notifies.add(notify);
|
}
|
// 同步点位状态
|
if (form.getAuditingResult() == WorkOrderStatusEnum.AUDITING_SUCCESS) {
|
ywPointService.updateRecovery(serialNumbers, 0);
|
}
|
notifyService.saveBatch(notifies);
|
return Result.ok("操作成功");
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result ywCondition(WorkOrderYWConditionForm form) {
|
WorkOrder workOrder = baseMapper.selectById(form.getId());
|
if (Objects.isNull(workOrder)) {
|
throw new ServiceException("工单不存在");
|
}
|
// 工单状态
|
workOrder.setStatus(WorkOrderStatusEnum.YW_HANDLE);
|
workOrder.setYwHandleTime(LocalDateTime.now());
|
baseMapper.updateById(workOrder);
|
// 添加一条运维情况记录
|
WorkOrderYwConditionRecord workOrderYwConditionRecord = new WorkOrderYwConditionRecord();
|
workOrderYwConditionRecord.setWorkOrderNo(workOrder.getWorkOrderNo());
|
workOrderYwConditionRecord.setCommitUser(SecurityUtils.getLoginUser().getUserId().intValue());
|
workOrderYwConditionRecord.setYwCondition(form.getYwCondition());
|
workOrderYwConditionRecord.setYwProofMaterials(form.getYwProofMaterials());
|
workOrderYwConditionRecord.setSysMsg(Boolean.FALSE);
|
workOrderYwConditionRecordMapper.insert(workOrderYwConditionRecord);
|
return Result.ok("操作成功");
|
}
|
|
@Override
|
public List<WorkOrderYwConditionRecordVO> selectYwConditionByYwId(String workOrderNo) {
|
List<WorkOrderYwConditionRecordVO> ywConditionList = workOrderYwConditionRecordMapper.selectYwConditionByYwId(workOrderNo);
|
ywConditionList.stream().forEach(item -> {
|
if (Objects.nonNull(item.getSysMsg()) && item.getSysMsg()) {
|
item.setUnitName("系统消息");
|
}
|
});
|
return ywConditionList;
|
}
|
|
@Override
|
public List<WorkOrderAuditingRecord> selectYwAuditingListByYwId(String workOrderNo) {
|
return new LambdaQueryChainWrapper<>(workOrderAuditingRecordMapper)
|
.eq(WorkOrderAuditingRecord::getWorkOrderNo, workOrderNo)
|
.orderByAsc(WorkOrderAuditingRecord::getCreateTime)
|
.list();
|
}
|
|
@Override
|
public Result ywResult(WorkOrderYWResultForm form) {
|
return null;
|
}
|
|
@Override
|
public Result checkResult(WorkOrderCheckResultForm form) {
|
return null;
|
}
|
|
/**
|
* 批量删除
|
*
|
* @param ids
|
* @return
|
*/
|
@Override
|
public Result remove(List<String> ids) {
|
if (baseMapper.deleteBatchIds(ids) > 0) {
|
return Result.ok("删除成功");
|
}
|
return Result.error("删除失败");
|
}
|
|
/**
|
* id删除
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public Result removeById(String id) {
|
if (baseMapper.deleteById(id) > 0) {
|
return Result.ok("删除成功");
|
}
|
return Result.error("删除失败");
|
}
|
|
/**
|
* 分页查询
|
*
|
* @param query
|
* @return
|
*/
|
@Override
|
public Result page(WorkOrderQuery query) {
|
IPage<WorkOrderVO> page = PageUtil.getPage(query, WorkOrderVO.class);
|
query.setUnitId(SecurityUtils.getUnitId());
|
query.setStart(DateUtils.getDayStart(query.getStart()));
|
query.setEnd(DateUtils.getDayEnd(query.getEnd()));
|
baseMapper.page(page, query);
|
if (!CollectionUtils.isEmpty(page.getRecords())) {
|
page.getRecords().stream().forEach(item -> {
|
if (StringUtils.hasText(item.getErrorType())) {
|
item.setErrorTypeList(List.of(item.getErrorType().split(",")));
|
}
|
if (StringUtils.hasText(item.getImgListStr())) {
|
item.setImgList(List.of(item.getImgListStr().split(",")));
|
}
|
});
|
}
|
return Result.ok().data(page.getRecords()).total(page.getTotal());
|
}
|
|
@Override
|
public Result distributePage(DistributeWorkOrderQuery query) {
|
IPage<WorkOrderVO> page = PageUtil.getPage(query, WorkOrderVO.class);
|
baseMapper.distributePage(page, query);
|
return Result.ok().data(page).total(page.getTotal());
|
}
|
|
@Override
|
@Transactional
|
public Result distributeFast(DistributeWorkOrderVO data) {
|
// 获取当前时间
|
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
|
data.setEnd(now);
|
switch (data.getFastWay()) {
|
case LAST_HOUR:
|
data.setStart(now.minusHours(1));
|
break;
|
case LAST_TWO_HOUR:
|
data.setStart(now.minusHours(2));
|
break;
|
case LAST_DAY:
|
data.setStart(now.minusDays(1));
|
break;
|
default:
|
break;
|
}
|
if (Objects.isNull(data.getStart())) {
|
throw new RuntimeException("无法生成快速下发的时间范围,请选择正确的快速下发方式");
|
}
|
// 查询符合条件的工单
|
List<WorkOrder> list = new LambdaQueryChainWrapper<>(baseMapper)
|
.select(WorkOrder::getSerialNumber, WorkOrder::getWorkOrderNo)
|
.eq(WorkOrder::getStatus, WorkOrderStatusEnum.WAIT_DISTRIBUTE)
|
.eq(Objects.nonNull(data.getUnitId()), WorkOrder::getUnitId, data.getUnitId())
|
.in(WorkOrder::getErrorType, data.getErrorType())
|
.between(WorkOrder::getCreateTime, data.getStart(), data.getEnd())
|
.orderByDesc(WorkOrder::getCreateTime)
|
.last("limit " + data.getFastNumLimit())
|
.list();
|
List<String> workOrderNoList = list.stream().map(WorkOrder::getWorkOrderNo).toList();
|
List<String> serialNumberList = list.stream().map(WorkOrder::getSerialNumber).toList();
|
|
if (workOrderNoList.isEmpty()) {
|
return Result.error("没有符合条件的工单");
|
}
|
if (!getDistributeLock()) {
|
return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
|
}
|
try {
|
new LambdaUpdateChainWrapper<>(baseMapper)
|
.set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED)
|
.in(WorkOrder::getWorkOrderNo, workOrderNoList)
|
.update();
|
addDistributeRecord(workOrderNoList, WorkOrderDistributeWayEnum.FAST_DISTRIBUTE);
|
// 同步点位状态
|
ywPointService.updateRecovery(serialNumberList, 1);
|
return Result.ok("成功下发" + workOrderNoList.size() + "条工单");
|
} catch (Exception e) {
|
return Result.error("操作失败");
|
} finally {
|
distributeUnLock();
|
}
|
}
|
|
@Override
|
@Transactional
|
public Result selectedIdsDistribute(DistributeWorkOrderQuery query) {
|
WorkOrderDistributeWayEnum distributeWayEnum = WorkOrderDistributeWayEnum.SELECTED_DISTRIBUTE;
|
if (!getDistributeLock()) {
|
return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
|
}
|
try {
|
if (query.getWorkOrderNOList().isEmpty()) {
|
query.setWorkOrderNOList(new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(WorkOrder::getStatus, WorkOrderStatusEnum.WAIT_DISTRIBUTE)
|
.eq(Objects.nonNull(query.getUnitId()), WorkOrder::getUnitId, query.getUnitId())
|
.select(WorkOrder::getWorkOrderNo)
|
.list()
|
.stream()
|
.map(WorkOrder::getWorkOrderNo)
|
.collect(Collectors.toList()));
|
distributeWayEnum = WorkOrderDistributeWayEnum.ALL_DISTRIBUTE;
|
}
|
if (query.getWorkOrderNOList().isEmpty()) {
|
return Result.error("没有工单待下发");
|
}
|
new LambdaUpdateChainWrapper<>(baseMapper)
|
.set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED)
|
.in(WorkOrder::getWorkOrderNo, query.getWorkOrderNOList())
|
.update();
|
addDistributeRecord(query.getWorkOrderNOList(), distributeWayEnum);
|
// 同步点位状态
|
List<String> serialNumberList = new LambdaQueryChainWrapper<>(baseMapper).select(WorkOrder::getSerialNumber).in(WorkOrder::getWorkOrderNo, query.getWorkOrderNOList()).list().stream().map(WorkOrder::getSerialNumber).toList();
|
ywPointService.updateRecovery(serialNumberList, 1);
|
return Result.ok("成功下发" + query.getWorkOrderNOList().size() + "条工单");
|
} catch (Exception e) {
|
System.out.println(e.getMessage());
|
return Result.error("操作失败");
|
} finally {
|
distributeUnLock();
|
}
|
}
|
|
/**
|
* 申请工单下发锁
|
*
|
* @return 工单下发锁申请结果
|
*/
|
public synchronized Boolean getDistributeLock() {
|
if (Objects.isNull(redisCache.getCacheObject(DISTRIBUTE_LOCK_KEY))) {
|
redisCache.setCacheObject(DISTRIBUTE_LOCK_KEY, "1", 30, TimeUnit.SECONDS);
|
return true;
|
} else {
|
return false;
|
}
|
}
|
|
/**
|
* 工单下发锁释放
|
*/
|
public synchronized void distributeUnLock() {
|
redisCache.deleteObject(DISTRIBUTE_LOCK_KEY);
|
}
|
|
/**
|
* 添加工单下发记录
|
*
|
* @param workOrderNoList 工单id
|
*/
|
private void addDistributeRecord(List<String> workOrderNoList, WorkOrderDistributeWayEnum distributeWay) {
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
workOrderDistributeRecordMapper.insertBatch(
|
workOrderNoList.stream()
|
.map(no -> new WorkOrderDistributeRecord(no, loginUser.getUserId(), distributeWay))
|
.toList()
|
);
|
}
|
|
/**
|
* 根据id查找
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public Result detail(String id) {
|
|
WorkOrder entity = baseMapper.selectById(id);
|
Assert.notNull(entity, "记录不存在");
|
WorkOrderVO vo = WorkOrderVO.getVoByEntity(entity, null);
|
return Result.ok().data(vo);
|
}
|
|
/**
|
* 列表
|
*
|
* @return
|
*/
|
@Override
|
public Result all() {
|
List<WorkOrder> entities = baseMapper.selectList(null);
|
List<WorkOrderVO> vos = entities.stream()
|
.map(
|
entity -> WorkOrderVO.getVoByEntity(entity, null)
|
)
|
.collect(Collectors.toList());
|
return Result.ok().data(vos);
|
}
|
|
@Override
|
public Result screenWorkOrder(ScreenQuery query) {
|
ScreenWorkOrderVO screen = baseMapper.screenWorkOrder(query);
|
return Result.ok().data(screen);
|
}
|
|
@Override
|
public Map<String, Object> home(HomeQuery monitorQuery) {
|
Map<String, Object> dataMap = new HashMap<>();
|
Map<String, Object> data1 = new HashMap<>();
|
Map<String, Object> data2 = new HashMap<>();
|
Map<String, Object> data3 = new HashMap<>();
|
List<Map<String, Object>> home = baseMapper.home(monitorQuery);
|
if (ObjectUtils.isNotEmpty(home)) {
|
for (Map<String, Object> map : home) {
|
if (Objects.nonNull(map.get("dateType")) && StringUtils.hasText(map.get("dateType").toString())) {
|
data1.put(map.get("dateType").toString(), map.get("num1"));
|
data2.put(map.get("dateType").toString(), map.get("num2"));
|
data3.put(map.get("dateType").toString(), map.get("num3"));
|
}
|
}
|
dataMap.put("name", home.get(0).get("name"));
|
}
|
dataMap.put("complete", data1);
|
dataMap.put("waiting", data2);
|
dataMap.put("pending", data3);
|
return dataMap;
|
}
|
|
@Override
|
public WorkOrderTotalVO workOrderTotal(DashboardQuery dashboardQuery) {
|
return baseMapper.workOrderTotal(dashboardQuery);
|
}
|
|
@Override
|
public List<WorkOrderRegionVO> workOrderRegion(DashboardQuery dashboardQuery) {
|
//初始化所有区域数据
|
List<WorkOrderRegionVO> vos = new ArrayList<>();
|
for (AreaDeptEnum value : AreaDeptEnum.values()) {
|
WorkOrderRegionVO vo = new WorkOrderRegionVO();
|
vo.setArea(value.getName());
|
vo.setDoneNum(0);
|
vo.setTodoNum(0);
|
vos.add(vo);
|
}
|
List<WorkOrderRegionVO> workOrderRegionVOS = baseMapper.workOrderRegion(dashboardQuery);
|
for (WorkOrderRegionVO vo : vos) {
|
for (WorkOrderRegionVO workOrder : workOrderRegionVOS) {
|
//赋值
|
if (vo.getArea().equals(workOrder.getArea())) {
|
BeanUtils.copyProperties(workOrder, vo);
|
}
|
}
|
}
|
return vos;
|
}
|
|
|
@Override
|
public synchronized String getFrameImgByDevice(String deviceId, String channelId, String workOrderNo) {
|
String url = String.format(this.rtspServer + "/api/play/start/%s/%s", deviceId, channelId);
|
String result = HttpUtils.sendGet(url);
|
log.error("拿到取流响应结果:" + result);
|
WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
|
String imgUrl = null;
|
if (0 == wvpResult.getCode()) {
|
log.error("请求成功");
|
JSONObject data = (JSONObject) wvpResult.getData();
|
String rtspUrl = data.getString("rtsp"); // 取地址
|
log.error("目标地址:" + rtspUrl);
|
if (StringUtils.hasText(rtspUrl)) {
|
try {
|
FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
|
grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式,不然会丢包很严重
|
grabber.setImageWidth(960);
|
grabber.setImageHeight(540);
|
grabber.start();
|
CanvasFrame canvasFrame = new CanvasFrame("正茂");// 创建窗口
|
canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置窗口关闭程序是否也跟随关闭
|
canvasFrame.setAlwaysOnTop(true);
|
|
OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
|
int ex = 0;
|
while (true) {
|
if (ex > 1) {
|
break;
|
}
|
Frame frame = grabber.grabImage();
|
canvasFrame.showImage(frame);
|
//程序到这里其实已经实现了预览的功能了,下面的方法就是将流保存成图片
|
|
//opencv_core.Mat
|
Mat mat = converter.convertToMat(frame);
|
|
imgUrl = workOrderNo + "_" + IdUtils.fastSimpleUUID() + ".png";
|
// 生成图片路径
|
String imgPath = PlatformConfig.getProfile() + "/" + imgUrl;
|
System.out.println("图片保存地址:" + imgPath);
|
imgUrl = Constants.RESOURCE_PREFIX + "/" + imgUrl;
|
|
opencv_imgcodecs.imwrite(imgPath, mat);
|
|
ex++;
|
try {
|
Thread.sleep(1000);
|
}
|
catch (InterruptedException e)
|
{
|
e.printStackTrace();
|
} // 1000毫秒刷新一次圖像
|
}
|
grabber.stop(); // 停止捕获
|
grabber.release(); // 释放资源
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return imgUrl;
|
}
|
|
@Override
|
public void saveFrameImgByDevice(String deviceId, String channelId, String workOrderNo) {
|
String url = String.format(this.rtspServer + "/api/play/start/%s/%s", deviceId, channelId);
|
String result = HttpUtils.sendGet(url);
|
WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
|
String imgUrl = null;
|
if (wvpResult.getCode() == 0) {
|
JSONObject data = (JSONObject) wvpResult.getData();
|
String rtspUrl = data.getString("fmp4"); // 取mp4地址
|
if (StringUtils.hasText(rtspUrl)) {
|
System.out.println("目标地址:" + rtspUrl);
|
FFmpegFrameGrabber grabber = null;
|
try {
|
grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
|
//设置10s超时
|
grabber.setTimeout(10000);
|
grabber.start();
|
Frame frame = grabber.grabImage(); // 直接捕获一帧
|
if (frame != null) {
|
System.out.println("成功捕获一帧");
|
// 将Frame转换为Mat
|
OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
|
Mat mat = converter.convertToMat(frame);
|
|
imgUrl = workOrderNo + "_" + IdUtils.fastSimpleUUID() + ".png";
|
// 生成图片路径
|
String imgPath = PlatformConfig.getProfile() + "/" + imgUrl;
|
System.out.println("图片保存地址:" + imgPath);
|
imgUrl = Constants.RESOURCE_PREFIX + "/" + imgUrl;
|
// 保存图片
|
opencv_imgcodecs.imwrite(imgPath, mat);
|
} else {
|
System.out.println("未捕获到帧");
|
}
|
} catch (FrameGrabber.Exception e) {
|
e.printStackTrace();
|
} finally {
|
if (grabber != null) {
|
try {
|
grabber.stop(); // 停止捕获
|
} catch (FrameGrabber.Exception e) {
|
e.printStackTrace();
|
}
|
// 通常不需要调用release(),因为stop()会处理资源释放
|
// grabber.release(); // 释放资源
|
}
|
}
|
}
|
} else {
|
System.out.println("请求失败,错误码:" + wvpResult.getCode());
|
}
|
System.out.println("图片URL:" + imgUrl);
|
if (StringUtils.hasText(imgUrl)) {
|
WorkOrderCheckImg img = new WorkOrderCheckImg();
|
img.setWorkOrderNo(workOrderNo);
|
img.setImgUrl(imgUrl);
|
img.setCreateTime(new Date());
|
workOrderCheckImgMapper.insert(img);
|
}
|
}
|
|
@Override
|
public List<DeviceInfoVO> hasErrorWorkOrderList(Date start, Date end) {
|
List<DeviceInfoVO> list = baseMapper.hasErrorWorkOrderList(start, end);
|
return list;
|
}
|
|
@Override
|
public void updateImgById(Integer workOrderId, String imgPath) {
|
new LambdaUpdateChainWrapper<>(baseMapper)
|
.eq(WorkOrder::getId, workOrderId)
|
.set(WorkOrder::getYwCheckResult, imgPath)
|
.update();
|
}
|
|
@Override
|
public Result processImg(String workOrderNo) {
|
WorkOrder workOrder = new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(WorkOrder::getWorkOrderNo, workOrderNo)
|
.one();
|
if (Objects.isNull(workOrder)) {
|
throw new RuntimeException("此工单不存在");
|
}
|
// 运维记录
|
List<WorkOrderYwConditionRecordVO> workOrderYwConditionRecordVOS = this.selectYwConditionByYwId(workOrderNo);
|
// 审核记录
|
List<WorkOrderAuditingRecord> workOrderAuditingRecords = this.selectYwAuditingListByYwId(workOrderNo);
|
WorkOrderProcessVO process = new WorkOrderProcessVO();
|
process.setYwList(workOrderYwConditionRecordVOS);
|
process.setAuditingList(workOrderAuditingRecords);
|
// 查询点位事前事后最新的一条数据是否审核通过
|
ReportAuditingRecordVO beforeRecord = ywPointService.getReportResult(workOrder.getSerialNumber(), "事前报备");
|
ReportAuditingRecordVO afterRecord = ywPointService.getReportResult(workOrder.getSerialNumber(), "事后报备");
|
|
Date now = new Date();
|
if (Objects.nonNull(beforeRecord)) {
|
if (now.before(beforeRecord.getBeginCreateTime())) {
|
process.setBeforeReportMsg("事前报备已失效");
|
} else if (now.after(beforeRecord.getEndCreateTime())) {
|
process.setBeforeReportMsg("事前报备未生效");
|
} else {
|
process.setBeforeReportMsg("已事前报备");
|
}
|
}
|
if (Objects.nonNull(afterRecord)) {
|
if (now.before(afterRecord.getBeginCreateTime())) {
|
process.setAfterReportMsg("事后报备已失效");
|
} else if (now.after(afterRecord.getEndCreateTime())) {
|
process.setAfterReportMsg("事后报备未生效");
|
} else {
|
process.setAfterReportMsg("已事后报备");
|
}
|
}
|
return Result.ok().data(process);
|
}
|
|
@Override
|
public Result detailByNo(String workOrderNo) {
|
WorkOrderDetailVO workOrder = baseMapper.detailByNo(workOrderNo);
|
// 是否报备
|
boolean hasReport = new LambdaQueryChainWrapper<>(reportMapper)
|
.eq(Report::getSerialNumber, workOrder.getSerialNumber())
|
.exists();
|
workOrder.setHasReport(hasReport);
|
// 故障类型
|
List<SysDictData> errorList = workOrderErrorTypeService.getBaseMapper().getErrorList(workOrder.getWorkOrderNo());
|
List<String> errList = errorList.stream().map(SysDictData::getDictLabel).collect(Collectors.toList());
|
workOrder.setErrorTypeList(errList);
|
// 检测图片
|
List<WorkOrderCheckImg> imgList = new LambdaQueryChainWrapper<>(workOrderCheckImgMapper)
|
.eq(WorkOrderCheckImg::getWorkOrderNo, workOrderNo)
|
.orderByDesc(WorkOrderCheckImg::getCreateTime)
|
.last("limit 20")
|
.list();
|
workOrder.setImgList(imgList);
|
return Result.ok().data(workOrder);
|
}
|
|
@Override
|
public List<WorkOrderVO> export(WorkOrderExportQuery query) {
|
query.setUnitId(SecurityUtils.getUnitId());
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
if (query.getStart() == null) {
|
query.setStart(format.format(DateUtils.getDayStart(new Date())));
|
} else {
|
query.setStart(query.getStart() + " 00:00:00");
|
}
|
if (query.getEnd() == null) {
|
query.setStart(format.format(DateUtils.getDayEnd(new Date())));
|
} else {
|
query.setEnd(query.getEnd() + " 23:59:59");
|
}
|
|
List<WorkOrderVO> export = baseMapper.export(query);
|
|
System.out.println(export);
|
return export;
|
}
|
}
|