package com.ycl.task; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.mongodb.client.result.DeleteResult; import com.ycl.platform.domain.entity.*; import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult; import com.ycl.platform.domain.result.UY.VideoOnlineResult; import com.ycl.platform.domain.vo.CalculateRuleVO; import com.ycl.platform.domain.vo.ContractVO; import com.ycl.platform.domain.vo.ReportVO; import com.ycl.platform.mapper.*; import com.ycl.platform.service.IContractScoreService; import com.ycl.utils.DateUtils; import constant.ApiConstants; import constant.RedisConstant; import enumeration.ContractRule; import enumeration.general.AuditingStatus; import enumeration.general.RuleDeductCategoryEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.management.monitor.Monitor; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; /** * 合同考核定时任务 */ @Slf4j @Component("contractTask") public class ContractTask { @Autowired private MongoTemplate mongoTemplate; @Autowired private RedisTemplate redisTemplate; @Autowired private TMonitorMapper monitorMapper; @Autowired private TContractMapper contractMapper; @Autowired private YwPointMapper ywPointMapper; @Autowired private ReportMapper reportMapper; @Autowired private ContractRuleRecordMapper recordMapper; @Autowired private IContractScoreService contractScoreService; private static final Integer Online = 1; private static final Integer Offline = -1; private static final String AuditStatus_Pass = "1"; private static final String Remark = "系统生成"; /** * 合同考核 在线率每日任务检测 * 查生效的合同关联的公司,获取unitId集合 * 根据unitId查询对应点位获取各个公司管理的设备Ids * 查询三种设备在线不在线情况,封装为一个map<国标码,在线状态> * 计算每日每家公司的在线率存入mysql * 月底计算平均值,根据在线率和合同标准扣减分数 */ public void onlineCheck() { log.info("开始计算合同点位在线率"); List ruleVos = contractMapper.getCalculateRule(new Date()).stream() .filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_Online.getName().equals(calculateRuleVO.getRuleName())) .collect(Collectors.toList()); List unitIds = ruleVos.stream().map(CalculateRuleVO::getUnitId).collect(Collectors.toList()); List ywPoints = ywPointMapper.selectList(new QueryWrapper().in("unit_id", unitIds)); //key是unitId value是设备编码集合 Map> unitMap = ywPoints.stream() .collect(Collectors.groupingBy( YwPoint::getUnitId, Collectors.mapping( YwPoint::getSerialNumber, Collectors.toList() ) )); Map onlineStatusMap = new HashMap<>(); //查mongo获取设备在线情况 Date date = DateUtils.getDay(2024, 7, 13); //车辆、人脸 Query query = new Query(); query.addCriteria(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List results = mongoTemplate.find(query, SnapshotDataMonitorResult.class); for (SnapshotDataMonitorResult result : results) { if (ApiConstants.HK_SnapCount_ResultType_Null != result.getResultType()) { onlineStatusMap.put(result.getExternalIndexCode(), Online); } else { onlineStatusMap.put(result.getExternalIndexCode(), Offline); } } //视频 Query videoQuery = new Query(Criteria .where("mongoCreateTime").gte(DateUtils.getDayStart(date)).lt(DateUtils.getDayEnd(date))); List videoOnlineResults = mongoTemplate.find(videoQuery, VideoOnlineResult.class); for (VideoOnlineResult videoOnlineResult : videoOnlineResults) { onlineStatusMap.put(videoOnlineResult.getDeviceId(), videoOnlineResult.getStatus()); } //查询报备列表 List reportNumbers = reportMapper.selectNumberList(AuditStatus_Pass, DateUtils.getDate()); //计算每个公司的点位在线率 List ruleRecordList = new ArrayList<>(); unitMap.forEach((unitId, serialNumberList) -> { int totalSite = 0; int onlineSite = 0; for (String number : serialNumberList) { //报备过不纳入计算 if (!CollectionUtils.isEmpty(reportNumbers) && reportNumbers.contains(number)) continue; Integer status = onlineStatusMap.get(number); totalSite++; if (Online.equals(status)) { onlineSite++; } } BigDecimal online = new BigDecimal(onlineSite).divide(new BigDecimal(totalSite), 2, RoundingMode.DOWN); ContractRuleRecord contractRuleRecord = new ContractRuleRecord(); contractRuleRecord.setSiteOnline(online); contractRuleRecord.setCreateTime(new Date()); contractRuleRecord.setUnitId(unitId); ruleRecordList.add(contractRuleRecord); }); //存储结果 recordMapper.insertBatch(ruleRecordList); log.info("结束计算合同点位在线率"); } //月底计算在线率分数 public void calculateOnlineScore() { log.info("开始计算合同点位在线率分数"); //如果是月底,需要统计平均在线率然后进行积分扣除 // String now = DateUtils.getDate(); String mouthStart = DateUtils.getMouthStart(new Date()); String mouthEnd = DateUtils.getMouthEnd(new Date()); // if (now.equals(mouthEnd)) { //查一个月的记录 List ruleMonthRecords = recordMapper.selectMonth(mouthStart, mouthEnd); //通过unitId分单位 Map> unitMap = ruleMonthRecords.stream().collect(Collectors.groupingBy(ContractRuleRecord::getUnitId)); //查在线率规则 获取key为合同id,value为在线率规则的map Map> contractMap = contractMapper.getCalculateRule(new Date()).stream() .filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_Online.getName().equals(calculateRuleVO.getRuleName())) .collect(Collectors.groupingBy(CalculateRuleVO::getContractId)); //准备批量打分的集合 List contractScoreList = new ArrayList<>(); contractMap.forEach((contractId, ruleList) -> { //一个合同对应一个单位,因此unitId都相同 CalculateRuleVO calculateRuleVO = ruleList.get(0); Integer unitId = calculateRuleVO.getUnitId(); List ruleRecordList = unitMap.get(Long.parseLong(unitId + "")); if (!CollectionUtils.isEmpty(ruleMonthRecords)) { BigDecimal siteOnlineTotal = ruleRecordList.stream().map(ContractRuleRecord::getSiteOnline).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal siteOnline = siteOnlineTotal.divide(new BigDecimal(ruleRecordList.size()), 2, RoundingMode.DOWN); for (CalculateRuleVO ruleVO : ruleList) { Double max = ruleVO.getMax(); Double min = ruleVO.getMin(); //判断范围在哪个区间 if (checkRange(min, max, siteOnline.multiply(new BigDecimal(100)))) { //需要扣除的分数 Double deductScore = ruleVO.getCalcFraction(); ContractScore contractScore = new ContractScore(); contractScore.setContractId(Long.parseLong(contractId + "")); contractScore.setAuditingStatus(AuditingStatus.PASS); contractScore.setAuditingTime(new Date()); contractScore.setAuditingUser(Remark); contractScore.setUnitId(Long.parseLong(unitId + "")); contractScore.setRuleId(Long.parseLong(ruleVO.getId() + "")); contractScore.setRuleIds("0," + ruleVO.getId()); contractScore.setNum(siteOnline + ""); contractScore.setDeductCategory(ruleVO.getDeductCategory().getDesc()); contractScore.setScore(new BigDecimal(deductScore)); contractScore.setRuleName(ruleVO.getRuleName() + "/" + ruleVO.getRuleCondition()); contractScore.setCreateTime(new Date()); contractScore.setUpdateTime(new Date()); contractScore.setRemark(Remark); contractScoreList.add(contractScore); } } } }); // } contractScoreService.saveBatch(contractScoreList); log.info("结束计算合同点位在线率分数"); } private boolean checkRange(Double min, Double max, BigDecimal siteOnline) { if (siteOnline == null) { return false; } if (max != null && siteOnline.compareTo(new BigDecimal(max)) > 0) { return false; } if (min != null && siteOnline.compareTo(new BigDecimal(min)) < 0) { return false; } return true; } /** * 检测工单表 进行合同积分扣除 * 查出工单需要扣分的所有规则 * 查出未扣分且已经审核完成了的工单组成map> 工单需要连工单故障表查出多个故障类型 * 循环工单map,每个工单故障类型查对应的规则,根据规则和工单创建时间和审核通过时间进行扣分 * 插入合同积分表,修改工单状态为已扣分 */ public void workOrderDeduct() { //查询生效合同对应所有的规则 List calculateRules = contractMapper.getCalculateRule(new Date()); Map>> ruleMap = calculateRules.stream() .collect(Collectors.groupingBy( CalculateRuleVO::getRuleName, // 按规则名称分组 Collectors.groupingBy( CalculateRuleVO::getContractId // 每个规则名称内部再按合同ID分组,value为规则集合 ) )); //前端感知源治理工作(时钟同步规则、OSD规则、一机一档规则) 获取key为合同id,value为规则的map Map> monitorRuleMap = ruleMap.get(ContractRule.CONTRACT_RULE_Monitor.getName()); //存储故障(24小时以内,48小时以内) 获取key为合同id,value为规则的map Map> storeRuleMap = ruleMap.get(ContractRule.CONTRACT_RULE_Store.getName()); //点位异常情况处理 获取key为合同id,value为规则的map Map> siteRuleMap = ruleMap.get(ContractRule.CONTRACT_RULE_Site.getName()); } /** * 不定期检查数据 扣除积分 */ public void randomDeduct() { } }