package com.yeejoin.amos.boot.module.tzs.flc.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.tzs.api.dto.CylWarningMsgDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.MsgLog;
import com.yeejoin.amos.boot.module.tzs.api.enums.EarlyWarningLevelEnum;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.MsgLogServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.TzsAuthServiceImpl;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.*;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.*;
import com.yeejoin.amos.boot.module.tzs.flc.api.mapper.CylinderInfoMapper;
import com.yeejoin.amos.boot.module.tzs.flc.api.service.ICylinderInfoService;
import com.yeejoin.amos.component.rule.RuleTrigger;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.IntConsumer;

/**
 * 气瓶基本信息服务实现类
 *
 * @author system_generator
 * @date 2021-12-14
 */
@Service
@Slf4j
public class CylinderInfoServiceImpl extends BaseService<CylinderInfoDto, CylinderInfo, CylinderInfoMapper> implements ICylinderInfoService {


    @Autowired
    CylinderUnitServiceImpl cylinderUnitServiceImpl;

    @Autowired
    CylinderUnitDataServiceImpl cylinderUnitDataServiceImpl;

    @Autowired
    CylinderInfoDataServiceImpl cylinderInfoDataServiceImpl;

    @Autowired
    CylinderTagsServiceImpl cylinderTagsServiceImpl;

    @Autowired
    CylinderFillingServiceImpl cylinderFillingServiceImpl;

    @Autowired
    CylinderIntegrityDataServiceImpl cylinderIntegrityDataServiceImpl;

    @Autowired
    CylinderFillingRecordServiceImpl cylinderFillingRecordServiceImpl;

    @Autowired
    CylinderFillingCheckServiceImpl cylinderFillingCheckServiceImpl;

    @Autowired
    CylinderAreaDataServiceImpl cylinderAreaDataServiceImpl;

    @Autowired
    CylinderFillingUnloadDataServiceImpl cylinderFillingUnloadDataServiceImpl;

    @Autowired
    CylinderInfoDataUnitServiceImpl cylinderInfoDataUnitServiceImpl;

    @Autowired
    CylinderFillingDataUnitServiceImpl cylinderFillingDataUnitServiceImpl;

    @Autowired
    CylinderTagsDataUnitServiceImpl cylinderTagsDataUnitServiceImpl;

    @Autowired
    CylinderIntegrityDataUnitServiceImpl cylinderIntegrityDataUnitServiceImpl;

    @Autowired
    CylinderFillingCheckDataUnitServiceImpl cylinderFillingCheckDataUnitServiceImpl;

    @Autowired
    CylinderFillingUnloadDataUnitServiceImpl cylinderFillingUnloadDataUnitServiceImpl;

    @Autowired
    MsgLogServiceImpl msgLogService;

    @Autowired
    private RuleTrigger ruleTrigger;

    @Autowired
    TzsAuthServiceImpl tzsAuthService;

    @Value("${cylinder-early-warning-packageId:气瓶监管/cylwarningmsg}")
    private String packageId;

