fuliqi
2024-11-14 e9af9f5cfeddbe5c0b33a3060b8ea6364c51e744
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java
@@ -1,9 +1,11 @@
package com.ycl.platform.service.impl;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -11,10 +13,11 @@
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.excel.ErrorExport;
import com.ycl.platform.domain.excel.PointExport;
import com.ycl.platform.domain.excel.WorkOrderWhiteExport;
import com.ycl.platform.domain.form.*;
import com.ycl.platform.domain.query.*;
import com.ycl.platform.domain.vo.*;
@@ -26,13 +29,11 @@
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;
@@ -40,23 +41,24 @@
import com.ycl.utils.http.HttpUtils;
import com.ycl.utils.redis.RedisCache;
import com.ycl.utils.uuid.IdUtils;
import constant.ApiConstants;
import constant.CheckConstants;
import constant.Constants;
import constant.RedisConstant;
import enumeration.ErrorType;
import enumeration.general.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.bytedeco.javacv.*;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.OpenCVFrameConverter;
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.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -65,21 +67,13 @@
import org.springframework.util.StringUtils;
import pojo.CascadeOption;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.File;
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.io.OutputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -101,10 +95,10 @@
    private final WorkOrderDistributeRecordMapper workOrderDistributeRecordMapper;
    private final WorkOrderErrorTypeServiceImpl workOrderErrorTypeService;
    private final WorkOrderErrorTypeMapper workOrderErrorTypeMapper;
    private final WorkOrderWhiteMapper workOrderWhiteMapper;
    private final SysConfigMapper configMapper;
    private final ReportMapper reportMapper;
    private final WorkOrderCheckImgMapper workOrderCheckImgMapper;
    private final WorkOrderWhiteMapper workOrderWhiteMapper;
    private final DeviceInfoMapper deviceInfoMapper;
    private final ApplicationContext applicationContext;
    @Value("${rtsp.server:http://127.0.0.1:7788}")
@@ -124,19 +118,12 @@
    }
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchAddWorkOrder(List<WorkOrder> workOrderList){
    public Boolean batchAddWorkOrder(List<WorkOrder> workOrderList) {
        int total = workOrderList.size();
        // 查询出白名单列表
        List<String> serialNumbers = workOrderWhiteMapper.selectList().stream().map(WorkOrderWhite::getSerialNumber).collect(Collectors.toList());
        // 遍历工单列表,判断是否在白名单中
        workOrderList = workOrderList.stream().filter(item -> !serialNumbers.contains(item.getSerialNumber()))
                .collect(Collectors.toList());
        //清理数据
        workOrderList = workOrderList.stream().filter(item -> {
            return StringUtils.hasText(item.getSerialNumber()) && Objects.nonNull(item.getStatus()) && !CollectionUtils.isEmpty(item.getErrorTypeList());
        }).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workOrderList)) {
            return Boolean.TRUE;
        }
        // 根据国标码去重
        workOrderList = workOrderList.stream()
                .collect(Collectors.toMap(
@@ -144,6 +131,12 @@
                        p -> p,
                        (existing, replacement) -> existing // 冲突时保留第一个
                )).values().stream().collect(Collectors.toList());
        //检查白名单
        workOrderList = checkWhite(workOrderList);
        if (CollectionUtils.isEmpty(workOrderList)) {
            return Boolean.TRUE;
        }
        List<String> serialNumberList = workOrderList.stream().map(WorkOrder::getSerialNumber).collect(Collectors.toList());
        // 查出数据库中国标码对应的未完成的工单
        List<WorkOrder> inDatabaseWorkOrderList = baseMapper.getNotFinishedWorkOrders(serialNumberList);
@@ -186,7 +179,7 @@
                        }
                    }
                    //避免代下发的工单直接变成下发
                    if(!databaseWorkOrder.getStatus().equals(WorkOrderStatusEnum.WAIT_DISTRIBUTE)) {
                    if (!databaseWorkOrder.getStatus().equals(WorkOrderStatusEnum.WAIT_DISTRIBUTE)) {
                        databaseWorkOrder.setStatus(WorkOrderStatusEnum.DISTRIBUTED);
                    }
                    databaseWorkOrder.setUpdateTime(now);
@@ -297,7 +290,7 @@
                workOrderErrorType.setErrorName(errorType);
                waitAddErrorTypeList.add(workOrderErrorType);
            }
            log.info("即将生成的工单:{}",workOrder);
            log.info("即将生成的工单:{}", workOrder);
        }
        redisCache.setCacheObject(RedisConstant.WORKORDER_NUM, workOrderNum);
        redisCache.releaseLock(RedisConstant.WORKORDER_NUM_LOCK, requestId);
