package com.mvc.service.copy;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.constant.*;
import com.mvc.dao.TAireadMapper;
import com.mvc.entity.TAiread;
import com.mvc.entity.TAireadExample;
import com.mvc.model.*;
import com.mvc.model.iotcard.TIotcardInfoModel;
import com.mvc.netty.dealconstant.ResourceTag;
import com.mvc.othermodel.GroupAndStationTree;
import com.mvc.service.TDeviceOperationService;
import com.mvc.service.dic.DicGeneralService;
import com.mvc.service.iotcard.IotCardService;
import com.mvc.service.taizhang.DeviceAccService;
import com.mvc.service.taizhang.StationAccService;
import com.mvc.service.taizhang.TAicbqCfgService;
import com.mvc.service.temp.TempAireadService;
import com.mvc.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mvc.service.TUsingunitGroupService;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional
public class TAireadService {
    private static Logger log = LoggerFactory.getLogger(TAireadService.class);

    @Resource
    private TAireadMapper tAireadMapper;

    @Resource
    private TServerReadService tServerReadService;

    @Resource
    private TAicbqCfgService tAicbqCfgService;

    @Resource
    private StationAccService stationAccService;

    @Resource
    private Environment env;

    @Resource
    private TUsingunitGroupService tUsingunitGroupService;

    @Resource
    private DicGeneralService dicGeneralService;

    @Resource
    private DeviceAccService deviceAccService;

    @Resource
    private IotCardService iotCardService;

    @Resource
    private TempAireadService tempAireadService;

    //@Resource
    //private TExtendIdentService extendIdentService;

    @Resource
    private TDeviceOperationService deviceOperationService;

    //解除限制的站码(允许用户看全部数据,间隔比较短) 4060100050:机房温度监控,2507110001/2:博顺源测试的
    private static final List<String> UNRESTRICTED_STATION_CODE = Arrays.asList("4060100050", "2507110001", "2507110002");

