fuliqi
2025-01-16 23302186a81c1b6f3e5f398f21b057350bfd34e8
ycl-server/src/main/java/com/ycl/task/ContractTask.java
@@ -120,7 +120,6 @@
    //月底计算在线率分数
    public void calculateOnlineScore() {
        //TODO:检查表
        log.info("开始计算合同点位在线率分数");
        //月底需要统计平均在线率然后进行积分扣除
        String mouthStart = DateUtils.getMouthStart(new Date());
@@ -179,7 +178,7 @@
                .collect(Collectors.groupingBy(
                        CalculateRuleVO::getRuleName,  // 按规则名称分组
                        Collectors.groupingBy(
                                CalculateRuleVO::getContractId // 每个规则名称内部再按合同ID分组,value为规则集合
                                CalculateRuleVO::getContractId // 每个规则名称内部再按合同ID分组,value为规则集合(多个合同情况)
                        )
                ));
        //前端感知源治理工作(时钟同步规则、OSD规则、一机一档规则) 获取key为合同id,value为规则的map
@@ -195,12 +194,38 @@
        LocalDateTime endTime = LocalDateTime.now();
        // 计算30天前的日期
        LocalDateTime startTime = endTime.minusDays(30);
        List<WorkOrderVO> workOrders = workOrderMapper.selectPassOrder(startTime, endTime, WorkOrderStatusEnum.AUDITING_SUCCESS.getValue(), "审核通过");
        //自动扣分的工单故障类型
        List<String> deductErrorType = new ArrayList<>();
        deductErrorType.add(ErrorType.OSD_ERROR.getValue());
        deductErrorType.add(ErrorType.ABNORMAL_PIC.getValue());
        deductErrorType.add(ErrorType.POINT_INFO_ERROR.getValue());
        deductErrorType.add(ErrorType.CLOCK_SKEW.getValue());
        List<WorkOrderVO> workOrders = workOrderMapper.selectPassOrder(startTime, endTime, WorkOrderStatusEnum.AUDITING_SUCCESS.getValue(),deductErrorType);
        //存在有两种扣分的故障 只扣减第一个故障
        Map<String, WorkOrderVO> map = workOrders.stream()
                .collect(Collectors.toMap(
                        WorkOrderVO::getWorkOrderNo,
                        Function.identity(),
                        (older, newer) -> older.getDistributeTime().compareTo(newer.getDistributeTime()) <= 0 ? older : newer
                ));
        workOrders = new ArrayList<>(map.values());
        List<String> workOrderNos = workOrders.stream().map(WorkOrderVO::getWorkOrderNo).collect(Collectors.toList());
        List<WorkOrderVO> auditTimeList = workOrderMapper.getAuditTimeList(workOrderNos);
        Map<String, List<Date>> auditTimeMap = auditTimeList.stream()
                .collect(Collectors.groupingBy(
                        WorkOrderVO::getWorkOrderNo, // 分组的键
                        Collectors.mapping(WorkOrderVO::getAuditTime, Collectors.toList())));
        List<WorkOrderVO> handleTimeList = workOrderMapper.getHandleTimeList(workOrderNos);
        Map<String, List<Date>> handleTimeMap = handleTimeList.stream()
                .collect(Collectors.groupingBy(
                        WorkOrderVO::getWorkOrderNo, // 分组的键
                        Collectors.mapping(WorkOrderVO::getHandleTime, Collectors.toList())));
        for (WorkOrderVO workOrder : workOrders) {
            //检测是否报备过
            if (!CollectionUtils.isEmpty(reportNumbers)) {
                if (reportNumbers.contains(workOrder.getSerialNumber())) continue;
            }
//            if(!WorkOrderStatusEnum.AUDITING_SUCCESS.equals(workOrder.getStatus())) continue;
            String errorType = workOrder.getErrorType();
            //存储故障 录像或图片访问异常 (改成手动打分了)
//            if (ErrorType.VIDEO_NONE.getValue().equals(errorType) || ErrorType.PIC_URLABNORMAL.getValue().equals(errorType)) {
@@ -227,7 +252,7 @@
//                }
//            }
            //前端感知源治理工作(时钟同步规则、OSD规则、一机一档规则)
            if (ErrorType.OSD_ERROR.getValue().equals(errorType) || ErrorType.CLOCK_SKEW.getValue().equals(errorType) || ErrorType.CLOCK_RIGHT.getValue().equals(errorType)) {
            if (ErrorType.OSD_ERROR.getValue().equals(errorType) || ErrorType.CLOCK_SKEW.getValue().equals(errorType) || ErrorType.POINT_INFO_ERROR.getValue().equals(errorType)) {
                if (!CollectionUtils.isEmpty(monitorRuleMap)) {
                    monitorRuleMap.forEach((contractId, rules) -> {
                        Integer unitId = rules.get(0).getUnitId();
@@ -235,10 +260,24 @@
                        if (workOrder.getUnitId().equals(unitId)) {
                            //工单下发时间
                            Date createTime = workOrder.getDistributeTime();
                            Date auditTime = workOrder.getAuditTime();
                            double diffTime = (double) (auditTime.getTime() - createTime.getTime()) / (1000 * 60 * 60);
                            //选择时间范围内的规则
                            List<Date> auditTimes = auditTimeMap.get(workOrder.getWorkOrderNo());
                            List<Date> handleTimes = handleTimeMap.get(workOrder.getWorkOrderNo());
                            //拿到审核时间
                            long auditDuration = getAuditDuration(auditTimes, handleTimes);
                            //审核通过时间
                            Date passTime = Collections.max(auditTimes);
                            //处理花费总时长
                            double diffTime = (double) (passTime.getTime() - createTime.getTime() - auditDuration) / (1000 * 60 * 60);
                            //找到对应规则、选择时间范围内的规则
                            for (CalculateRuleVO rule : rules) {
                                if(ErrorType.OSD_ERROR.getValue().equals(errorType)){
                                    if(!rule.getRuleCondition().equals("OSD标识")) continue;
                                }else if(ErrorType.CLOCK_SKEW.getValue().equals(errorType)){
                                    if(!rule.getRuleCondition().equals("时钟同步")) continue;
                                }else if( ErrorType.POINT_INFO_ERROR.getValue().equals(errorType)){
                                    if(!rule.getRuleCondition().equals("一机一档")) continue;
                                }
                                if (checkRange(rule.getMin(), rule.getMax(), new BigDecimal(diffTime))) {
                                    double deductScore = rule.getCalcFraction();
                                    ContractScore contractScore = getContractScore(rule, deductScore, Math.round(diffTime * 100) / 100 + "", Remark + "工单编号为:" + workOrder.getWorkOrderNo() + "处理超时,扣除" + deductScore + "分");
@@ -251,7 +290,7 @@
                }
            }
            //点位异常情况处理(镜头异常、摄像头遮挡等)
            if (ErrorType.SCREEN_OCCLUSION.getValue().equals(errorType)) {
            if (ErrorType.ABNORMAL_PIC.getValue().equals(errorType)) {
                if (!CollectionUtils.isEmpty(monitorRuleMap)) {
                    siteRuleMap.forEach((contractId, rules) -> {
                        Integer unitId = rules.get(0).getUnitId();
@@ -259,8 +298,13 @@
                        if (workOrder.getUnitId().equals(unitId)) {
                            //工单下发时间
                            Date createTime = workOrder.getDistributeTime();
                            Date auditTime = workOrder.getAuditTime();
                            double diffTime = (double) (auditTime.getTime() - createTime.getTime()) / (1000 * 60 * 60);
                            List<Date> auditTimes = auditTimeMap.get(workOrder.getWorkOrderNo());
                            List<Date> handleTimes = handleTimeMap.get(workOrder.getWorkOrderNo());
                            //拿到审核时间
                            long auditDuration = getAuditDuration(auditTimes, handleTimes);
                            //审核通过时间
                            Date passTime = Collections.max(auditTimes);
                            double diffTime = (double) (passTime.getTime() - createTime.getTime() -auditDuration) / (1000 * 60 * 60);
                            //选择时间范围内的规则
                            for (CalculateRuleVO rule : rules) {
                                if (checkRange(rule.getMin(), rule.getMax(), new BigDecimal(diffTime))) {
@@ -294,6 +338,27 @@
        log.info("结束执行工单扣分");
    }
    private long getAuditDuration(List<Date> auditTimes, List<Date> handleTimes) {
        //计算出审核的总时间(由于故障类型会更新导致可能提交的时间点数量和审核的时间点数量不一致)
        long auditDuration = 0;
        for (Date auditTime : auditTimes) {
            //离这次审核最近的一次提交处理时间点
            Date nearestHandleTime = null;
            long minDifference = Long.MAX_VALUE;
            for (Date handleTime : handleTimes) {
                if(handleTime.before(auditTime)) {
                    long difference = Math.abs(auditTime.getTime() - handleTime.getTime());
                    if (difference < minDifference) {
                        minDifference = difference;
                        nearestHandleTime = handleTime;
                    }
                }
            }
            auditDuration += auditTime.getTime()-nearestHandleTime.getTime();
        }
        return auditDuration;
    }
    /**
     * 不定期检查数据 扣除积分
@@ -318,7 +383,7 @@
            List<ContractScore> contractScoreList = new ArrayList<>();
            //查询报备列表
            List<String> reportNumbers = reportMapper.selectNumberList(AuditStatus_Pass, DateUtils.getDate());
            Date date = DateUtils.getDay(2024, 7, 13);
            Date date = new Date();
            //查图片完整性规则 获取key为合同id,value为规则的map
            Map<Integer, List<CalculateRuleVO>> contractMap = contractMapper.getCalculateRule(new Date()).stream()
                    .filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_PicComplete.getName().equals(calculateRuleVO.getRuleName()))
@@ -398,8 +463,7 @@
            List<ContractScore> contractScoreList = new ArrayList<>();
            //查询报备列表
            List<String> reportNumbers = reportMapper.selectNumberList(AuditStatus_Pass, DateUtils.getDate());
            //TODO:测试日期
            Date date = DateUtils.getDay(2024, 7, 13);
            Date date = new Date();
            //查图片完整性规则 获取key为合同id,value为规则的map
            Map<Integer, List<CalculateRuleVO>> contractMap = contractMapper.getCalculateRule(new Date()).stream()
                    .filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_VideoRecord.getName().equals(calculateRuleVO.getRuleName()))