    /**
     * 分页查询
     */
    public Page<CylinderInfoDto> queryForCylinderInfoPage(Page<CylinderInfoDto> page) {
        return queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<CylinderInfoDto> queryForCylinderInfoList() {
        return queryForList("", false);
    }

    @Override
    public Map<String, Long> queryNumAndOutOfDateNum(Long unitId) {
        return baseMapper.queryNumAndOutOfDateNum(unitId);
    }

    /**
     * 获取上个月气瓶总量
     */
    public Integer getLastMonthInfoTotal(String regionCode) {
        return baseMapper.getLastMonthInfoTotal(regionCode);
    }

    /**
     * 获取上上个月气瓶总量
     */
    public Integer getMonthBeforeLastInfoTotal(String regionCode) {
        return baseMapper.getMonthBeforeLastInfoTotal(regionCode);
    }

    public Integer getInfoTotalByRegionCode(String regionCode) {
        return baseMapper.getInfoTotalByRegionCode(regionCode);
    }

    public Double queryIntegirtyByAppId(String appId) {
        return this.baseMapper.queryIntegirtyByAppId(appId);
    }

    public Integer getWarnNum(String code) {
        return baseMapper.getWarnNum(code);
    }

    /**
     * 按单位统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synFillingUnloadData() {
        cylinderFillingUnloadDataServiceImpl.remove(new LambdaQueryWrapper<CylinderFillingUnloadData>());
        countByRegion(regionModel -> {
            Calendar now = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (int i = 0; i < 30; i++) {
                now.add(Calendar.DATE, -1);
                CylinderFillingUnloadDataDto temp = new CylinderFillingUnloadDataDto();
                Double fillingSum = cylinderFillingRecordServiceImpl.getFillingSum(String.valueOf(regionModel.getRegionCode()), now.getTime());
                Double unloadSum = 0d;
                temp.setFillingSum(fillingSum);
                temp.setRegionCode(String.valueOf(regionModel.getRegionCode()));
                temp.setStatisDate(now.getTime());
                temp.setStatisDateStr(sdf.format(now.getTime()));
                temp.setUnloadSum(unloadSum);
                cylinderFillingUnloadDataServiceImpl.createWithModel(temp);
            }
        });
    }

    /**
     * 按区域统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synAreaData() {
        cylinderAreaDataServiceImpl.remove(new LambdaQueryWrapper<CylinderAreaData>());
        countByRegion(regionModel -> {
            CylinderAreaDataDto temp = new CylinderAreaDataDto();
            temp.setAreaName(regionModel.getRegionName());
            String code = regionModel.getRegionCode() + "";
            Integer cylinderTotal = this.getInfoTotalByRegionCode(code);
            Integer cylinderUnitTotal = cylinderUnitServiceImpl.getUnitTotalByRegionCode(code);
            Integer cylinderUnitWarn = cylinderUnitServiceImpl.getWarnNum(code);
            Integer cylinderInfoWarn = this.getWarnNum(code);
            int warmTotal = cylinderUnitWarn + cylinderInfoWarn;
            String parentCode = "";
            if ("610000".equals(code)) {
                parentCode = "-1";
            } else if (!"00".equals(code.substring(4, 6))) {
                parentCode = code.substring(0, 4) + "00";
            } else {
                parentCode = "610000";
            }
            temp.setCylinderNum(Long.valueOf(cylinderTotal));
            temp.setParentRegionCode(parentCode);
            temp.setRegionCode(regionModel.getRegionCode() + "");
            temp.setUnitNum(Long.valueOf(cylinderUnitTotal));
            temp.setWarnNum((long) warmTotal);
            cylinderAreaDataServiceImpl.createWithModel(temp);
        });
    }

    /**
     * 按区域统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void addIntegrityData() {
        cylinderIntegrityDataServiceImpl.remove(new LambdaQueryWrapper<CylinderIntegrityData>());
        countByRegion(regionModel -> {
            List<CylinderUnit> unitlist = cylinderUnitServiceImpl.list(new LambdaQueryWrapper<CylinderUnit>().like(CylinderUnit::getRegionCode, regionModel));
            List<CylinderIntegrityDataDto> tempList = new LinkedList<>();
            unitlist.forEach(t -> {
                CylinderIntegrityDataDto temp = new CylinderIntegrityDataDto();
                String appId = t.getAppId();
                Double totalIntegirty = 0d;
                // tz_cylinder_info
                Double unitIntegirty = t.getIntegrity();
                //tz_cylinder_tags
                Double tagIntegirty = cylinderTagsServiceImpl.queryIntegirtyByAppId(appId);
                //tz_cylinder_info
                Double infoIntegirty = this.queryIntegirtyByAppId(appId);
                // tz_cylinder_filling_record 30天内
                Double recordIntegirty = cylinderFillingRecordServiceImpl.queryIntegirtyByAppId(appId);
                //tz_cylinder_filling  30天内
                Double fillingIntegirty = cylinderFillingServiceImpl.queryIntegirtyByAppId(appId);
                //tz_cylinder_filling_check 30天内
                Double checkIntegirty = cylinderFillingCheckServiceImpl.queryIntegirtyByAppId(appId);
                totalIntegirty = (unitIntegirty + tagIntegirty + infoIntegirty + recordIntegirty + fillingIntegirty + checkIntegirty) / 6;
                BigDecimal bg = new BigDecimal(totalIntegirty);
                totalIntegirty = bg.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
                temp.setAppId(appId);
                temp.setRegionCode(String.valueOf(regionModel.getRegionCode()));
                temp.setIntegrity(totalIntegirty);
                temp.setUnitName(t.getUnitName());
                // 判断list 是否达到5个，如果达到则对比最后一个进行替换
                if (tempList.size() == 5) {
                    if (tempList.get(0).getIntegrity() < totalIntegirty) {
                        tempList.set(0, temp);
                    }
                } else {
                    tempList.add(temp);
                }
                tempList.sort(Comparator.comparing(CylinderIntegrityDataDto::getIntegrity));
            });
            tempList.forEach(t -> {
                cylinderIntegrityDataServiceImpl.createWithModel(t);
            });
        });
    }

    /**
     * 企业总量按区域统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void getCylinderUnitInfo() {
        cylinderUnitDataServiceImpl.remove(new LambdaQueryWrapper<CylinderUnitData>());
        countByRegion(regionModel -> {
            String regionCode = String.valueOf(regionModel.getRegionCode());
            Integer cylinderUnitTotal = cylinderUnitServiceImpl.getUnitTotalByRegionCode(regionCode);
            Double lastUnitTotal = Double.valueOf(cylinderUnitServiceImpl.getLastMonthUnitTotal(regionCode));
            Double monthUnitLastInfo = Double.valueOf(cylinderUnitServiceImpl.getMonthBeforeLastUnitTotal(regionCode));
            double changeNum = lastUnitTotal - monthUnitLastInfo;
            double percent = 0d;
            if (monthUnitLastInfo != 0) {
                percent = changeNum / monthUnitLastInfo;
                BigDecimal bg = new BigDecimal(percent);
                percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            CylinderUnitDataDto temp = new CylinderUnitDataDto();
            temp.setChangeSum((long) changeNum);
            temp.setChangePercent((int) (percent * 100) + "");
            temp.setRegionCode(regionCode);
            temp.setTotalSum((long) cylinderUnitTotal);
            cylinderUnitDataServiceImpl.createWithModel(temp);
        });
    }

    /**
     * 气瓶总量按区域统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void getCylinderInfo() {
        cylinderInfoDataServiceImpl.remove(new LambdaQueryWrapper<>());
        countByRegion(regionModel -> {
            CylinderInfoDataDto temp = new CylinderInfoDataDto();
            String regionCode = String.valueOf(regionModel.getRegionCode());
            Integer cylinderTotal = this.getInfoTotalByRegionCode(regionCode);//当前总数
            Double lastInfoTotal = Double.valueOf(this.getLastMonthInfoTotal(regionCode));//上月总数
            Double monthBeforeLastInfo = Double.valueOf(this.getMonthBeforeLastInfoTotal(regionCode));//上上月总数
            double percent = 0d;
            if (monthBeforeLastInfo != 0) {
                percent = (lastInfoTotal - monthBeforeLastInfo) / monthBeforeLastInfo;
                BigDecimal bg = new BigDecimal(percent);
                percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            temp.setChangeSum((long) (lastInfoTotal - monthBeforeLastInfo));
            temp.setChangePercent((int) (percent * 100) + "");
            temp.setRegionCode(regionCode);
            temp.setTotalSum((long) cylinderTotal);
            cylinderInfoDataServiceImpl.createWithModel(temp);
        });
    }

    /**
     * 按单位统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synUnitCylinderInfoData() {
        cylinderInfoDataUnitServiceImpl.remove(new LambdaQueryWrapper<CylinderInfoDataUnit>());
        countByUnit(cylinderUnit -> {
            CylinderInfoDataUnitDto temp = new CylinderInfoDataUnitDto();
            temp.setAppId(cylinderUnit.getAppId());
            int count = this.count(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getAppId, cylinderUnit.getAppId()));//当前总数
            temp.setTotalSum((long) count);
            Double thismonth = Double.valueOf(baseMapper.getLastMonthInfoTotalUnit(cylinderUnit.getAppId()));//上月总数
            Double lastmonth = Double.valueOf(baseMapper.getMonthBeforeLastInfoTotalUnit(cylinderUnit.getAppId()));//上上月总数
            double percent = 0d;
            if (lastmonth != 0) {
                percent = (thismonth - lastmonth) / lastmonth;
                BigDecimal bg = new BigDecimal(percent);
                percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            temp.setChangeSum((long) (thismonth - lastmonth));
            temp.setChangePercent((int) (percent * 100) + "");
            cylinderInfoDataUnitServiceImpl.createWithModel(temp);
        });
    }

    /**
     * 充装量按单位和月统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synUnitCylinderFillingData() {
        cylinderFillingDataUnitServiceImpl.remove(new LambdaQueryWrapper<CylinderFillingDataUnit>());
        countByUnit(cylinderUnit -> {
            // 按照月份 获取数据 取一年数据
            Calendar calendar = Calendar.getInstance();
            // 按月份获取充装量
            // 当月与上月 对比获取数据
            for (int i = 0; i < 12; i++) {
                // 获取当月数据
                CylinderFillingDataUnitDto temp = new CylinderFillingDataUnitDto();
                String year = calendar.get(Calendar.YEAR) + "";
                int month = calendar.get(Calendar.MONTH) + 1;
                String monthStr = month < 10 ? "0" + month : month + "";
                temp.setFillingYear(year);
                temp.setFillingMonth(monthStr);
                //本月
                Double thisMonth = cylinderFillingRecordServiceImpl.getFillingSumByMonth(cylinderUnit.getAppId(), calendar.getTime());
                temp.setTotalSum(thisMonth);
                calendar.add(Calendar.MONTH, -1);
                //上月
                Double lastMonth = cylinderFillingRecordServiceImpl.getFillingSumByMonth(cylinderUnit.getAppId(), calendar.getTime());
                double percent = 0d;
                if (lastMonth != 0) {
                    percent = (thisMonth - lastMonth) / lastMonth;
                    BigDecimal bg = new BigDecimal(percent);
                    percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                }
                temp.setChangePercent((int) (percent * 100) + "");
                temp.setAppId(cylinderUnit.getAppId());
                temp.setChangeSum(thisMonth - lastMonth);
                cylinderFillingDataUnitServiceImpl.createWithModel(temp);
            }
        });
    }

    /**
     * 按单位统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synUnitCylinderTagsData() {
        cylinderTagsDataUnitServiceImpl.remove(new LambdaQueryWrapper<CylinderTagsDataUnit>());
        countByUnit(cylinderUnit -> {
            CylinderTagsDataUnitDto temp = new CylinderTagsDataUnitDto();
            temp.setAppId(cylinderUnit.getAppId());
            int cylinder = this.count(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getAppId, cylinderUnit.getAppId()));
            int tags = cylinderTagsServiceImpl.count(new LambdaQueryWrapper<CylinderTags>().eq(CylinderTags::getAppId, cylinderUnit.getAppId()));
            double percent = 0d;
            if (tags != 0) {
                percent = (double) cylinder / (double) tags;
                BigDecimal bg = new BigDecimal(percent);
                percent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            temp.setCylinderSum((long) cylinder);
            temp.setTagsSum((long) tags);
            temp.setTagPercent(percent * 100);
            cylinderTagsDataUnitServiceImpl.createWithModel(temp);
        });
    }

    /**
     * 按单位统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synUnitIntegrityData() {
        cylinderIntegrityDataUnitServiceImpl.remove(new LambdaQueryWrapper<CylinderIntegrityDataUnit>());
        countByUnit(cylinderUnit -> {
            // 企业信息
            CylinderIntegrityDataUnitDto uninInfo = new CylinderIntegrityDataUnitDto();
            uninInfo.setAppId(cylinderUnit.getAppId());
            uninInfo.setDataType("企业信息");
            Double unitIntegirty = cylinderUnit.getIntegrity();
            uninInfo.setIntegrity(unitIntegirty);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(uninInfo);
            // 气瓶基本信息
            CylinderIntegrityDataUnitDto cylinderInfo = new CylinderIntegrityDataUnitDto();
            cylinderInfo.setAppId(cylinderUnit.getAppId());
            cylinderInfo.setDataType("气瓶基本信息");
            Double cylinderIntegirty = this.queryIntegirtyByAppId(cylinderUnit.getAppId());
            cylinderInfo.setIntegrity(cylinderIntegirty);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(cylinderInfo);
            // 气瓶标签信息
            CylinderIntegrityDataUnitDto cylinderTag = new CylinderIntegrityDataUnitDto();
            cylinderTag.setAppId(cylinderUnit.getAppId());
            cylinderTag.setDataType("气瓶标签信息");
            Double tagIntegirty = cylinderTagsServiceImpl.queryIntegirtyByAppId(cylinderUnit.getAppId());
            cylinderTag.setIntegrity(tagIntegirty);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(cylinderTag);
            // 气瓶检验信息
            CylinderIntegrityDataUnitDto cylinderInspection = new CylinderIntegrityDataUnitDto();
            cylinderInspection.setAppId(cylinderUnit.getAppId());
            cylinderInspection.setDataType("气瓶检验信息");
            cylinderInspection.setIntegrity(0d);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(cylinderInspection);
            // 充装前检查
            CylinderIntegrityDataUnitDto cylinderFilling = new CylinderIntegrityDataUnitDto();
            cylinderFilling.setAppId(cylinderUnit.getAppId());
            cylinderFilling.setDataType("充装前检查");
            Double fillingIntegirty = cylinderFillingServiceImpl.queryIntegirtyByAppId(cylinderUnit.getAppId());
            cylinderFilling.setIntegrity(fillingIntegirty);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(cylinderFilling);
            // 充装信息
            CylinderIntegrityDataUnitDto cylinderRecord = new CylinderIntegrityDataUnitDto();
            cylinderRecord.setAppId(cylinderUnit.getAppId());
            cylinderRecord.setDataType("充装信息");
            Double recordIntegirty = cylinderFillingRecordServiceImpl.queryIntegirtyByAppId(cylinderUnit.getAppId());
            cylinderRecord.setIntegrity(recordIntegirty);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(cylinderRecord);
            // 充装后复查
            CylinderIntegrityDataUnitDto cylinderCheck = new CylinderIntegrityDataUnitDto();
            cylinderCheck.setAppId(cylinderUnit.getAppId());
            cylinderCheck.setDataType("充装后复查");
            Double checkIntegirty = cylinderFillingCheckServiceImpl.queryIntegirtyByAppId(cylinderUnit.getAppId());
            cylinderCheck.setIntegrity(checkIntegirty);
            cylinderIntegrityDataUnitServiceImpl.createWithModel(cylinderCheck);
        });
    }

    /**
     * 充装详情按单位统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synUnitFillingCheckData() {
        cylinderFillingCheckDataUnitServiceImpl.remove(new LambdaQueryWrapper<CylinderFillingCheckDataUnit>());
        countByUnit(cylinderUnit -> {
            // 按照月份 获取数据 取一年数据
            Calendar c = Calendar.getInstance();
            // 按月份获取充装量
            // 当月与上月 对比获取数据
            for (int i = 0; i < 12; i++) {
                // 获取当月数据
                CylinderFillingCheckDataUnitDto temp = new CylinderFillingCheckDataUnitDto();
                String year = c.get(Calendar.YEAR) + "";
                int month = c.get(Calendar.MONTH) + 1;
                String monthStr = month < 10 ? "0" + month : month + "";
                temp.setFillingMonth(monthStr);
                temp.setFillingYear(year);
                temp.setFillingDate(year + "-" + monthStr);
                Integer countThisMonth = cylinderFillingRecordServiceImpl.getFillingCountByMonth(cylinderUnit.getAppId(), c.getTime());
                temp.setTotalSum((long) countThisMonth);
                // 获取本月数据
                Integer fillingCount = cylinderFillingServiceImpl.getFillingCountByMonth(cylinderUnit.getAppId(), c.getTime());
                Integer fillingCheckCount = cylinderFillingCheckServiceImpl.getFillingCountByMonth(cylinderUnit.getAppId(), c.getTime());
                // 充装前检查率：充装前检查次数/充装次数
                double before = 0d;
                if (countThisMonth != 0) {
                    before = (double) (fillingCount) / (double) countThisMonth;
                }
                temp.setFillingCount((long) fillingCount);
                temp.setFillingPercent(before * 100);
                // 充装后检查率：充装后检查次数/充装次数
                double after = 0d;
                if (countThisMonth != 0) {
                    after = (double) (fillingCheckCount) / (double) countThisMonth;
                }
                temp.setFillingCheckCount((long) fillingCheckCount);
                temp.setFillingCheckPercent(after * 100);
                // 充装合格率：充装前检查合格次数+充装后检查合格次数/2*充装次数
                double passed = 0d;
                // 充装前检查合格次数
                Integer fillingPassedCount = cylinderFillingServiceImpl.getFillingPassedCountByMonth(cylinderUnit.getAppId(), c.getTime());
                // 充装后检查合格次数
                Integer fillingCheckPassedCount = cylinderFillingCheckServiceImpl.getFillingPassedCountByMonth(cylinderUnit.getAppId(), c.getTime());
                if (countThisMonth != 0) {
                    passed = ((double) (fillingPassedCount) + (double) fillingCheckPassedCount) / (double) (2 * countThisMonth);
                }
                temp.setFillingPassedCount((long) (fillingPassedCount + fillingCheckPassedCount));
                temp.setTotalSumDouble((long) 2 * countThisMonth);
                temp.setFillingPassedPercent(passed * 100);
                temp.setAppId(cylinderUnit.getAppId());
                c.add(Calendar.MONTH, -1);
                cylinderFillingCheckDataUnitServiceImpl.createWithModel(temp);
            }
        });
    }

    /**
     * 充装量、卸液量按单位统计
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 2 * * ?")
    public void synFillingUnloadUnitData() {
        cylinderFillingUnloadDataUnitServiceImpl.remove(new LambdaQueryWrapper<CylinderFillingUnloadDataUnit>());
        countByUnit(cylinderUnit -> {
            Calendar now = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (int i = 0; i < 30; i++) {
                now.add(Calendar.DATE, -1);
                CylinderFillingUnloadDataUnitDto temp = new CylinderFillingUnloadDataUnitDto();
                Double fillingSum = cylinderFillingRecordServiceImpl.getFillingSumByDate(cylinderUnit.getAppId(), now.getTime());
                Double unloadSum = 0d;
                temp.setFillingSum(fillingSum);
                temp.setAppId(cylinderUnit.getAppId());
                temp.setStatisDate(now.getTime());
                temp.setStatisDateStr(sdf.format(now.getTime()));
                temp.setUnloadSum(unloadSum);
                cylinderFillingUnloadDataUnitServiceImpl.createWithModel(temp);
            }
        });
    }

    /**
     * 根据月份统计
     */
    private void countByMonth(IntConsumer consumer) {
        for (int i = 0; i < 12; i++) {
            consumer.accept(i);
        }
    }

    /**
     * 根据单位统计
     */
    private void countByUnit(Consumer<CylinderUnit> consumer) {
        List<CylinderUnit> units = cylinderUnitServiceImpl.list();
        units.forEach(consumer);
    }

    /**
     * 根据区域统计
     */
    private void countByRegion(Consumer<RegionModel> consumer) {
        List<RegionModel> regionList = new ArrayList<>();
        Collection<RegionModel> regions = Systemctl.regionClient.queryForTree(null).getResult();
        regions.forEach(regionModel -> convertTreeToList(regionList, regionModel));
        regionList.forEach(consumer);
    }

    /**
     * 将区域树转为区域List列表
     */
    private void convertTreeToList(List<RegionModel> regionList, RegionModel region) {
        regionList.add(region);
        if (region.getChildren() != null) {
            region.getChildren().forEach(c -> {
                convertTreeToList(regionList, c);
            });
        }
    }

    public Integer getOverDateStatisticsNumber(String earlyWarningLevel) {
        return this.baseMapper.countOverDateNumber(earlyWarningLevel);
    }

    public Page<CylinderInfoDto> earlyWarningLevelPageList(Page<CylinderInfoDto> page, String earlyWarningLevel) {
        Page<CylinderInfoDto> result = this.baseMapper.queryPageListByEarlyWarningLevel(page, earlyWarningLevel);
        result.getRecords().forEach(r -> {
            r.setEarlyWarningLevelName(EarlyWarningLevelEnum.getEumByLevel(earlyWarningLevel).getName());
            r.setInspectionStatusDesc(EarlyWarningLevelEnum.getEumByLevel(earlyWarningLevel).getStatus());
        });

        return result;
    }

    public void calEarlyWarningLevel() {
        if (log.isDebugEnabled()) {
            log.debug("气瓶超期预警时间调用规则开始");
        }
        // 1.批量分组大小
        int size = 500;
        int total = this.count();
        int groupNumber = total / size + 1;
        // 2.批量小分组处理数据，调用规则
        for (int i = 0; i < groupNumber; i++) {
            Page<CylinderInfo> page = new Page<>();
            page.setCurrent(i);
            page.setSize(size);
            LambdaQueryWrapper<CylinderInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(CylinderInfo::getSequenceCode,CylinderInfo::getSequenceNbr).orderByDesc(CylinderInfo::getSequenceNbr);
            IPage<CylinderInfo> result = this.page(page, wrapper);
            for (CylinderInfo r : result.getRecords()) {
                // 设置token
                tzsAuthService.setRequestContext();
                // 调用规则
                this.touchRuleToCalLevel(r);
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("气瓶超期预警时间调用规则完成");
        }
    }

    private void touchRuleToCalLevel(CylinderInfo r) {
        Date now = new Date();
        String dateStr;
        try {
            dateStr = DateUtils.dateFormat(now,DateUtils.DATE_TIME_PATTERN);
        } catch (ParseException e) {
           throw  new RuntimeException("日期个时候失败");
        }
        //1.气瓶详情
        CylinderInfoDto cylinderInfoDto = this.getDetail(r.getSequenceCode());
        try {
            CylWarningMsgDto cylWarningMsgDto = new CylWarningMsgDto();
            int interval = DateUtils.dateBetweenIncludeToday(now, cylinderInfoDto.getNextInspectionDate()) - 1;
            cylWarningMsgDto.setNum(String.valueOf(interval));
            cylWarningMsgDto.setFactoryNum(cylinderInfoDto.getFactoryNum());
            cylWarningMsgDto.setUserType(cylinderInfoDto.getCustomType());
            cylWarningMsgDto.setUserPeople(cylinderInfoDto.getCustomName());
            cylWarningMsgDto.setUserPeoplePhone(cylinderInfoDto.getContactPhone());
            cylWarningMsgDto.setCylSeq(cylinderInfoDto.getSequenceCode());
            cylWarningMsgDto.setCompanyName(cylinderInfoDto.getUnitName());
            cylWarningMsgDto.setPhone(cylinderInfoDto.getPersonMobilePhone());
            cylWarningMsgDto.setPeople(cylinderInfoDto.getUnitPerson());
            cylWarningMsgDto.setCurrentTime(dateStr);
            // 2.循环调用规则 触发计算等级及发送消息
            if (log.isInfoEnabled()) {
                log.info("调用规则对象！+：{}", JSON.toJSONString(cylWarningMsgDto));
            }
            ruleTrigger.publish(cylWarningMsgDto, packageId, null);
        } catch (Exception e) {
            log.error("调用规则失败！:{},{}", JSON.toJSONString(cylinderInfoDto),e);
        }
    }

    public CylinderInfoDto getDetail(String sequenceCode) {
        CylinderInfoDto dto = this.baseMapper.getDetail(sequenceCode);
        dto.setInspectionStatusDesc(StringUtils.isNotEmpty(dto.getEarlyWarningLevel()) ? EarlyWarningLevelEnum.getEumByLevel(dto.getEarlyWarningLevel()).getStatus() : "");
        return dto;
    }

    public List<MsgLog> getMsgList(String sequenceCode, String terminalType) {
        LambdaQueryWrapper<MsgLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MsgLog::getRelationCode, sequenceCode);
        wrapper.eq(StringUtils.isNotEmpty(terminalType), MsgLog::getTerminalType, terminalType);
        wrapper.orderByDesc(MsgLog::getSendTime);
        return msgLogService.list(wrapper);
    }

    /**
     * 更新气瓶等级
     * @param sequenceCode 唯一表设
     * @param level 等级
     * @return CylinderInfo
     */
    public CylinderInfo updateEarlyWarningLevel(String sequenceCode, String level) {
        CylinderInfo cylinderInfo = this.getOne(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getSequenceCode, sequenceCode));
        cylinderInfo.setEarlyWarningLevel(level);
        cylinderInfo.setEarlyWarningLevelCalDate(new Date());
        this.updateById(cylinderInfo);
        return cylinderInfo;
    }

    public Boolean nextInspectionDateUpdate(List<CylinderInfoDto> cylinderInfoDtos) {
        // 1.更新下次检验日期
        List<CylinderInfo> cylinderInfos = new ArrayList<>();
        cylinderInfoDtos.forEach(c -> {
            CylinderInfo cylinderInfo = this.getOne(new LambdaQueryWrapper<CylinderInfo>().eq(CylinderInfo::getSequenceCode, c.getSequenceCode()));
            cylinderInfo.setNextInspectionDate(c.getNextInspectionDate());
            cylinderInfos.add(cylinderInfo);
        });
        if (!cylinderInfos.isEmpty()) {
            this.updateBatchById(cylinderInfos);
        }
        // 2.循环调用规则 触发计算等级及发送消息
        cylinderInfos.forEach(this::touchRuleToCalLevel);
        return Boolean.TRUE;
    }
}