fuliqi
2024-09-10 7d5ea3631d163343b652bd6bd40b94b34c4194eb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.ycl.calculate;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycl.platform.domain.entity.CheckIndexFace;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.HK.MonitoringDetailResult;
import com.ycl.platform.domain.result.HK.SnapshotDataMonitorResult;
import com.ycl.platform.domain.vo.TMonitorVO;
import com.ycl.platform.mapper.CheckIndexFaceMapper;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.service.ICheckIndexFaceService;
import com.ycl.platform.service.ITMonitorService;
import com.ycl.system.entity.SysDictData;
import com.ycl.system.mapper.SysConfigMapper;
import com.ycl.system.mapper.SysDictDataMapper;
import constant.*;
import enumeration.general.AreaDeptEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import utils.DateUtils;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
 
/**
 * 计算人脸点位在线率、视图库对接稳定性
 * 抓拍数据量监测结果接口数据
 * 获取分省厅、区域的map<k,v> k为deptId或者Province_deptId
 * 循环map计算点位在线率
 * 更新或新增
 */
@Component
@Slf4j
public class FaceSnapshotDataCalculation extends IndexCalculationServe<SnapshotDataMonitorResult, FaceSnapshotDataCalculation.AreaStats> implements CalculationStrategy<SnapshotDataMonitorResult> {
    @Autowired
    private CheckIndexFaceMapper checkIndexFaceMapper;
    @Autowired
    private ICheckIndexFaceService checkIndexFaceService;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private TMonitorMapper monitorMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysDictDataMapper dictDataMapper;
    //区域人脸点位在线指标的内部类
    protected static class AreaStats {
        int totalSites = 0;
        int totalDataSum = 0;
    }
 
    @Override
    public void calculate(List<SnapshotDataMonitorResult> list) {
        //获取分区域的指标数量
        Map<String, FaceSnapshotDataCalculation.AreaStats> areaStatsMap = getAreaStatsMap(list);
        if (areaStatsMap == null) return;
 
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 获取本月的第一天
        LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
        // 判断今天是否是本月的第一天
        if (today.equals(firstDayOfMonth)) {
            // 如果是,则清除Redis中记录中断次数的数据
            redisTemplate.delete(RedisConstant.Check_Face_ViewConnect);
        }
        //从字典获取同期抓拍量
        List<SysDictData> faceSnap = dictDataMapper.selectDictDataByType(CheckConstants.DICT_FACE_SNAP);
        // 查询今日数据
        List<CheckIndexFace> checkIndexFaceList = checkIndexFaceMapper.selectToday(DateUtils.getDate());
        List<CheckIndexFace> checkIndexFaces = new ArrayList<>();
        areaStatsMap.forEach((deptId, stats) -> {
            if (stats.totalSites > 0) {
                CheckIndexFace checkIndexFace = createOrUpdateCheckIndexFace(deptId, stats, checkIndexFaceList,faceSnap);
                if (checkIndexFace != null) {
                    checkIndexFaces.add(checkIndexFace);
                }
            }
        });
 
        checkIndexFaceService.saveOrUpdateBatch(checkIndexFaces);
    }
 
    //累计总点位数、离线数、总抓拍量
    @Override
    public void updateAreaStats(Map<String, AreaStats> areaStatsMap, String key, SnapshotDataMonitorResult result) {
        //返回对象的引用,如果不存在会放入新的key,value
        AreaStats stats = areaStatsMap.computeIfAbsent(key, k -> new AreaStats());
        stats.totalSites++;
        if (ApiConstants.HK_SnapCount_ResultType_Null != result.getResultType()) {
            stats.totalDataSum += result.getDataCount();
        }
    }
 
 
    //人脸视图库对接稳定性
    private CheckIndexFace createOrUpdateCheckIndexFace(String key, AreaStats stats, List<CheckIndexFace> checkIndexFaceList,List<SysDictData> faceSnap) {
        CheckIndexFace checkIndexFace = getCheckIndex(key, checkIndexFaceList, CheckIndexFace.class);
        if (checkIndexFace == null) {
            return null;
        }
        //视图库对接稳定性
        //Redis记录该区县当月无数据上传次数
        Integer noDateCount = (Integer) redisTemplate.opsForHash().get(RedisConstant.Check_Face_ViewConnect, key);
        // 如果值为null,则初始化为0
        if (noDateCount == null) {
            noDateCount = 0;
        }
        Double deductScore = 0.1 * noDateCount;
        log.info("总量:{}",stats.totalDataSum);
        if (stats.totalDataSum != 0) {
            Integer deptId = key.startsWith(ApiConstants.Province) ? Integer.parseInt(key.split("_")[1]) : Integer.parseInt(key);
            String dictKey = key.startsWith(ApiConstants.Province) ? ApiConstants.Province+ AreaDeptEnum.fromDept(deptId).getCode() : ApiConstants.County+AreaDeptEnum.fromDept(deptId).getCode();
            Optional<SysDictData> first = faceSnap.stream().filter(sysDictData -> sysDictData.getDictLabel().equals(dictKey)).findFirst();
            if(first.isPresent()) {
                String value = first.get().getDictValue();
                Map<String, Object> viewConnectParam = new HashMap<>();
                viewConnectParam.put("totalDataSum", stats.totalDataSum);
                viewConnectParam.put("avgCount", new BigDecimal(value).multiply(new BigDecimal(CheckConstants.MultiplyNum)).divide(new BigDecimal(LocalDate.now().getDayOfMonth()), 0, RoundingMode.HALF_UP));
                BigDecimal viewConnectStability = viewConnectStability(viewConnectParam);
                viewConnectStability = viewConnectStability.subtract(new BigDecimal(deductScore)).max(BigDecimal.ZERO).min(BigDecimal.ONE);
                checkIndexFace.setViewConnectStability(viewConnectStability);
            }
        } else {
            noDateCount++;
        }
        // 将新的值放回Hash中
        redisTemplate.opsForHash().put(RedisConstant.Check_Face_ViewConnect, key, noDateCount);
        return checkIndexFace;
    }
}