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<CalculateRuleVO> ruleVos = contractMapper.getCalculateRule(new Date()).stream()
|
.filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_Online.getName().equals(calculateRuleVO.getRuleName()))
|
.collect(Collectors.toList());
|
List<Integer> unitIds = ruleVos.stream().map(CalculateRuleVO::getUnitId).collect(Collectors.toList());
|
List<YwPoint> ywPoints = ywPointMapper.selectList(new QueryWrapper<YwPoint>().in("unit_id", unitIds));
|
//key是unitId value是设备编码集合
|
Map<Long, List<String>> unitMap = ywPoints.stream()
|
.collect(Collectors.groupingBy(
|
YwPoint::getUnitId,
|
Collectors.mapping(
|
YwPoint::getSerialNumber,
|
Collectors.toList()
|
)
|
));
|
Map<String, Integer> 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<SnapshotDataMonitorResult> 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<VideoOnlineResult> videoOnlineResults = mongoTemplate.find(videoQuery, VideoOnlineResult.class);
|
for (VideoOnlineResult videoOnlineResult : videoOnlineResults) {
|
onlineStatusMap.put(videoOnlineResult.getDeviceId(), videoOnlineResult.getStatus());
|
}
|
//查询报备列表
|
List<String> reportNumbers = reportMapper.selectNumberList(AuditStatus_Pass, DateUtils.getDate());
|
//计算每个公司的点位在线率
|
List<ContractRuleRecord> 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<ContractRuleRecord> ruleMonthRecords = recordMapper.selectMonth(mouthStart, mouthEnd);
|
//通过unitId分单位
|
Map<Long, List<ContractRuleRecord>> unitMap = ruleMonthRecords.stream().collect(Collectors.groupingBy(ContractRuleRecord::getUnitId));
|
//查在线率规则 获取key为合同id,value为在线率规则的map
|
Map<Integer, List<CalculateRuleVO>> contractMap = contractMapper.getCalculateRule(new Date()).stream()
|
.filter(calculateRuleVO -> ContractRule.CONTRACT_RULE_Online.getName().equals(calculateRuleVO.getRuleName()))
|
.collect(Collectors.groupingBy(CalculateRuleVO::getContractId));
|
|
//准备批量打分的集合
|
List<ContractScore> contractScoreList = new ArrayList<>();
|
contractMap.forEach((contractId, ruleList) -> {
|
//一个合同对应一个单位,因此unitId都相同
|
CalculateRuleVO calculateRuleVO = ruleList.get(0);
|
Integer unitId = calculateRuleVO.getUnitId();
|
List<ContractRuleRecord> 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<unitId,List<WorkOrder>> 工单需要连工单故障表查出多个故障类型
|
* 循环工单map,每个工单故障类型查对应的规则,根据规则和工单创建时间和审核通过时间进行扣分
|
* 插入合同积分表,修改工单状态为已扣分
|
*/
|
public void workOrderDeduct() {
|
//查询生效合同对应所有的规则
|
List<CalculateRuleVO> calculateRules = contractMapper.getCalculateRule(new Date());
|
Map<String, Map<Integer, List<CalculateRuleVO>>> ruleMap = calculateRules.stream()
|
.collect(Collectors.groupingBy(
|
CalculateRuleVO::getRuleName, // 按规则名称分组
|
Collectors.groupingBy(
|
CalculateRuleVO::getContractId // 每个规则名称内部再按合同ID分组,value为规则集合
|
)
|
));
|
//前端感知源治理工作(时钟同步规则、OSD规则、一机一档规则) 获取key为合同id,value为规则的map
|
Map<Integer, List<CalculateRuleVO>> monitorRuleMap = ruleMap.get(ContractRule.CONTRACT_RULE_Monitor.getName());
|
//存储故障(24小时以内,48小时以内) 获取key为合同id,value为规则的map
|
Map<Integer, List<CalculateRuleVO>> storeRuleMap = ruleMap.get(ContractRule.CONTRACT_RULE_Store.getName());
|
//点位异常情况处理 获取key为合同id,value为规则的map
|
Map<Integer, List<CalculateRuleVO>> siteRuleMap = ruleMap.get(ContractRule.CONTRACT_RULE_Site.getName());
|
|
}
|
/**
|
* 不定期检查数据 扣除积分
|
*/
|
public void randomDeduct() {
|
|
}
|
|
}
|