    public int countHasRepeatrRecord(TAiread tAiread) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andSampleTimeEqualTo(tAiread.getSampleTime());
        criteria.andRptTimeEqualTo(tAiread.getRptTime());
        criteria.andStationCodeEqualTo(tAiread.getStationCode());
        int l = (int) tAireadMapper.countByExample(example);
        return l;
    }

    public TAiread addTAiread(TAiread tAiread) {
        //入库时统一处理部分报文中带SN是12位的问题 2022-06-28 guozhao
        if (StringUtils.isNotEmpty(tAiread.getDeviceSn())) {
            String sn = tAiread.getDeviceSn().substring(0, BaseConstant.LENGTH_DEVICE_SN);
            tAiread.setDeviceSn(sn);
        }

        DeviceAccModel accModel = deviceAccService.findDeviceAccBysn(tAiread.getDeviceSn());
        if (accModel != null) {
            tAiread.setDeviceType(accModel.getDeviceType());
        }

        //防止信息被没有调试信息的覆盖
        if (!io.netty.util.internal.StringUtil.isNullOrEmpty(tAiread.getSzsbz())) {
            tAiread.setGoodFlag(getGoodFlag(tAiread));
        }

        //处理空路径,没有图片的 2024-01-12 guozhao
        if (!ImageUtil.isImageByExtension(tAiread.getSmallJpgUrl())) {
            tAiread.setSmallJpgUrl("");
        }
        if (!ImageUtil.isImageByExtension(tAiread.getBigJpgUrl())) {
            tAiread.setBigJpgUrl("");
        }

        tAiread = getDataByUnitType(tAiread);   //按照设备配置处理小数点问题 2022-07-11 guozhao
        TAiread lastAiread = getLastRecord(tAiread);//上次计数记录
        if (lastAiread != null) {
            if (tAiread.getMcuRunNum() != null) {
                if (tAiread.getResultValue() != null && tAiread.getSampleTime() != null) {
                    tAiread.setPreAmount(tAiread.getResultValue().stripTrailingZeros().toPlainString());
                    tAiread.setPreTime(tAiread.getSampleTime());
                }
            }
            //add:兼容全配置模式添加 2025-03-10 guozhao
            handleOperationStatusChanged(lastAiread, tAiread);
        }

        //此处做了一个特殊处理,智慧院要看温度,但小程序已经根据审核进行过滤了
        //由于机房空调宕机 2025-03-22 guozhao
        if (UNRESTRICTED_STATION_CODE.contains(tAiread.getStationCode())) {
            tAiread.setReviewFlag(BaseConstant.VALID_FLAG);
            tAiread.setReviewResultFlag(ReviewResultType.IDENT_TRUE.getCode());
            tAiread.setReviewMan("特殊处理");
        }

        tAireadMapper.insert(tAiread);
        handleDuplicateRecord(tAiread, accModel);
        return tAiread;
    }

    /**
     * 处理操作(投运)状态变化
     *
     * @param lastAiread
     * @param curAiread
     */
    private void handleOperationStatusChanged(TAiread lastAiread, TAiread curAiread) {
        if (StringUtils.isEmpty(lastAiread.getOperationStatus()) || StringUtils.isEmpty(curAiread.getOperationStatus())) {
            return;
        }
        OperationStatus lastStatus = OperationStatus.findOperationStatusByflag(lastAiread.getOperationStatus());
        OperationStatus curStatus = OperationStatus.findOperationStatusByflag(curAiread.getOperationStatus());

        //新旧两次都要求是投运状态才比较
        if ((lastStatus != OperationStatus.OPERATIONAL && lastStatus != OperationStatus.CONFIG_INVALID) ||
                curStatus != OperationStatus.OPERATIONAL && curStatus != OperationStatus.CONFIG_INVALID) {
            return;
        }

        boolean lastValid = DeviceReportInfo.isValidData(lastAiread.getDeviceReportCode());
        boolean curValid = DeviceReportInfo.isValidData(curAiread.getDeviceReportCode());
        //上次有效识别,本次无效,要加入异常记录
        if (lastValid && !curValid) {
            TDeviceOperationModel operationModel = new TDeviceOperationModel(curAiread);
            deviceOperationService.saveTDeviceOperation(operationModel);
        }
    }

    /**
     * 获取上次记录
     *
     * @param tAiread
     * @return
     */
    private TAiread getLastRecord(TAiread tAiread) {
        if (StringUtils.isEmpty(tAiread.getDeviceSn())) return null;
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andDeviceSnEqualTo(tAiread.getDeviceSn());
        criteria.andFunCodeEqualTo("32");
        example.setOrderByClause("SAMPLE_TIME desc");
        Page<Object> pageObject = PageHelper.startPage(1, 1);
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        if (tAireads != null && tAireads.size() > 0) {
            TAiread last = tAireads.get(0);
            //两次的MCU运行次数相差1
            if (last.getMcuRunNum() != null && tAiread.getMcuRunNum() - last.getMcuRunNum() == 1) {
                int cz = tAiread.getBatRumTime() - last.getBatRumTime();
                last.setIntervalMinutes(cz);
                tAireadMapper.updateByPrimaryKey(last);
            }
            return last;
        }
        return null;
    }

    //根据观测时间，查询最近一条数据
    public TAiread findlastTAireadBydatatime(String stationCode, Date sampleTime) {
        TAiread tAiread = tAireadMapper.findlastTAireadBydatatime(stationCode, sampleTime);
        return tAiread;
    }

    /**
     * 根据设备SN,采样时间范围,分页查询数据
     *
     * @param deviceSn
     * @param startTime
     * @param endTime
     * @param page
     * @param rows
     * @return
     */
    public Map<String, Object> findAllTAiread(String deviceSn, String startTime, String endTime, Integer page, Integer rows) {
        //保留此方法,是为了兼容其它前端和内部调用
        TAireadModel queryModel = new TAireadModel();
        queryModel.setDeviceSn(deviceSn);
        queryModel.setStartTime(startTime);
        queryModel.setEndTime(endTime);
        queryModel.setPage(page);
        queryModel.setRows(rows);
        return findAllTAireadByCondition(queryModel);
    }

    /**
     * 根据站代码、采样时间范围分页查询数据
     *
     * @param stationCode
     * @param startTime
     * @param endTime
     * @param page
     * @param rows
     * @return
     */
    public Map<String, Object> findAllTAireadByStationCode(String stationCode, String startTime, String endTime, Integer page, Integer rows) {
        //保留此方法,是为了兼容其它前端和内部调用
        TAireadModel queryModel = new TAireadModel();
        queryModel.setStationCode(stationCode);
        queryModel.setStartTime(startTime);
        queryModel.setEndTime(endTime);
        queryModel.setPage(page);
        queryModel.setRows(rows);
        return findAllTAireadByCondition(queryModel);
    }

    /**
     * 根据TAireadModel查询列表
     *
     * @param queryModel
     * @return
     */
    public Map<String, Object> findAllTAireadByCondition(TAireadModel queryModel) {
        List<TAireadModel> resList = new ArrayList<>();

        Map<String, Object> resMap = new HashMap<>();
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        StationAccModel accModel = null;

        //当前查询的用户类型
        QueryUserType queryUserType = HttpUtil.getQueryUserTypeByRequest();
        if (queryUserType != null) {
            queryModel.setQueryUserType(queryUserType.getFlag());
        }

        if (StringUtils.isNotEmpty(queryModel.getDeviceSn())) {//SN查询
            criteria.andDeviceSnEqualTo(queryModel.getDeviceSn());
        } else if (StringUtils.isNotEmpty(queryModel.getStationName()) || StringUtils.isNotEmpty(queryModel.getUserDefinedCode())) {
            if (StringUtils.isNotEmpty(queryModel.getStationName())) {//站点名称查询
                accModel = stationAccService.findStationAccByStationName(queryModel.getStationName());
            } else {//用户自定义编码
                accModel = stationAccService.findStationAccByUserDefinedCode(queryModel.getUserDefinedCode());
            }

            if (accModel != null) {
                criteria.andStationCodeEqualTo(accModel.getStationCode());
            } else {
                resMap.put("total", 0);
                resMap.put("list", resList);
                return resMap;
            }
        } else if (StringUtils.isNotEmpty(queryModel.getStationCode())) {//站点编号查询
            criteria.andStationCodeEqualTo(queryModel.getStationCode());
        } else if (StringUtils.isNotEmpty(queryModel.getImei())) {
            criteria.andImeiEqualTo(queryModel.getImei());
        } else {
            return resMap;//没有查询条件
        }

        boolean isFilterCreateStationTime = queryModel.getFilterCreateStationTime() != null && queryModel.getFilterCreateStationTime() == 1;

        Date startDate = null;
        if (StringUtils.isNotEmpty(queryModel.getStartTime())) {
            startDate = DateUtil.parseTimeStr(queryModel.getStartTime(), "yyyyMMddHHmmss");
            criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        }

        if (StringUtils.isNotEmpty(queryModel.getEndTime())) {
            Date endDate = DateUtil.parseTimeStr(queryModel.getEndTime(), DateUtil.PATTERN_DATA_UNSIGNED);
            criteria.andSampleTimeLessThanOrEqualTo(endDate);
        }

        if (queryUserType != null && queryUserType == QueryUserType.CUSTOMER) {//客户只看审核过后的
            criteria.andReviewFlagEqualTo(BaseConstant.VALID_FLAG);
        }

        if (StringUtils.isNotEmpty(queryModel.getFunCode())) {
            criteria.andFunCodeEqualTo(queryModel.getFunCode());
        }

        if (queryModel.getIsCustomer() != null && queryModel.getIsCustomer() == 1) {
            criteria.andBigJpgUrlIsNotNull();
            criteria.andBigJpgUrlNotEqualTo("");
        }

        //根据建站时间过滤数据(早期部分数据没有建站时间) 2024-04-22 guozhao
        if (isFilterCreateStationTime && accModel != null && accModel.getCreateTime() != null) {
            Date createTime = accModel.getCreateTime();
            if (startDate == null || startDate.getTime() < createTime.getTime()) {
                criteria.andSampleTimeGreaterThanOrEqualTo(createTime);
            }
        }

        //当用户为客户时,只查询投运后的数据(isNull是为了让用户能查没有投运标记的记录) 2025-03-31 guozhao
        if (StringUtils.isNotEmpty(queryModel.getQueryUserType()) && queryModel.getQueryUserType().equals(QueryUserType.CUSTOMER.getFlag())) {
            criteria.andOperationStatusBetweenOrIsNull(OperationStatus.OPERATIONAL.getFlag(), OperationStatus.CONFIG_INVALID.getFlag());
        }

        example.setOrderByClause("SAMPLE_TIME desc");
        Page<Object> pageObject = PageHelper.startPage(queryModel.getPage(), queryModel.getRows());
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);

        StationAccModel stationAccModel = null;
        //获取当前设备的的物联网卡数据列表
        Map<Integer, TIotcardInfoModel> iotcardInfoModelMap = null;
        Optional<TAiread> optional = tAireads.stream().filter(s -> StringUtils.isNotEmpty(s.getCcid())).findFirst();
        if (optional.isPresent()) {
            iotcardInfoModelMap = iotCardService.findIotcardInfoModelsByCcid(optional.get().getCcid(), startDate);
        }
        //获取服务侧识别数据
        Map<String, TServerReadModel> serverReadModelMap = tServerReadService.findServerReadModelsByAireadInfo(queryModel.getDeviceSn(), queryModel.getStationCode(), startDate);
        //获取扩展识别数据
        //Map<Integer, TExtendIdentModel> extendIdentModelMap = extendIdentService.findExtendIdentModelsByAiReadInfo(queryModel.getDeviceSn(), queryModel.getStationCode(), startDate);
        for (int i = 0; i < tAireads.size(); i++) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAireads.get(i), model);

            //判断MUC运行次数是否差1
            if (i + 1 < tAireads.size() && tAireads.get(i).getMcuRunNum() != null && tAireads.get(i + 1).getMcuRunNum() != null) {
                int num = tAireads.get(i).getMcuRunNum() - tAireads.get(i + 1).getMcuRunNum();
                model.setLoseFlag(tAireads.get(i).getMcuRunNum() - tAireads.get(i + 1).getMcuRunNum() > 1 ? "1" : "0");
                model.setNumOfDiff(num);
            }

            if (serverReadModelMap != null && serverReadModelMap.containsKey(model.getAireadId())) {
                model.setServerReadModel(serverReadModelMap.get(model.getAireadId()));
            }

            //添加站名 2022-07-13 guozhao
            if (stationAccModel == null) {
                stationAccModel = stationAccService.findStationAccByStationCode(model.getStationCode());
            }
            if (stationAccModel != null) {
                model.setStationName(stationAccModel.getStationName());
                model.setDeviceUnitName(getDeviceUnitName(stationAccModel));
                model.setUserDefinedCode(stationAccModel.getUserDefinedCode());
            } else {
                model.setStationName("");
                model.setUserDefinedCode(model.getStationCode());
            }

            if (model.getRptTime() != null && model.getRevTime() != null) {
                model.setTranDuration(DateUtil.getSencondsbetweenTime(model.getRptTime(), model.getRevTime()));
            }

            dealInvalidImageUrl(model);
            setIotCardInfo(iotcardInfoModelMap, model);
            setEmptyFields(model);

            model.setQueryUserType(queryUserType == null ? "" : queryUserType.getFlag());
            setExtendFields(model);//设置扩展字段
            handleResultValueByReviewResultFlag(model);

            resList.add(model);
        }

        resMap.put("total", pageObject.getTotal());
        resMap.put("list", resList);
        return resMap;
    }

    public TAireadModel saveTAiread(TAireadModel model) {
        TAiread TAiread = new TAiread();
        //防范处理超过12位的情况 2022-06-28 guozhao
        String sn = model.getDeviceSn().substring(0, BaseConstant.LENGTH_DEVICE_SN);
        model.setDeviceSn(sn);
        BeanUtils.copyProperties(model, TAiread);

        tAireadMapper.insert(TAiread);
        model.setId(TAiread.getId());
        return model;
    }

    public TAireadModel updateTAiread(TAireadModel model) {
        TAiread TAiread = tAireadMapper.selectByPrimaryKey(model.getId());
        BeanUtils.copyProperties(model, TAiread);
        tAireadMapper.updateByPrimaryKey(TAiread);
        return model;
    }

    public int deleteTAiread(int id) {
        int i = tAireadMapper.deleteByPrimaryKey(id);
        return i;
    }

    public int findtotalnumBySnAndTime(String deviceSn, Date startDate, Date endDate) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andDeviceSnEqualTo(deviceSn);
        criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        criteria.andSampleTimeLessThanOrEqualTo(endDate);
        int num = (int) tAireadMapper.countByExample(example);
        return num;
    }

    //根据sn和时间段查询所有数据
    public List<TAireadModel> findAllTaireadBySnAndTime(String deviceSn, Date startDate, Date endDate) {
        List<TAireadModel> resList = new ArrayList<>();
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andDeviceSnEqualTo(deviceSn);
        criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        criteria.andSampleTimeLessThanOrEqualTo(endDate);
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        for (int i = 0; i < tAireads.size(); i++) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAireads.get(i), model);
            resList.add(model);
        }
        return resList;
    }

    /**
     * 根据站代码和采样时间找对应的记录(大小图匹配)
     *
     * @param stationCode
     * @param sampleTime
     * @param type        1:找小图,2:找大图
     * @return
     */
    public TAireadModel findTairedBySnAndTime(String stationCode, Date sampleTime, int type) {
        if (stationCode == null || sampleTime == null) {
            return null;
        }
        TAireadModel resmodel = new TAireadModel();
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationCode);
        criteria.andSampleTimeEqualTo(sampleTime);
        if (type == 1) {
            criteria.andSmallJpgUrlIsNotNull();
        } else {
            criteria.andBigJpgUrlIsNotNull();
        }
        //防止新图匹配旧记录 2024-05-27 guozhao
        example.setOrderByClause("REV_TIME desc");
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        if (tAireads.size() > 0) {
            BeanUtils.copyProperties(tAireads.get(0), resmodel);
            return resmodel;
        } else {
            return null;
        }
    }

    /**
     * 获取goodflag(根据调试信息)
     *
     * @param entity
     * @return
     */
    private String getGoodFlag(TAiread entity) {
        String[] tsxx = entity.getSzsbz().split(",");

        boolean isGood = false;                                   //数据是否有效
        if (tsxx.length == 12) {
            //新版本MCU程序
            isGood = BaseConstant.IDENT_GOOD_FLAG.contains(tsxx[11]);
        } else if (tsxx.length == 10) {
            //旧版本MCU程序(仅处理1和0.1立方的情况,其它情况不常见,并且老版本程序正在被淘汰)
            String flag = entity.getIdentValue().toString();
            int index = flag.indexOf(".");
            List<TAicbqCfgModel> cfgModels = tAicbqCfgService.findTAicbqCfg(entity.getDeviceSn(), "", "1");
            if (cfgModels != null && cfgModels.size() > 0) {
                //此处暂时只处理了0.1立方的
                flag = cfgModels.get(0).getUnitType() == 1 ? flag.substring(index + 1, index + 2) : flag.substring(index + 2, index + 3);
            } else {
                flag = flag.substring(index + 1, index + 2);           //默认水表是1立方的,下面去配置表确认末尾单位
            }

            isGood = BaseConstant.IDENT_GOOD_FLAG.contains(flag);
        }
        return isGood ? "1" : "0";
    }

    /**
     * 根据当前读数对象获取最近一条有效数据
     *
     * @param curModel
     * @return
     */
    public TAireadModel findPreGoodModelByDeviceSn(TAireadModel curModel) {
        if (curModel == null || StringUtils.isEmpty(curModel.getDeviceSn())) return null;
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andDeviceSnEqualTo(curModel.getDeviceSn());
        criteria.andGoodFlagEqualTo("1");
        criteria.andIdLessThan(curModel.getId());

        TAireadExample.Criteria criteria2 = example.or();
        criteria2.andDeviceSnEqualTo(curModel.getDeviceSn());
        criteria2.andReviewFlagEqualTo("1");
        criteria2.andIdLessThan(curModel.getId());

        example.setOrderByClause("SAMPLE_TIME desc");
        Page<Object> pageObject = PageHelper.startPage(1, 1);
        List<TAiread> list = tAireadMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(list.get(0), model);
            return model;
        }
        return null;
    }

    /**
     * 根据配置的尾数单位控制识别值的小数点个数
     *
     * @param tAiread
     * @return
     */
    private TAiread getDataByUnitType(TAiread tAiread) {
        if (tAiread.getIdentValue() == null) return tAiread;

        //数据报文中已经上传了 尾数单位,数值在MCU已经处理过了,不再特殊处理
        if (tAiread.getDecimalDigits() != null) {
            return tAiread;
        }

        List<TAicbqCfgModel> cfgs = tAicbqCfgService.findTAicbqCfg(tAiread.getDeviceSn(), tAiread.getStationCode(), "1");

        if (cfgs != null && cfgs.size() > 0) {
            TAicbqCfgModel cfg = cfgs.get(0);
            if (tAiread.getDeviceType() == null || !tAiread.getDeviceType().equals("2")) {//水表
                //此处暂时是固定的,后续可以从字典表读取(实际影响不大,小数位数的对应关系基本不会变)
                int num = tAiread.getIdentValue().stripTrailingZeros().scale();
                if (cfg.getUnitType() != null) {
                    num = cfg.getUnitType() < 4 ? 4 - cfg.getUnitType() : 0;
                }
                tAiread.setDecimalDigits(num);//记录小数点位数
                if (tAiread.getIdentValue() != null) {
                    tAiread.setIdentValue(tAiread.getIdentValue().setScale(num, RoundingMode.HALF_UP));
                    tAiread.setResultValue(tAiread.getIdentValue());
                }
                if (tAiread.getRawValue() != null) {
                    tAiread.setRawValue(tAiread.getRawValue().setScale(num, RoundingMode.HALF_UP));
                }
            } else {//压力表
                int num = tAiread.getIdentValue().stripTrailingZeros().scale();
                if (cfgs.get(0).getPgPrecisionType() != null) {
                    num = cfgs.get(0).getPgPrecisionType();
                }
                tAiread.setDecimalDigits(num);//记录小数点位数
                if (tAiread.getIdentValue() != null) {
                    tAiread.setIdentValue(tAiread.getIdentValue().setScale(num, RoundingMode.HALF_UP));
                }
                if (tAiread.getRawValue() != null) {
                    tAiread.setRawValue(tAiread.getRawValue().setScale(num, RoundingMode.HALF_UP));
                }
            }
        } else {
            int num = tAiread.getIdentValue().stripTrailingZeros().scale();
            tAiread.setDecimalDigits(num > -1 ? num : 0);//没有配置的,按传输值的小数位存储
            if (tAiread.getIdentValue() != null) {
                tAiread.setIdentValue(tAiread.getIdentValue().stripTrailingZeros());
            }
            if (tAiread.getRawValue() != null) {
                tAiread.setRawValue(tAiread.getRawValue().stripTrailingZeros());
            }
        }
        return tAiread;
    }

    /**
     * 根据AireadId获取数据
     *
     * @param aireadId
     * @return
     */
    public TAireadModel getTaireadByAireadId(String aireadId) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andAireadIdEqualTo(aireadId);
        List<TAiread> list = tAireadMapper.selectByExample(example);

        if (list != null && list.size() > 0) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(list.get(0), model);
            return model;
        }
        return null;
    }

    /**
     * 根据Id获取数据
     *
     * @param id
     * @return
     */
    public TAireadModel getTaireadById(Integer id) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(id);
        List<TAiread> list = tAireadMapper.selectByExample(example);

        if (list != null && list.size() > 0) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(list.get(0), model);
            return model;
        }
        return null;
    }

    public Map<String, Object> findLatestDataByStationCodes(int type, String code, boolean isCustomer, int page, int rows) {
        String stationCode = "";

        List<StationAccModel> stationAccModels = null;
        if (type == 1) {
            stationAccModels = stationAccService.findStationAccByUnitCode(code);
        } else if (type == 2) {
            stationCode += tUsingunitGroupService.getStationCodesByGroupCode(code, 1);     //查自己
            //stationCode+=tUsingunitGroupService.getStationCodesByGroupCode(code,2);     //查下级
        } else if (type == 3) {//根据单位结构ID查询的
            int unitStructureId = Integer.parseInt(code);
            stationAccModels = stationAccService.findStationAccByUnitCode(unitStructureId);
        }

        if (stationAccModels != null) {
            for (StationAccModel model : stationAccModels) {
                stationCode += model.getStationCode() + ",";
            }
        }

        if (stationCode.length() > 0) {
            stationCode = stationCode.substring(0, stationCode.length() - 1);
        }

        return findLatestTAireadByStationCodes(stationCode, false, isCustomer, page, rows);
    }

    /**
     * 根据站台编码获取最新的一条读数记录
     *
     * @param stationCode
     * @return
     */
    public TAireadModel findLatesTAireadByStationCode(String stationCode) {
        if (StringUtils.isEmpty(stationCode)) return null;
        Page<Object> pageObject = PageHelper.startPage(1, 1);
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationCode);
        example.setOrderByClause("SAMPLE_TIME desc");
        List<TAiread> list = tAireadMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(list.get(0), model);

            return model;
        }
        return null;
    }

    /**
     * 根据deviceSn获取最新的一条读数记录
     *
     * @param deviceSn
     * @return
     */
    public TAireadModel findLatestTAireadByDeviceSn(String deviceSn) {
        if (StringUtils.isEmpty(deviceSn)) return null;
        PageHelper.startPage(1, 1);
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andDeviceSnEqualTo(deviceSn);
        example.setOrderByClause("SAMPLE_TIME desc");
        List<TAiread> list = tAireadMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(list.get(0), model);

            return model;
        }
        return null;
    }

    /**
     * 根据站点串获取当前所有站点最新读数
     *
     * @param stationCodes 遥测站号(code1,code2,code3)
     * @param isSortCode   是否按照stationCode排序
     * @param isCustomer   是否是客户获取数据(这个是不准确的,主要用于燃气表)
     * @param page
     * @param rows
     * @return
     */
    public Map<String, Object> findLatestTAireadByStationCodes(String stationCodes, boolean isSortCode, boolean isCustomer, Integer page, Integer rows) {
        String[] arrStationCodes = stationCodes.split(",");
        if (isSortCode) {
            Arrays.sort(arrStationCodes);
        }
        List<TAireadModel> res = new ArrayList<>();
        Map<String, Object> resMap = new HashMap<>();
        Page<Object> pageObject = PageHelper.startPage(page, rows);

        String condition = "";//自定义的查询条件
        QueryUserType queryUserType = HttpUtil.getQueryUserTypeByRequest();

        //根据接口中的用户类型,当为客户是只可看投运后,且审核过的数据 2025-04-24
        if (queryUserType != null && queryUserType == QueryUserType.CUSTOMER) {
            StringBuilder sb = new StringBuilder();
            sb.append(" and REVIEW_FLAG =");
            sb.append(BaseConstant.VALID_FLAG);
            sb.append(" and (OPERATION_STATUS between ");
            sb.append(OperationStatus.OPERATIONAL.getFlag());
            sb.append(" and ");
            sb.append(OperationStatus.CONFIG_INVALID.getFlag());
            sb.append(" or OPERATION_STATUS is null)");
            condition = sb.toString();
        }

        List<TAiread> list;
        if (isCustomer) {
            list = tAireadMapper.findLatestDataByStationCodes_Customer(arrStationCodes);
        } else {
            list = tAireadMapper.findLatestDataByStationCodes(arrStationCodes, condition);
        }

        //要使用两个是因为服务侧使用的是业务主键,物联网卡和扩展使用的是实际主键
        List<String> aireadIds = new ArrayList<>();//业务主键列表
        List<Integer> aireadKeys = new ArrayList<>();//主键列表

        //获取当前设备的的物联网卡数据列表
        Map<Integer, TIotcardInfoModel> iotcardInfoModelMap = null;
        //获取服务侧识别数据
        Map<String, TServerReadModel> serverReadModelMap = null;
        //获取扩展识别数据
        //Map<Integer, TExtendIdentModel> extendIdentModelMap = null;
        //站点台账
        Map<String, StationAccModel> stationAccMap = stationAccService.findStationAccMapByStationCodes(stationCodes);

        if (!isCustomer) {
            for (TAiread tAiread : list) {
                aireadIds.add(tAiread.getAireadId());
                aireadKeys.add(tAiread.getId());
            }

            iotcardInfoModelMap = iotCardService.findIotcardInfoModelMapByAiReadKeys(aireadKeys);
            serverReadModelMap = tServerReadService.findServerReadModelsByAireadIds(aireadIds);
            //extendIdentModelMap = extendIdentService.findExtendIdentMapByAiReadKeys(aireadKeys);
        }

        for (TAiread tAiread : list) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAiread, model);

            if (serverReadModelMap != null && serverReadModelMap.containsKey(model.getAireadId())) {
                model.setServerReadModel(serverReadModelMap.get(model.getAireadId()));
            }

            //添加站名 2022-07-13 guozhao
            if (stationAccMap.containsKey(model.getStationCode())) {
                model.setStationName(stationAccMap.get(model.getStationCode()).getStationName());
                model.setDeviceUnitName(getDeviceUnitName(stationAccMap.get(model.getStationCode())));
                model.setUserDefinedCode(stationAccMap.get(model.getStationCode()).getUserDefinedCode());
            } else {
                model.setStationName("");
                model.setUserDefinedCode(model.getStationCode());
            }

            if (model.getRptTime() != null && model.getRevTime() != null) {
                model.setTranDuration(DateUtil.getSencondsbetweenTime(model.getRptTime(), model.getRevTime()));
            }
            setIotCardInfo(iotcardInfoModelMap, model);
            setExtendFields(model);//设置扩展字段
            handleResultValueByReviewResultFlag(model);
            setEmptyFields(model);
            res.add(model);
        }

        resMap.put("total", pageObject.getTotal());
        resMap.put("list", res);
        return resMap;
    }

    //根据站代码和月份，查找本月最新后一条数据，主要查询本月累计用水量
    public TAireadModel findDataByMonth(String stationcode, Integer month, String changeflag) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, month - 1);
        int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, actualMaximum);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String format1 = format.format(calendar.getTime());
        Date date = DateUtil.parseTimeStr(format1, "yyyyMMdd");
        Date enddate = DateUtil.getOtherDateByCurrentDate(date, 1);
        Date startdate = DateUtil.getOtherDateByCurrentDate(enddate, -3);
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationcode);
        criteria.andSampleTimeGreaterThanOrEqualTo(startdate);
        criteria.andSampleTimeLessThan(enddate);
        example.setOrderByClause("SAMPLE_TIME DESC");
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        if (tAireads.size() > 0) {
            TAiread tAiread = tAireads.get(0);
            TAireadModel resModel = new TAireadModel();
            BeanUtils.copyProperties(tAiread, resModel);
            if (StringUtils.isNotEmpty(resModel.getSmallJpgUrl()) && "1".equals(changeflag)) {
                String baseImagePath = env.getProperty(ResourceTag.UploadPathTag.getTag());
                resModel.setSmallJpgUrl(baseImagePath + resModel.getSmallJpgUrl().substring(resModel.getSmallJpgUrl().indexOf("rawdata")));
            }
            return resModel;
        } else {
            return null;
        }
    }

    //根据站代码和月份，查找本月最新后一条数据，主要查询本月累计用水量(上面的方法Month跨年后,日期会统计出错)
    public TAireadModel findDataByMonth(String stationcode, String strDate, String changeflag) {
        strDate = strDate.substring(0, 6) + "01000000";//防止前台传过来的day不是1号
        Date countDate = DateUtil.parseTimeStr(strDate, "yyyyMMddHHmmss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(countDate);
        calendar.add(Calendar.MONTH, 1);//下月1号
        Date endDate = calendar.getTime();

        calendar.add(Calendar.DAY_OF_MONTH, -3);
        Date startDate = calendar.getTime();

        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationcode);
        criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        criteria.andSampleTimeLessThan(endDate);
        example.setOrderByClause("SAMPLE_TIME DESC");
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        if (tAireads.size() > 0) {
            TAiread tAiread = tAireads.get(0);
            TAireadModel resModel = new TAireadModel();
            BeanUtils.copyProperties(tAiread, resModel);
            if (StringUtils.isNotEmpty(resModel.getSmallJpgUrl()) && "1".equals(changeflag)) {
                String baseImagePath = env.getProperty(ResourceTag.UploadPathTag.getTag());
                resModel.setSmallJpgUrl(baseImagePath + resModel.getSmallJpgUrl().substring(resModel.getSmallJpgUrl().indexOf("rawdata")));
            }
            return resModel;
        } else {
            return null;
        }
    }

    /**
     * 查询所有站点最新数据，根据各版本号进行过滤(前台重点关注模块使用)
     *
     * @param queryModel
     * @return
     */
    public List<TAireadModel> findTAireadListByVersion(CustomeGroupQueryModel queryModel) {
        List<TAireadModel> resList = new ArrayList<>();
        List<GroupAndStationTree> list = stationAccService.findAllStationTree();

        for (GroupAndStationTree tree : list) {
            if (!tree.getType().equals("2")) {
                continue;
            }

            TAireadModel aireadModel = findLatesTAireadByStationCode(tree.getCode());
            if (aireadModel == null) {
                continue;
            }
            if (StringUtils.isNotEmpty(queryModel.getAiVersion()) && queryModel.getAiCompare() != null) {
                if (!compareVersion(aireadModel.getAiVersion(), queryModel.getAiVersion(), queryModel.getAiCompare()))
                    continue;
            }
            if (StringUtils.isNotEmpty(queryModel.getSoftVer()) && queryModel.getSoftCompare() != null) {
                if (!compareVersion(aireadModel.getSoftVer(), queryModel.getSoftVer(), queryModel.getSoftCompare()))
                    continue;
            }
            if (StringUtils.isNotEmpty(queryModel.getHardVersion()) && queryModel.getHardCompare() != null) {
                if (!compareVersion(aireadModel.getHardVersion(), queryModel.getHardVersion(), queryModel.getHardCompare()))
                    continue;
            }
            if (StringUtils.isNotEmpty(queryModel.getNbVersion()) && queryModel.getNbCompare() != null) {
                if (!compareVersion(aireadModel.getNbVersion(), queryModel.getNbVersion(), queryModel.getNbCompare()))
                    continue;
            }
            aireadModel.setStationName(tree.getLabel());
            resList.add(aireadModel);
        }

        return resList;
    }

    private boolean compareVersion(String ver1, String ver2, Integer flag) {
        if (StringUtils.isEmpty(ver1) || ver1.length() != ver2.length()) {
            return false;
        }

        if (NumberUtil.isNumberic(ver2)) {//纯数字版本号
            long lngVer1 = Long.parseLong(ver1);
            long lngVer2 = Long.parseLong(ver2);
            if (flag == -1) {
                return lngVer2 > lngVer1;
            } else if (flag == 0) {
                return lngVer1 == lngVer2;
            } else {
                return lngVer1 > lngVer2;
            }
        } else {//有字母有数字版本号
            String letter2 = StringUtil.extractLetters(ver2);//要查询版本ver2的字母部分
            String num2 = StringUtil.extractDigits(ver2);//要查询版本ver2的数字部分

            //字母在ver2中的索引
            int index = ver2.indexOf(letter2);
            String letter1 = ver1.substring(index, index + letter2.length());

            if (!letter1.equals(letter2)) {//字母部分都不相同
                return false;
            }

            //数字在ver2中的索引
            index = ver2.indexOf(num2);
            String num1 = ver1.substring(index, index + num2.length());
            long lngVer1 = Long.parseLong(num1);
            long lngVer2 = Long.parseLong(num2);
            if (flag == -1) {
                return lngVer2 > lngVer1;
            } else if (flag == 0) {
                return lngVer1 == lngVer2;
            } else {
                return lngVer1 > lngVer2;
            }
        }
    }

    /**
     * 获取读数的计量单位名称
     *
     * @param model
     * @return
     */
    public String getDeviceUnitName(StationAccModel model) {
        if (model == null || StringUtils.isEmpty(model.getDeviceType())) return "";
        if (model.getDeviceType().equals("1")) return "m³";
        if (!model.getDeviceType().equals("2")) return "";
        DicGeneralModel dicModel = dicGeneralService.findADicGeneralModelByDicTypeAndKey("11", model.getDeviceUnit() + "");
        return dicModel == null ? "" : dicModel.getDicValue();
    }

    /**
     * 根据StationCodeAndSampleTime获取当日最后新一条记录
     *
     * @param stationCode
     * @param sampleTime
     * @return
     */
    public TAireadModel findTAireadByStationCodeAndSampleTime(String stationCode, String sampleTime) {
        sampleTime = sampleTime.substring(0, 8);
        String kssj = sampleTime + "000000";
        String jssj = sampleTime + "235959";
        Date startDate = DateUtil.parseTimeStr(kssj, "yyyyMMddHHmmss");
        Date endDate = DateUtil.parseTimeStr(jssj, "yyyyMMddHHmmss");

        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationCode);
        criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        criteria.andSampleTimeLessThanOrEqualTo(endDate);
        example.setOrderByClause("SAMPLE_TIME desc");

        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        if (tAireads != null && tAireads.size() > 0) {
            TAiread last = tAireads.get(0);
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(last, model);
            return model;
        }
        return null;
    }

    /**
     * 根据SN和时间范围获取最新的一样数据
     *
     * @param deviceSn
     * @param startTime
     * @param endTime
     * @return
     */
    public TAireadModel findLatestTAireadModelBySnAndDateRange(String deviceSn, Date startTime, Date endTime) {
        if (StringUtils.isEmpty(deviceSn)) return null;
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andDeviceSnEqualTo(deviceSn);
        criteria.andSampleTimeGreaterThanOrEqualTo(startTime);
        criteria.andSampleTimeLessThanOrEqualTo(endTime);
        example.setOrderByClause("SAMPLE_TIME desc");
        Page<Object> pageObject = PageHelper.startPage(1, 1);
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        if (tAireads != null && tAireads.size() > 0) {
            TAiread last = tAireads.get(0);
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(last, model);
            return model;
        }
        return null;
    }

    /**
     * 查询维护记录相关的读数列表
     *
     * @return
     */
    public List<TAireadModel> findMaintenanceAireadList() {
        List<TAireadModel> tAireadModels = new ArrayList<>();
        List<TAiread> tAireads = tAireadMapper.findMaintenanceAireadList();
        for (TAiread tAiread : tAireads) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAiread, model);
            tAireadModels.add(model);
        }
        return tAireadModels;
    }

    /**
     * 处理无效图片路径
     *
     * @param model
     */
    private void dealInvalidImageUrl(TAireadModel model) {
        //防止图像路径是下面的格式,并没有保存图片(在纯服务侧识别时,添加,特殊性:中图传无图报文,大图才有图片)
        //http://127.0.0.1:6090/image/rawdata/2023-11/8800005996/
        String url = model.getSmallJpgUrl();
        if (StringUtils.isNotEmpty(url)) {
            if (!ImageUtil.isImageByExtension(url)) {
                model.setSmallJpgUrl("");
            }
        }
        url = model.getBigJpgUrl();
        if (StringUtils.isNotEmpty(url)) {
            if (!ImageUtil.isImageByExtension(url)) {
                model.setBigJpgUrl("");
            }
        }
    }

    /**
     * 设置流量卡基本信息
     *
     * @param map
     * @param model
     */
    private void setIotCardInfo(Map<Integer, TIotcardInfoModel> map, TAireadModel model) {
        if (map != null && map.containsKey(model.getId())) {
            model.setIotCardDuedate(map.get(model.getId()).getDuedate());
            model.setIotCardRemaingprs(map.get(model.getId()).getRemaingprs());
            model.setIotCardWorkingcondition(map.get(model.getId()).getWorkingcondition());
        }
    }

    /**
     * 处理重复记录
     *
     * @param newAiread
     */
    private void handleDuplicateRecord(TAiread newAiread, DeviceAccModel accModel) {
        /*** 说明
         * 起因：燃气表在服务器未给响应时,会重新工作发数据(报文类型仍是32,36),会出现同一采样时间多条数据(水表是用的补发报)
         * 处理方式:新来32数据,直接查历史,如果历史中有完整的(有大图),则将当前新记录和多余的历史都移至临时表,如果后面又来36,会合并至当前保留的历史数据中
         * 缺陷:最后的36报文,与被替换的36是判断不出来的(需要从报文数据中分析找出来)
         * 补充：燃气表是先发32(无图),再发36(大图) -- 2024-01-15 guozhao
         * */
        /*if (accModel == null) {
            return;
        }*/
        //暂时不处理其它类型表,廉博在测试小图 2024-05-29 guozhao
        /*if (!accModel.getDeviceType().equals(DeviceType.GAS_METER.getCode())) {
            return;
        }*/

        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andIdNotEqualTo(newAiread.getId());
        if (StringUtils.isNotEmpty(newAiread.getDeviceSn())) {
            criteria.andDeviceSnEqualTo(newAiread.getDeviceSn());
        }
        criteria.andStationCodeEqualTo(newAiread.getStationCode());
        criteria.andSampleTimeEqualTo(newAiread.getSampleTime());
        List<TAiread> oldList = tAireadMapper.selectByExample(example);

        //插入:处理水表
        /*if (!accModel.getDeviceType().equals(DeviceType.GAS_METER.getCode())) {
            if (oldList != null && oldList.size() > 0) {
                moveToTempAiread(oldList.get(0));
            }
            return;
        }*/
        //处理燃气表
        boolean isOldComPlete = false;

        for (TAiread airead : oldList) {
            if (isOldComPlete) {
                //已经找到完整的,将多余的历史记录,移到临时表
                moveToTempAiread(airead);
                continue;
            }

            if (ImageUtil.isImageByExtension(airead.getBigJpgPackGid())) {
                //从历史表中取到了完整的记录,将新记录移至临时表
                isOldComPlete = true;
                moveToTempAiread(newAiread);
            } else {
                //当前历史记录没有大图,移至临时表
                moveToTempAiread(airead);
            }
        }
    }

    /**
     * 赋值扩展识别信息
     *
     * @param map
     * @param aireadModel
     */
    //已将服务侧识别直接切换为免服,因此不再使用 2025-03-31 guozhao
    private void setExtendIdentInfo(Map<Integer, TExtendIdentModel> map, TAireadModel aireadModel) {
        if (map != null && map.containsKey(aireadModel.getId())) {
            aireadModel.setNoConfigIdentValue(map.get(aireadModel.getId()).getIdentValue());
            aireadModel.setNoConfigDebugInfo(map.get(aireadModel.getId()).getDebugInfo());
            aireadModel.setNoConfigIdentJpgUrl(map.get(aireadModel.getId()).getImagePath());
        }
    }

    /**
     * 设置为空字段(减少传输量)
     *
     * @param model
     */
    private void setEmptyFields(TAireadModel model) {
        model.setErrorCode("");
        model.setHardwareCode("");
        model.setBigJpgPackGid("");
        model.setTaskReviewId("");
        model.setReviewMan("");
        model.setRandomCode("");
    }

    /**
     * 移动记录至临时表
     *
     * @param airead
     */
    private void moveToTempAiread(TAiread airead) {
        if (tempAireadService.saveTempAiread(airead) != null) {
            tAireadMapper.deleteByPrimaryKey(airead.getId());
        }
    }

    /**
     * 根据设备SN数组获取其最新一条数据(微信使用)
     *
     * @param devices
     * @return
     */
    public List<TAireadModel> findLatestDataByDeviceSns_Wx(String[] devices) {
        List<TAireadModel> resList = new ArrayList<>();
        List<TAiread> aireads = tAireadMapper.findLatestDataByDeviceSns_Wx(devices);
        for (TAiread airead : aireads) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(airead, model);
            StationAccModel stationAccModel = stationAccService.findStationAccByStationCode(airead.getStationCode());
            model.setStationName(stationAccModel == null ? "未建站" : stationAccModel.getStationName());

            resList.add(model);
        }
        return resList;
    }

    /**
     * 赋值预测值
     *
     * @param aireadModel
     */
    /*private void setPredictValue(TAireadModel aireadModel) {
        TDataPredict dataPredict = dataPredictService.getTDataPredictByAireadId(aireadModel.getId());
        if (dataPredict != null && dataPredict.getPredictValue() != null) {
            aireadModel.setPredictValue(dataPredict.getPredictValue());
        }
    }*/

    /**
     * 根据站点串获取当前所有站点最新读数
     *
     * @param deviceSns  遥测站号(sn1,sn2,sn3)
     * @param isSortCode 是否按照deviceSn排序
     * @param page
     * @param rows
     * @return
     */
    public Map<String, Object> findLatestTAireadByDeviceSns(String deviceSns, boolean isSortCode, Integer page, Integer rows) {
        String[] arrDeviceSn = deviceSns.split(",");
        if (isSortCode) {
            Arrays.sort(arrDeviceSn);
        }
        List<TAireadModel> res = new ArrayList<>();
        Map<String, Object> resMap = new HashMap<>();
        Page<Object> pageObject = PageHelper.startPage(page, rows);

        List<TAiread> list = tAireadMapper.findLatestDataByDeviceSns(arrDeviceSn);

        //要使用两个是因为服务侧使用的是业务主键,物联网卡和扩展使用的是实际主键
        List<String> aireadIds = new ArrayList<>();//业务主键列表
        List<Integer> aireadKeys = new ArrayList<>();//主键列表

        //获取当前设备的的物联网卡数据列表
        Map<Integer, TIotcardInfoModel> iotcardInfoModelMap = null;
        //获取服务侧识别数据
        Map<String, TServerReadModel> serverReadModelMap = null;
        //获取扩展识别数据
        //Map<Integer, TExtendIdentModel> extendIdentModelMap = null;

        for (TAiread tAiread : list) {
            aireadIds.add(tAiread.getAireadId());
            aireadKeys.add(tAiread.getId());
        }

        iotcardInfoModelMap = iotCardService.findIotcardInfoModelMapByAiReadKeys(aireadKeys);
        serverReadModelMap = tServerReadService.findServerReadModelsByAireadIds(aireadIds);
        //extendIdentModelMap = extendIdentService.findExtendIdentMapByAiReadKeys(aireadKeys);

        for (TAiread tAiread : list) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAiread, model);

            if (serverReadModelMap != null && serverReadModelMap.containsKey(model.getAireadId())) {
                model.setServerReadModel(serverReadModelMap.get(model.getAireadId()));
            }

            StationAccModel accModel = stationAccService.findStationAccByStationCode(tAiread.getStationCode());
            {
                if (accModel != null) {
                    model.setStationName(accModel.getStationName());
                    model.setUserDefinedCode(accModel.getUserDefinedCode());
                }
            }

            if (model.getRptTime() != null && model.getRevTime() != null) {
                model.setTranDuration(DateUtil.getSencondsbetweenTime(model.getRptTime(), model.getRevTime()));
            }
            setIotCardInfo(iotcardInfoModelMap, model);
            setExtendFields(model);//设置扩展字段
            setEmptyFields(model);
            res.add(model);
        }

        resMap.put("total", pageObject.getTotal());
        resMap.put("list", res);
        return resMap;
    }

    /**
     * 根据站点编码和时间获取读数列表(正序)
     *
     * @param stationCode
     * @param startDate
     * @param endDate
     * @return
     */
    public List<TAiread> findAllTaireadByStationCodeAndTime(String stationCode, Date startDate, Date endDate) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationCode);
        criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        criteria.andSampleTimeLessThanOrEqualTo(endDate);

        example.setOrderByClause("SAMPLE_TIME");

        return tAireadMapper.selectByExample(example);
    }

    /**
     * 根据时间范围分页获取所有站点读数
     * 为测试服务侧识别添加的方法(不必选SN和stationCode)
     *
     * @param startTime
     * @param endTime
     * @param page
     * @param rows
     * @return
     */
    public Map<String, Object> findAllTaireadByTime(String startTime, String endTime, Integer page, Integer rows) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();

        Date startDate;
        if (StringUtils.isNotEmpty(startTime)) {
            startDate = DateUtil.parseTimeStr(startTime, "yyyyMMddHHmmss");
            criteria.andSampleTimeGreaterThanOrEqualTo(startDate);
        }

        if (StringUtils.isNotEmpty(endTime)) {
            Date endDate = DateUtil.parseTimeStr(endTime, "yyyyMMddHHmmss");
            criteria.andSampleTimeLessThanOrEqualTo(endDate);
        }

        example.setOrderByClause("SAMPLE_TIME");
        Page<Object> pageObject = PageHelper.startPage(page, rows);
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);

        Map<String, Object> resMap = new HashMap<>();
        List<TAireadModel> res = new ArrayList<>();
        for (TAiread tAiread : tAireads) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAiread, model);
            res.add(model);
        }

        resMap.put("total", pageObject.getTotal());
        resMap.put("list", res);

        return resMap;
    }

    /**
     * 根据站代码和起始采样时间获取所有站点读数
     *
     * @param stationCode
     * @param startTime
     * @return
     */
    public List<TAireadModel> findAllTaireadByStationCodeAndStartTime(String stationCode, Date startTime) {
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();

        criteria.andStationCodeEqualTo(stationCode);
        criteria.andSampleTimeGreaterThanOrEqualTo(startTime);
        return selectByExample(example);
    }

    private List<TAireadModel> selectByExample(TAireadExample example) {
        List<TAiread> tAireads = tAireadMapper.selectByExample(example);
        List<TAireadModel> resList = new ArrayList<>();
        for (TAiread tAiread : tAireads) {
            TAireadModel model = new TAireadModel();
            BeanUtils.copyProperties(tAiread, model);
            resList.add(model);
        }
        return resList;
    }

    /**
     * 根据StationCode获取最新一条记录
     *
     * @param stationCode
     * @param isFiltered  是否过滤未审核数据
     * @return
     */
    public TAireadModel findReviewedAiReadModel(String stationCode, boolean isFiltered) {
        QueryUserType queryUserType = HttpUtil.getQueryUserTypeByRequest();

        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationCode);
        /*if (isFiltered) {
            criteria.andReviewFlagEqualTo(BaseConstant.VALID_FLAG);
        }*/
        //控制用户只看投运后的数据 2025-04-24 guozhao
        if (queryUserType != null && queryUserType == QueryUserType.CUSTOMER) {
            criteria.andReviewFlagEqualTo(BaseConstant.VALID_FLAG);
            criteria.andOperationStatusBetweenOrIsNull(OperationStatus.OPERATIONAL.getFlag(), OperationStatus.CONFIG_INVALID.getFlag());
        }

        example.setOrderByClause("SAMPLE_TIME desc");

        List<TAireadModel> list = selectByExample(example);
        if (list != null && list.size() > 0) {
            TAireadModel model = list.get(0);
            //无效审核不显示识别值
            handleResultValueByReviewResultFlag(model);
            return model;
        }
        return null;
    }

    /**
     * 根据审核结果标识处理结果值
     *
     * @param model
     */
    private void handleResultValueByReviewResultFlag(TAireadModel model) {
        ReviewResultType reviewResultType = ReviewResultType.findReviewResultTypeByCode(model.getReviewResultFlag());
        if (reviewResultType == null || (reviewResultType != ReviewResultType.IDENT_TRUE && reviewResultType != ReviewResultType.REVIEW_REVISE)) {
            model.setResultValue(null);
            //当非正常的审核状态时,修改数据展示为仅图片
            if (model.getDataViewType() != null && model.getDataViewType().equals(DataViewType.IMAGE_AND_DATA.getDesc())) {
                model.setDataViewType(DataViewType.ONLY_IMAGE.getDesc());
            }
        }
    }

    /**
     * 设置扩展字段
     *
     * @param model
     */
    private void setExtendFields(TAireadModel model) {
        //初始化,减少前端判断
        model.setOperationStatusLabel("-");
        model.setIdentMessage("-");
        model.setDataViewType(DataViewType.NONE.getDesc());

        //赋值投运状态
        if (StringUtils.isNotEmpty(model.getOperationStatus())) {
            OperationStatus operationStatus = OperationStatus.findOperationStatusByflag(model.getOperationStatus());
            model.setOperationStatusLabel(operationStatus == null ? "-" : operationStatus.getDesc());
        }

        //根据投运状态,赋值用户可见状态（要考虑审核值的关联）
        if (StringUtils.isNotEmpty(model.getOperationStatus())) {
            QueryUserType queryUserType = QueryUserType.findDataViewTypeByflag(model.getQueryUserType());
            OperationStatus operationStatus = OperationStatus.findOperationStatusByflag(model.getOperationStatus());
            //控制非投运状态下的运维单位(允许==null是为了过渡以前没有投运状态的数据)
            if (operationStatus == null || (operationStatus == OperationStatus.OPERATIONAL || operationStatus == OperationStatus.CONFIG_INVALID)) {//已投运
                //已审核
                String reviewFlag = model.getReviewFlag();
                if (reviewFlag != null && reviewFlag.equals(BaseConstant.VALID_FLAG)) {
                    if (model.getReviewResultFlag().equals(ReviewResultType.IDENT_TRUE.getCode()) ||
                            model.getReviewResultFlag().equals(ReviewResultType.REVIEW_REVISE.getCode())) {
                        model.setDataViewType(DataViewType.IMAGE_AND_DATA.getDesc());
                    } else {//值无效,只显示图片
                        if (queryUserType == QueryUserType.CUSTOMER) {
                            model.setResultValue(null);
                        }
                        model.setDataViewType(DataViewType.ONLY_IMAGE.getDesc());
                    }
                }
            }
        }

        //设置设备上报信息
        if (StringUtils.isNotEmpty(model.getDeviceReportCode())) {
            DeviceReportInfo deviceReportInfo = DeviceReportInfo.findDeviceReportInfoByCode(model.getDeviceReportCode());
            model.setDeviceReportLabel(deviceReportInfo == null ? "-" : deviceReportInfo.getDesc());
        } else {
            model.setDeviceReportLabel("-");
        }
    }
}