@@ -326,6 +319,8 @@
        log.info("传入工单总数: {},实际添加工单数:{}, 实际修改工单数:{}", total, waitAddList.size(), updateNum);
        return Boolean.TRUE;
    }
    /**
     * 添加
     *
@@ -334,6 +329,16 @@
     */
    @Override
    public Result add(WorkOrderForm form) {
        //检查白名单
        List<WorkOrder> data = new ArrayList<>();
        WorkOrder workOrder = WorkOrderForm.getEntityByForm(form, null);
        data.add(workOrder);
        data = checkWhite(data);
        if (CollectionUtils.isEmpty(data)) {
            return Result.error("该设备的故障类型在白名单中,不能添加工单");
        }
        WorkOrder entity = data.get(0);
        //查redis今日工单数量
        int workOrderNum = 0;
        //UUID作为value,保证上锁的线程自己解锁
@@ -349,28 +354,22 @@
        } else {
            return Result.error("工单正在添加,请稍后再试");
        }
        WorkOrder entity = WorkOrderForm.getEntityByForm(form, null);
        // 查询出白名单列表
        List<String> serialNumbers = workOrderWhiteMapper.selectList().stream().map(WorkOrderWhite::getSerialNumber).collect(Collectors.toList());
        // 遍历工单列表,判断是否在白名单中
         if (serialNumbers.contains(entity.getSerialNumber())){
            return Result.error("该设备在白名单中,不能添加工单");
        }else {
            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("添加失败");
        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("添加失败");
    }
    /**
     * 修改
@@ -503,7 +502,7 @@
        // 国标设备的编码就是取视频流的设备编码,国标设备就一个。国标设备的每一个通道代表一个摄像头,也就是设备id是取流的通道id
        String frameImg = null;
        try {
            log.info("国标平台:{},设备编码:{},工单号:{}",gbDevices.get(0).getDeviceId(), workOrder.getSerialNumber(), workOrder.getWorkOrderNo());
            log.info("国标平台:{},设备编码:{},工单号:{}", gbDevices.get(0).getDeviceId(), workOrder.getSerialNumber(), workOrder.getWorkOrderNo());
            frameImg = this.getFrameImgByDevice(gbDevices.get(0).getDeviceId(), workOrder.getSerialNumber(), workOrder.getWorkOrderNo());
        } catch (Exception e) {
            e.printStackTrace();
@@ -516,11 +515,12 @@
            workOrderCheckImgMapper.insert(img);
        }
    }
    @Override
    public List<WorkOrderYwConditionRecordVO> selectYwConditionByYwId(String workOrderNo) {
        List<WorkOrderYwConditionRecordVO> ywConditionList = workOrderYwConditionRecordMapper.selectYwConditionByYwId(workOrderNo);
        ywConditionList.stream().forEach(item -> {
            if(item.getUserId().equals(1)){
            if (item.getUserId().equals(1)) {
                item.setUnitName("管理员");
            }
            if (Objects.nonNull(item.getSysMsg()) && item.getSysMsg()) {
@@ -598,11 +598,11 @@
    @Override
    public Result page(WorkOrderQuery query) {
        IPage<WorkOrderVO> page = PageUtil.getPage(query, WorkOrderVO.class);
        if(query.getUnitId()==null) {
        if (query.getUnitId() == null) {
            query.setUnitId(SecurityUtils.getUnitId());
        }
        if(query.getStart()!=null) query.setStart(DateUtils.getDayStart(query.getStart()));
        if(query.getEnd()!=null) query.setEnd(DateUtils.getDayEnd(query.getEnd()));
        if (query.getStart() != null) query.setStart(DateUtils.getDayStart(query.getStart()));
        if (query.getEnd() != null) query.setEnd(DateUtils.getDayEnd(query.getEnd()));
        baseMapper.page(page, query);
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            page.getRecords().stream().forEach(item -> {
@@ -631,8 +631,8 @@
    @Override
    public Result distributePage(DistributeWorkOrderQuery query) {
        IPage<WorkOrderVO> page = PageUtil.getPage(query, WorkOrderVO.class);
        if(query.getStart()!=null) query.setStart(DateUtils.getDayStart(query.getStart()));
        if(query.getEnd()!=null) query.setEnd(DateUtils.getDayEnd(query.getEnd()));
        if (query.getStart() != null) query.setStart(DateUtils.getDayStart(query.getStart()));
        if (query.getEnd() != null) query.setEnd(DateUtils.getDayEnd(query.getEnd()));
        baseMapper.distributePage(page, query);
        return Result.ok().data(page).total(page.getTotal());
    }
@@ -860,11 +860,11 @@
    @Override
    public String getFrameImgByDevice(String deviceId, String channelId, String workOrderNo) throws Exception {
        String url = String.format(this.rtspServer + "/api/play/start/img/%s/%s", deviceId, channelId);
        log.info("访问路径{}",url);
        log.info("访问路径{}", url);
        String result = HttpUtils.sendGet(url);
        log.info("拿到取流图片响应结果:" + result);
        WVPResult wvpResult = JSON.parseObject(result, WVPResult.class);
        if(wvpResult.getCode() == 0) {
        if (wvpResult.getCode() == 0) {
            Object imgUrl = (Object) wvpResult.getData();
            imgUrl = Objects.isNull(imgUrl) ? "" : imgUrl;
            log.info("拿到取流图片:" + imgUrl);
@@ -921,7 +921,7 @@
    }
    @Override
    public void saveFrameImgByDevice (String deviceId, String channelId, String workOrderNo){
    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);
@@ -982,13 +982,13 @@
    }
    @Override
    public List<DeviceInfoVO> hasErrorWorkOrderList (Date start, Date end){
    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){
    public void updateImgById(Integer workOrderId, String imgPath) {
        new LambdaUpdateChainWrapper<>(baseMapper)
                .eq(WorkOrder::getId, workOrderId)
                .set(WorkOrder::getYwCheckResult, imgPath)
@@ -996,7 +996,7 @@
    }
    @Override
    public Result processImg (String workOrderNo){
    public Result processImg(String workOrderNo) {
        WorkOrder workOrder = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(WorkOrder::getWorkOrderNo, workOrderNo)
                .one();
@@ -1037,7 +1037,7 @@
    }
    @Override
    public Result detailByNo (String workOrderNo){
    public Result detailByNo(String workOrderNo) {
        WorkOrderDetailVO workOrder = baseMapper.detailByNo(workOrderNo);
        // 是否报备
        boolean hasReport = new LambdaQueryChainWrapper<>(reportMapper)
@@ -1059,8 +1059,8 @@
    }
    @Override
    public List<WorkOrderVO> export (WorkOrderExportQuery query){
        if(query.getUnitId()==null) {
    public List<WorkOrderVO> export(WorkOrderExportQuery query) {
        if (query.getUnitId() == null) {
            query.setUnitId(SecurityUtils.getUnitId());
        }
        if (query.getStart() != null) query.setStart(query.getStart() + " 00:00:00");
@@ -1070,87 +1070,13 @@
    }
    /**
     * 工单白名单列表
     *
     * @param query 查询
     * @return {@link List }<{@link WorkOrderWhite }>
     * @author
     */
    @Override
    public Result selectWorkOrderWhiteList(WorkOrderWhiteQuery query) {
        IPage<WorkOrderWhite> page = PageUtil.getPage(query, WorkOrderWhite.class);
        workOrderWhiteMapper.page(page, query);
        return Result.ok().data(page.getRecords()).total(page.getTotal());
    }
    /**
     * 添加工单白名单
     *
     * @param workOrderWhite 白色工单
     * @return {@link Result }
     * @author
     */
    @Override
    public Result addWorkOrderWhite(WorkOrderWhite workOrderWhite) {
        // 通过设备编码查询设备信息
        YwPoint ywPoint = ywPointService.selectBySerialNumber(workOrderWhite.getSerialNumber());
        // 新增白名单设备记录
        if (ywPoint == null){
            return Result.error("设备不存在");
        }
        // 检查是否已经存在该白名单
        WorkOrderWhite flag = workOrderWhiteMapper.selectBySerialNumber(workOrderWhite.getSerialNumber());
        if (flag != null) {
            return Result.error("该设备已存在白名单");
        } else {
            workOrderWhite.setPointName(ywPoint.getPointName());
            workOrderWhite.setCreateBy(SecurityUtils.getUsername());
            workOrderWhiteMapper.insert(workOrderWhite);
            return Result.ok();
        }
    }
    /**
     * 批量删除工单白名单
     *
     * @param ids ids
     * @author
     */
    @Override
    public Result batchDeleteWorkOrderWhite(List<String> ids) {
        workOrderWhiteMapper.batchDelete(ids);
        return Result.ok();
    }
    /**
     * 批量导入白名单
     *
     * @param dataList 数据列表
     * @author
     */
    @Override
    public void batchImportWhite(List<PointExport> dataList) {
        // 获得所有需要新增的白名单对象
        List<WorkOrderWhite> whitelist = dataList.stream().map(pointExport ->
                        new WorkOrderWhite(pointExport.getSerialNumber(), pointExport.getPointName(), SecurityUtils.getUsername()))
                .collect(Collectors.toList());
        // 获得所有已存在的白名单设备编码
        List<String> serialNumbers = workOrderWhiteMapper.selectList().stream().map(WorkOrderWhite::getSerialNumber).collect(Collectors.toList());
        // 筛选出新增、修改的白名单对象
        List<WorkOrderWhite> updateWhiteList = whitelist.stream().filter(white -> serialNumbers.contains(white.getSerialNumber())).collect(Collectors.toList());
        List<WorkOrderWhite> insertWhiteList = whitelist.stream().filter(white ->!serialNumbers.contains(white.getSerialNumber())).collect(Collectors.toList());
        // 新增/修改白名单设备记录
        updateWhiteList.stream().forEach(white -> workOrderWhiteMapper.updateBySerialNumber(white));
        insertWhiteList.stream().forEach(white -> workOrderWhiteMapper.insert(white));
    }
    /**
     * 检测工单按钮
     *
     * @param workOrderNo
     * @return
     */
    @Override
    public Result checkImage(String workOrderNo,String serialNumber) {
    public Result checkImage(String workOrderNo, String serialNumber) {
        // 查出国标设备,就一条数据
        List<DeviceInfo> gbDevices = new LambdaQueryChainWrapper<>(deviceInfoMapper)
                .orderByDesc(DeviceInfo::getUpdateTime)
@@ -1158,7 +1084,7 @@
                .list();
        if (!CollectionUtils.isEmpty(gbDevices)) {
            try {
                String imgUrl = this.getFrameImgByDevice(gbDevices.get(0).getDeviceId(), serialNumber,workOrderNo);
                String imgUrl = this.getFrameImgByDevice(gbDevices.get(0).getDeviceId(), serialNumber, workOrderNo);
                if (StringUtils.hasText(imgUrl)) {
                    WorkOrderCheckImg img = new WorkOrderCheckImg();
                    img.setWorkOrderNo(workOrderNo);
@@ -1177,7 +1103,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result batchDeleteWorkOrder(List<String> workOrderNos) {
        if(!CollectionUtils.isEmpty(workOrderNos)) {
        if (!CollectionUtils.isEmpty(workOrderNos)) {
            //删除工单审核记录
            workOrderAuditingRecordMapper.delete(new QueryWrapper<WorkOrderAuditingRecord>().in("work_order_no", workOrderNos));
            //删除工单图片记录
@@ -1242,4 +1168,24 @@
        results.add(face);
        return Result.ok().data(results);
    }
    //白名单校验
    private List<WorkOrder> checkWhite(List<WorkOrder> workOrderList) {
        // 查询出白名单列表
        Map<String, WorkOrderWhite> whiteMap = workOrderWhiteMapper.selectList().stream().collect(Collectors.toMap(WorkOrderWhite::getSerialNumber, Function.identity()));
        workOrderList = workOrderList.stream()
                .filter(workOrder -> {
                    List<String> errorTypeList = workOrder.getErrorTypeList();
                    WorkOrderWhite white = whiteMap.get(workOrder.getSerialNumber());
                    if (white != null) {
                        List<String> whiteErrorListSet = Arrays.asList(white.getErrorType().split(","));
                        errorTypeList.removeIf(whiteErrorListSet::contains);
                    }
                    return !errorTypeList.isEmpty(); // 只保留 errorTypeList 非空的 WorkOrder
                })
                .collect(Collectors.toList());
        return workOrderList;
    }
}