zxl
2025-10-29 fea22e82e7e49691f6e0c20a29b228d0ab3173e9
ycl-server/src/main/java/com/ycl/task/DemeritRecordTask.java
@@ -5,9 +5,11 @@
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.google.common.util.concurrent.AtomicDouble;
import com.ycl.platform.domain.entity.DemeritRecord;
import com.ycl.platform.domain.entity.MonitorConstruction;
import com.ycl.platform.domain.entity.Report;
import com.ycl.platform.domain.result.UY.RecordMetaDSumResult;
import com.ycl.platform.mapper.DemeritRecordMapper;
import com.ycl.platform.mapper.IMonitorConstructionMapper;
import com.ycl.platform.mapper.ReportMapper;
import com.ycl.platform.service.IDemeritRecordService;
import com.ycl.utils.DateUtils;
@@ -50,6 +52,8 @@
    private final ReportMapper reportMapper;
    private final IMonitorConstructionMapper monitorConstructionMapper;
    private static final ExecutorService executorService = new ThreadPoolExecutor(16,
            128,
            5000,
@@ -59,21 +63,12 @@
    );
    private final IDemeritRecordService demeritRecordService;
    // 提取公共过滤方法
    private Predicate<RecordMetaDSumResult> deviceNameStartsWith(String prefix) {
        return result -> result.getDeviceName() != null && result.getDeviceName().startsWith(prefix);
    }
    private Predicate<RecordMetaDSumResult> deviceNameStartsWithAny(String... prefixes) {
        return result -> result.getDeviceName() != null &&
                Arrays.stream(prefixes).anyMatch(prefix -> result.getDeviceName().startsWith(prefix));
    }
    private DemeritRecord buildDemeritRecord(String constructionType,BigDecimal demerit,Integer deptId) {
    private DemeritRecord buildDemeritRecord(String constructionType,BigDecimal demerit,Integer deptId,Date recordTime) {
        DemeritRecord record = new DemeritRecord();
        record.setConstructionType(constructionType);
        record.setDemerit(demerit);
        record.setDeptId(deptId);
        record.setRecordTime(recordTime);
        return record;
    }
    private BigDecimal calculateTotalDeduction(List<RecordMetaDSumResult> records) {
@@ -126,7 +121,7 @@
        log.info("日期:{},查询出的设备录像记录数{}",today,results.size());
        //过滤掉非全景的设备 且 1则为细节,如果是0则为全景
        results.stream().filter(obj ->
        results = results.stream().filter(obj ->
        {
            String deviceId = obj.getDeviceId();
            if (deviceId == null || deviceId.length() < 7) {
@@ -135,7 +130,7 @@
            // 获取倒数第七位的字符
            char seventhFromEnd = deviceId.charAt(deviceId.length() - 7);
            return seventhFromEnd != '1'; //为1 则会 false 去除掉
        });
        }).collect(Collectors.toList());
        log.info("过滤后剩余全景设备数{}",results.size());
        //只考核LT_、(三期)
@@ -143,28 +138,43 @@
        // DX_R、(四区人脸)
        // DX_RS、(四区人脸)
        // (需要排除DX_R2、DX_RD、J_、T1、T3以及没有前缀的设备)
        List<String> prefixes = Arrays.asList("LT_", "DX_", "DX_R", "DX_RS");
        results.stream()
//        List<String> prefixes = Arrays.asList("LT_", "DX_", "DX_R", "DX_RS");
        //查询设备标签表中的MonitorConstruction列表
        List<MonitorConstruction> monitorConstructionList = new LambdaQueryChainWrapper<>(monitorConstructionMapper)
                .eq(MonitorConstruction::getDeleted, Boolean.FALSE)
                .list();
        List<String> serialNumberList = monitorConstructionList.stream()
                .map(MonitorConstruction::getSerialNumber).collect(Collectors.toList());
        //过滤获得包含了这些标签的设备录像情况集合
        results = results.stream()
                .filter(result -> {
                    String deviceName = result.getDeviceName();
                    if (deviceName == null) {
                        return false;
                    }
                    return prefixes.stream().anyMatch(deviceName::startsWith);
                    String sn = result.getNo();
                    // 任一字段非空且在集合中即可
                    return (sn != null && serialNumberList.contains(sn));
                })
                .collect(Collectors.toList());
        log.info("剩余考核设备过滤后设备数{}",results.size());
        //过滤掉报备的设备
        //查询在当前时间有报备的所有设备,
        //因为录像数据的时间
        List<String> deviceIds = new LambdaQueryChainWrapper<>(reportMapper)
        Date yesterday =new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(yesterday);
        calendar.add(Calendar.DAY_OF_YEAR, -1); // 减去1天 测试用
        yesterday = calendar.getTime();
        log.info("测试时间:{}",yesterday);
        List<Report> list = new LambdaQueryChainWrapper<>(reportMapper)
                .eq(Report::getStatus, 1)
                .ge(Report::getBeginCreateTime, today)
                .le(Report::getEndCreateTime, today)
                .list().stream()
                .ge(Report::getBeginCreateTime, DateUtils.getDayStart(yesterday))
                .le(Report::getEndCreateTime,  DateUtils.getDayEnd(yesterday))
                .list();
        log.info("报备记录:{}",list);
        List<String> deviceIds = list.stream()
                .collect(Collectors.toMap(
                        Report::getSerialNumber,  // key: serialNumber
                        Function.identity(),      // value: Report对象本身
@@ -177,7 +187,7 @@
        Set<String> deviceIdSet = new HashSet<>(deviceIds);
        log.info("报备设备数{}",deviceIdSet.size());
        results.stream()
        results = results.stream()
                .filter(result -> {
                    // 获取当前对象的deviceId
                    String resultDeviceId = result.getDeviceId();
@@ -202,6 +212,24 @@
        Map<String,List<RecordMetaDSumResult>> groupByArealayerno = results.stream()
                .collect(Collectors.groupingBy(RecordMetaDSumResult::getArealayerno));
        //按建设类型标签分组设备NO monitorConstructionList
        //按标签分组
        Map<String, List<String>> groupByTag = monitorConstructionList.stream()
                // 分组键:提取每个对象的 tag(注意处理 tag 为 null 的情况,避免键为 null)
                .collect(Collectors.groupingBy(
                        mc -> mc.getTag() != null ? mc.getTag() : "DEFAULT_TAG",
                        Collectors.mapping(MonitorConstruction::getSerialNumber, Collectors.toList())
                ));
        List<String> phaseOneTwoSerials = groupByTag.getOrDefault(ConstructionTypeEnum.PHASE_ONE_TWO.getDesc(), Collections.emptyList());
        List<String> phaseThreeSerials = groupByTag.getOrDefault(ConstructionTypeEnum.PHASE_THREE.getDesc(), Collections.emptyList());
        List<String> phaseFourthSerials = groupByTag.getOrDefault(ConstructionTypeEnum.PHASE_FOURTH.getDesc(), Collections.emptyList());
        List<String> checkEnterSichuan = groupByTag.getOrDefault(ConstructionTypeEnum.CHECK_ENTER_SICHUAN.getDesc(), Collections.emptyList());
        List<String> easternNewCity= groupByTag.getOrDefault(ConstructionTypeEnum.EASTERN_NEW_CITY.getDesc(), Collections.emptyList());
        List<String> yanTanPhaseTwoFace = groupByTag.getOrDefault(ConstructionTypeEnum.YAN_TAN_PHASE_TWO_FACE.getDesc(), Collections.emptyList());
        //循环分组后的map
        for (Map.Entry<String, List<RecordMetaDSumResult>> entry : groupByArealayerno.entrySet()) {
            String arealayerno = entry.getKey();
@@ -218,65 +246,62 @@
            if (CollectionUtils.isNotEmpty(resultList)) {
                // 对每个List进行处理 分建类型处理集合
                List<RecordMetaDSumResult> phase_one_two = resultList.stream()
                        .filter(deviceNameStartsWith("DX_"))
                        .filter(result -> {
                            String no = result.getNo();
                            return no != null && phaseOneTwoSerials.contains(no);
                        })
                        .collect(Collectors.toList());
                log.info("一二期考核记录数{}",phase_one_two.size());
                log.info("一二期考核记录数{}", phase_one_two.size());
                List<RecordMetaDSumResult> phase_three = resultList.stream()
                        .filter(deviceNameStartsWith("LT_"))
                        .filter(result -> {
                            String no = result.getNo();
                            return no != null && phaseThreeSerials.contains(no);
                        })
                        .collect(Collectors.toList());
                log.info("三期考核记录数{}",phase_three.size());
                log.info("三期考核记录数{}", phase_three.size());
                List<RecordMetaDSumResult> phase_fourth = resultList.stream()
                        .filter(deviceNameStartsWithAny("DX_R", "DX_RS"))
                        .filter(result -> {
                            String no = result.getNo();
                            return no != null && phaseFourthSerials.contains(no);
                        })
                        .collect(Collectors.toList());
                log.info("四期考核记录数{}",phase_fourth.size());
                if (CollectionUtils.isNotEmpty(phase_one_two)){
                    BigDecimal phaseOneTwoDeduction = calculateTotalDeduction(phase_one_two);
                    DemeritRecord demeritRecordPhaseOneTwo = buildDemeritRecord(
                            ConstructionTypeEnum.PHASE_ONE_TWO.name(),
                            phaseOneTwoDeduction,
                            areaDeptEnum.getDeptId());
                    demeritRecords.add(demeritRecordPhaseOneTwo);
                }else{
                    DemeritRecord phaseOneTwoDeduction = buildDemeritRecord(
                            ConstructionTypeEnum.PHASE_ONE_TWO.name(),
                            BigDecimal.ZERO,
                            areaDeptEnum.getDeptId());
                    demeritRecords.add(phaseOneTwoDeduction);
                }
                log.info("四期考核记录数{}", phase_fourth.size());
                List<RecordMetaDSumResult> check_enter_sichuan = resultList.stream()
                        .filter(result ->{
                            String no = result.getNo();
                            return  no != null && checkEnterSichuan.contains(no);
                        })
                        .collect(Collectors.toList());
                log.info("入川即检{}", check_enter_sichuan.size());
                if (CollectionUtils.isNotEmpty(phase_three)){
                    BigDecimal phaseThreeDeduction = calculateTotalDeduction(phase_three);
                    DemeritRecord demeritRecordPhaseThree = buildDemeritRecord(
                            ConstructionTypeEnum.PHASE_THREE.name(),
                            phaseThreeDeduction,
                            areaDeptEnum.getDeptId());
                    demeritRecords.add(demeritRecordPhaseThree);
                }else {
                    DemeritRecord phaseThreeDeduction = buildDemeritRecord(
                            ConstructionTypeEnum.PHASE_THREE.name(),
                            BigDecimal.ZERO,
                            areaDeptEnum.getDeptId());
                    demeritRecords.add(phaseThreeDeduction);
                }
                if (CollectionUtils.isNotEmpty(phase_fourth)){
                    BigDecimal phaseFourthDeduction = calculateTotalDeduction(phase_fourth);
                    DemeritRecord demeritRecordPhaseFourth = buildDemeritRecord(
                            ConstructionTypeEnum.PHASE_FOURTH.name(),
                            phaseFourthDeduction,
                            areaDeptEnum.getDeptId());
                    demeritRecords.add(demeritRecordPhaseFourth);
                }else{
                    DemeritRecord phaseFourthDeduction = buildDemeritRecord(
                            ConstructionTypeEnum.PHASE_FOURTH.name(),
                            BigDecimal.ZERO,
                            areaDeptEnum.getDeptId());
                    demeritRecords.add(phaseFourthDeduction);
                }
                List<RecordMetaDSumResult> eastern_new_city = resultList.stream()
                        .filter(result ->{
                            String no = result.getNo();
                            return  no != null && easternNewCity.contains(no);
                        })
                        .collect(Collectors.toList());
                log.info("东部新城{}", eastern_new_city.size());
                List<RecordMetaDSumResult> yan_tan_phase_two_face = resultList.stream()
                        .filter(result ->{
                            String no = result.getNo();
                            return  no != null && yanTanPhaseTwoFace.contains(no);
                        })
                        .collect(Collectors.toList());
                log.info("沿滩二期人脸{}", yan_tan_phase_two_face.size());
                //一二期
                buildAndAddDemeritRecords(phase_one_two, ConstructionTypeEnum.PHASE_ONE_TWO.name(), areaDeptEnum.getDeptId(),yesterday,demeritRecords);
                //三期
                buildAndAddDemeritRecords(phase_three, ConstructionTypeEnum.PHASE_THREE.name(), areaDeptEnum.getDeptId(),yesterday,demeritRecords);
                //四期
                buildAndAddDemeritRecords(phase_fourth, ConstructionTypeEnum.PHASE_FOURTH.name(), areaDeptEnum.getDeptId(),yesterday,demeritRecords);
                //入川即检
                buildAndAddDemeritRecords(check_enter_sichuan, ConstructionTypeEnum.CHECK_ENTER_SICHUAN.name(), areaDeptEnum.getDeptId(),yesterday,demeritRecords);
                //东部新城
                buildAndAddDemeritRecords(eastern_new_city, ConstructionTypeEnum.EASTERN_NEW_CITY.name(), areaDeptEnum.getDeptId(),yesterday,demeritRecords);
                //沿滩二期人脸
                buildAndAddDemeritRecords(yan_tan_phase_two_face, ConstructionTypeEnum.YAN_TAN_PHASE_TWO_FACE.name(), areaDeptEnum.getDeptId(),yesterday,demeritRecords);
            }
        }
@@ -292,4 +317,25 @@
        log.info("结束计算每日扣分记录情况:插入数据量{},数据信息:{}",demeritRecords.size(),demeritRecords);
    }
    public void buildAndAddDemeritRecords(List<RecordMetaDSumResult> constructionByRecordMetaList,
                                          String constructionType,Integer areaDeptId,Date recordTime,
                                          List<DemeritRecord> demeritRecords) {
        if (CollectionUtils.isNotEmpty(constructionByRecordMetaList)) {
                    BigDecimal deduction = calculateTotalDeduction(constructionByRecordMetaList);
                    DemeritRecord demeritRecord = buildDemeritRecord(
                            constructionType,
                            deduction,
                            areaDeptId,
                            DateUtils.getDayStart(recordTime));
                    demeritRecords.add(demeritRecord);
                }else{
                    DemeritRecord demeritRecord = buildDemeritRecord(
                            constructionType,
                            BigDecimal.ZERO,
                            areaDeptId,
                            DateUtils.getDayStart(recordTime));
                    demeritRecords.add(demeritRecord);
        }
    }
}