yangys
2025-11-24 11d4be720620abf502d35000e2ed40d30c4023bf
修复离线时间展示
已修改7个文件
141 ■■■■ 文件已修改
collect/src/main/java/com/qianwen/mdc/collect/mapper/iotdb/DeviceStateMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/java/com/qianwen/mdc/collect/mapper/iotdb/ProcessParamMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/java/com/qianwen/mdc/collect/service/DeviceOfflineCheckService.java 120 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/java/com/qianwen/mdc/collect/service/IOTMqttReceiveService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/java/com/qianwen/mdc/collect/service/PackedDataService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/resources/com/qianwen/mdc/collect/mapper/iotdb/DeviceStateMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/resources/com/qianwen/mdc/collect/mapper/iotdb/ProcessParamMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
collect/src/main/java/com/qianwen/mdc/collect/mapper/iotdb/DeviceStateMapper.java
@@ -114,4 +114,6 @@
     * @return
     */
    List<DeviceState> workstationFixPointStatesInTimeRange(@Param("workstationId")Long workstationId, @Param("startTime")Long startTime, @Param("endTime")Long endTime);
    DeviceState lastNoFixedState(@Param("workstationId")long workstationId);
}
collect/src/main/java/com/qianwen/mdc/collect/mapper/iotdb/ProcessParamMapper.java
@@ -11,9 +11,8 @@
    /**
     * 查询工位在最近duration毫秒内最后一个参数
     * @param workstationId
     * @param duration
     * @return
     */
    ProcessParam lastParamByWorstationId(@Param("workstationId") Long workstationId);
    ProcessParam lastParamByWorkstationId(@Param("workstationId") Long workstationId);
}
collect/src/main/java/com/qianwen/mdc/collect/service/DeviceOfflineCheckService.java
@@ -1,10 +1,22 @@
package com.qianwen.mdc.collect.service;
import java.util.Arrays;
import java.util.Date;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Sets;
import com.qianwen.mdc.collect.cache.TimeSliceCache;
import com.qianwen.mdc.collect.constants.CommonConstant;
import com.qianwen.mdc.collect.dto.CacheBuildDTO;
import com.qianwen.mdc.collect.dto.CalendarShiftTimeSlicesDTO;
import com.qianwen.mdc.collect.mapper.iotdb.DeviceStateMapper;
import com.qianwen.mdc.collect.utils.LocalDateTimeUtils;
import com.xxl.job.core.log.XxlJobLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,9 +27,7 @@
import com.qianwen.mdc.collect.dto.WorkstationDTO;
import com.qianwen.mdc.collect.entity.iotdb.DeviceState;
import com.qianwen.mdc.collect.entity.iotdb.ProcessParam;
import com.qianwen.mdc.collect.enums.FeedbackTimePointEnum;
import com.qianwen.mdc.collect.mapper.iotdb.ProcessParamMapper;
import com.qianwen.mdc.collect.vo.FactoryDataVO;
import cn.hutool.core.util.ObjectUtil;
/**
@@ -41,10 +51,13 @@
    private ProcessParamMapper processParamMapper;
    
    @Autowired
    private FactoryDataService factoryDataService;
    private DeviceStateService deviceStateService;
    @Autowired
    private TimeSliceCache timeSliceCache;
    @Autowired
    private DeviceStateMapper deviceStateMapper;
    /**
     * 保存状态固定点数据(state_{workstationId})
     * @param workstationIdList
     */
    public void checkOffline() {
        //将数据按照工位id分组
@@ -67,34 +80,109 @@
    }
    /**
     * 检查一个工位是否离线,离线则填充离线状态数据
     * @param workstationId
     * @param workstationId 工位id
     */
    public void handleWorkstationOffline(long workstationId) {
        ProcessParam lastParam = processParamMapper.lastParamByWorstationId(workstationId);
        long nowMills = System.currentTimeMillis();
        long onlineRange = nowMills - offlineConfigDuration;
        long nowMills = System.currentTimeMillis();
        long lastOnlineTime = nowMills - offlineConfigDuration;
        /*
        ProcessParam lastParam = processParamMapper.lastParamByWorkstationId(workstationId);
        if(lastParam != null && lastParam.getTime()> onlineRange) {
            //有数据,且在判定时间内-》在线
            return;
        }
        }*/
        DeviceState lastState = deviceStateMapper.lastNoFixedState(workstationId);
        if(lastState != null && lastState.getTime() > lastOnlineTime) {
            //有数据,且在判定时间内-》在线
            return;
        }
        //TODO 这里一直离线是什么数据
        XxlJobLogger.log("离线"+workstationId);
        //时间段内无参数,说明设备没采集数据判定为离线,插入状态,然后发送realTime消息给mdc
        //作为实时数据发送
        ProcessParam statusParam = new ProcessParam();
        statusParam.setTime(nowMills);
        statusParam.setN("DeviceStatus");
        statusParam.setV(OFFLINE_VALUE);
        statusParam.setWorkstationId(workstationId);
        if(lastParam == null || !lastParam.getN().equals("DeviceStatus")) {
        //if(lastState == null || !lastParam.getN().equals("DeviceStatus")) {
        if(lastState == null || lastState.getTime() <= lastOnlineTime) {
            //之前无任何采集的数据(或者上一条不是状态数据),新加一条离线状态数据
            paramService.insertProcessParam(statusParam);
            //paramService.insertProcessParam(statusParam);
            //插入状态表
            DeviceState offLineState = new DeviceState();
            offLineState.setTime(nowMills);
            String calendarCode = workstationCache.getWorkstationCalendarCodeForDate(workstationId, DateUtil.formatDate(DateUtil.date(nowMills)));
            offLineState.setCalendarCode(calendarCode);//111
            this.fillCalendar(offLineState);
            offLineState.setValueCollect(Integer.parseInt(OFFLINE_VALUE));
            offLineState.setWcs(offLineState.getValueCollect());
            offLineState.setWorkstationId(workstationId);
            offLineState.setIsFixPoint(false);
            offLineState.setIsDeleted(false);
            offLineState.setIsSync(false);
            deviceStateService.saveDeviceStates(Collections.singletonList(offLineState));
            XxlJobLogger.log("保存离线状态"+workstationId);
        }
        
        //通知mdc更新实时状态
        paramService.sendRealtimeDataMsg(statusParam);
        
    }
    /**
     * 填充数据日历
     * @param state 状态对象
     */
    void fillCalendar(DeviceState state){
        if (ObjectUtil.isEmpty(state.getCalendarCode())) {
            state.setCalendarCode(CommonConstant.DEFAULT_CODE);
        }
        java.util.Date collectTime = new java.util.Date(state.getTime());
        boolean isDefaultCalendar = true;
        if (!CommonConstant.DEFAULT_CODE.equals(state.getCalendarCode())) {
            CalendarShiftTimeSlicesDTO calendarShiftTimeSlicesDTO = timeSliceCache.getTimeSliceShift(state.getCalendarCode(), collectTime);//从redis中获得日历的时间切片
            if (ObjectUtil.isEmpty(calendarShiftTimeSlicesDTO)) {
                LocalDate targetDate = Instant.ofEpochMilli(state.getTime()).atZone(ZoneOffset.systemDefault()).toLocalDate();
                CacheBuildDTO cacheBuildDTO = CacheBuildDTO.builder().tenantIds(Sets.newHashSet(new String[]{"000000"})).calendarCode(state.getCalendarCode()).targetDate(targetDate).build();
                timeSliceCache.build(cacheBuildDTO);
                calendarShiftTimeSlicesDTO = timeSliceCache.getTimeSliceShift(state.getCalendarCode(), collectTime);
            }
            if (ObjectUtil.isNotEmpty(calendarShiftTimeSlicesDTO)) {
                state.setShiftIndex(calendarShiftTimeSlicesDTO.getShiftIndex());
                state.setShiftTimeType(Integer.valueOf(calendarShiftTimeSlicesDTO.getShiftTimeType()));
                state.setFactoryDate(Integer.valueOf(calendarShiftTimeSlicesDTO.getFactoryDate().replaceAll("-", "")));
                state.setFactoryWeek(calendarShiftTimeSlicesDTO.getFactoryWeek());
                state.setFactoryMonth(calendarShiftTimeSlicesDTO.getFactoryMonth());
                state.setFactoryYear(calendarShiftTimeSlicesDTO.getFactoryYear());
                isDefaultCalendar = false;
            }
        }
        //无日历切片,使用采集时间填充factoryYear,month,date,week几个属性
        if (isDefaultCalendar) {
            log.info("离线检查无日历切片");
            LocalDate localDate = Instant.ofEpochMilli(state.getTime()).atZone(ZoneOffset.systemDefault()).toLocalDate();
            state.setFactoryDate(Integer.valueOf(DatePattern.PURE_DATE_FORMAT.format(collectTime)));
            state.setFactoryYear(DateUtil.year(collectTime));
            state.setFactoryWeek(LocalDateTimeUtils.getWeek(localDate));
            state.setFactoryMonth(DateUtil.month(collectTime) + 1);
            state.setShiftIndex(CommonConstant.DEFAULT_SHIFT_INDEX);
            state.setShiftTimeType(CommonConstant.DEFAULT_SHIFT_TYPE);
        }
    }
    
}
collect/src/main/java/com/qianwen/mdc/collect/service/IOTMqttReceiveService.java
@@ -31,7 +31,7 @@
    
    /**
     * 处理收到的消息,对应TelemetryDataPostingConsumer
     * @param payload
     * @param payload 数据,json格式
     */
    public void handle(String payload) {
        //解析消息
collect/src/main/java/com/qianwen/mdc/collect/service/PackedDataService.java
@@ -126,13 +126,13 @@
            //telemetryData.setCalendarCode(calendarCode);
        } else {
            //telemetryData.setCalendarCode("#default#");
            pdata.setCalendarCode("#default#");
            pdata.setCalendarCode(CommonConstant.DEFAULT_CODE);
        }
        
        // TelemetryPropertyWrapper中packWorkstationCalendarInfo
        //------------start
        boolean isDefaultCalendar = true;
        if (!"#default#".equals(pdata.getCalendarCode())) {
        if (!CommonConstant.DEFAULT_CODE.equals(pdata.getCalendarCode())) {
            CalendarShiftTimeSlicesDTO calendarShiftTimeSlicesDTO = timeSliceCache.getTimeSliceShift(pdata.getCalendarCode(), collectTime);//从redis中获得日历的时间切片
            if (ObjectUtil.isEmpty(calendarShiftTimeSlicesDTO)) {//如果没有时间切片,则使用TimeSliceCache.build(cacheBuildDTO);构建
                LocalDate targetDate = Instant.ofEpochMilli(pdata.getTime()).atZone(ZoneOffset.systemDefault()).toLocalDate();
collect/src/main/resources/com/qianwen/mdc/collect/mapper/iotdb/DeviceStateMapper.xml
@@ -188,7 +188,11 @@
        select <include refid="all_columns" /> FROM root.f2.state_${workstationId}
        where is_fix_point=true and is_deleted=false and time &gt;= #{startTime} AND time &lt;= #{endTime}
    </select>
    <select id="lastNoFixedState" resultType="com.qianwen.mdc.collect.entity.iotdb.DeviceState">
        select <include refid="all_columns" /> FROM root.f2.state_${workstationId}
        where is_fix_point=false and is_deleted=false order by time desc limit 1
    </select>
</mapper>
collect/src/main/resources/com/qianwen/mdc/collect/mapper/iotdb/ProcessParamMapper.xml
@@ -12,7 +12,7 @@
    </resultMap>
    <!-- n,v,workstation_id -->
    <select id="lastParamByWorstationId" resultType="com.qianwen.mdc.collect.entity.iotdb.ProcessParam">
    <select id="lastParamByWorkstationId" resultType="com.qianwen.mdc.collect.entity.iotdb.ProcessParam">
            select  n as n,v as v,workstation_id as workstationId from root.f2.process_param_${workstationId}_* order by time desc limit 1 align by device
    </select>