package com.njcn.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nimbusds.jose.JWSObject;
import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.dto.LogInfoDTO;
import com.njcn.common.pojo.dto.UserTokenInfo;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils;
import com.njcn.db.constant.DbConstant;
import com.njcn.oss.constant.GeneralConstant;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.redis.pojo.enums.RedisKeyEnum;
import com.njcn.redis.utils.RedisMessageQueueUtil;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.system.enums.SystemResponseEnum;
import com.njcn.system.excel.UserLogExcel;
import com.njcn.system.mapper.AuditMapper;
import com.njcn.system.mapper.UserLogMapper;
import com.njcn.system.pojo.param.AuditParam;
import com.njcn.system.pojo.po.Config;
import com.njcn.system.pojo.po.UserLog;
import com.njcn.system.pojo.vo.*;
import com.njcn.system.service.AuditService;
import com.njcn.system.service.IConfigService;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.po.User;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

import static com.njcn.common.pojo.constant.LogInfo.UNKNOWN_USER;

/**
 * @version 1.0.0
 * @author: chenchao
 * @date: 2022/07/11 20:56
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AuditServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implements AuditService {

    private final AuditMapper auditMapper;

    @Value("${spring.datasource.dynamic.datasource.sjzx.url}")
    private String urls;

    private final GeneralInfo generalInfo;

    private final RedisUtil redisUtil;
    private final UserFeignClient userFeignClient;

    @Value("${clear.num}")
    private Integer clearHistoryLog;

    private final IConfigService iConfigService;

    /**
     * mqtt处理日志异步发布
     */
//    private final MqttPublisher publisher;

    /**
     * redis队列处理日志异步发布
     */
    private final RedisMessageQueueUtil redisMessageQueueUtil;

    private final FileStorageUtil fileStorageUtil;

    @Override
    public Page<AuditLogVO> getAuditLog(AuditParam auditParam) {
        List<AuditLogVO> auditLogVOS = new ArrayList<>();

        QueryWrapper<UserLog> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .between("sys_user_log.create_time", DateUtil.beginOfDay(DateUtil.parse(auditParam.getSearchBeginTime())),
                        DateUtil.endOfDay(DateUtil.parse(auditParam.getSearchEndTime())))
                .ne("sys_user_log.login_name", UNKNOWN_USER);
        if (StrUtil.isNotBlank(auditParam.getLoginName())) {
            queryWrapper.eq("sys_user_log.login_name", auditParam.getLoginName());
        }
        if (StrUtil.isNotBlank(auditParam.getOperateType())) {
            queryWrapper.eq("sys_user_log.operate_type", auditParam.getOperateType());
        }
        if (Objects.nonNull(auditParam.getType())) {
            queryWrapper.eq("sys_user_log.type", auditParam.getType());
        }
        if (Objects.nonNull(auditParam.getResult())) {
            queryWrapper.eq("sys_user_log.result", auditParam.getResult());
        }

        if (StrUtil.isNotBlank(auditParam.getSortBy()) && StrUtil.isNotBlank(auditParam.getOrderBy())) {
            if (DbConstant.DESC.equalsIgnoreCase(auditParam.getOrderBy())) {
                queryWrapper.orderByDesc("sys_user_log." + auditParam.getSortBy());
            } else {
                queryWrapper.orderByAsc("sys_user_log." + auditParam.getSortBy());
            }
        } else {
            queryWrapper.orderByDesc("sys_user_log.create_time");
        }


        Page<UserLog> info = this.page(new Page<>(auditParam.getPageNum(), auditParam.getPageSize()), queryWrapper);

        Page<AuditLogVO> page = BeanUtil.copyProperties(info, Page.class);
        if (CollUtil.isNotEmpty(info.getRecords())) {
            for (UserLog userLog : info.getRecords()) {
                AuditLogVO auditLogVO = new AuditLogVO();
                String updateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(userLog.getUpdateTime());
                auditLogVO.setTime(updateTime);
                auditLogVO.setUserName(userLog.getLoginName());
                auditLogVO.setOperate(userLog.getOperate());
                StringBuilder describe = new StringBuilder();
                describe.append(auditLogVO.getUserName()).append("在").append(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(userLog.getUpdateTime())).append("在").append(userLog.getIp()).append("执行了").append(userLog.getOperate()).append("，结果为");
                if (userLog.getResult() == 1) {
                    describe.append("成功");
                }
                if (userLog.getResult() == 0) {
                    describe.append("失败").append("，失败原因为").append(userLog.getFailReason());
                }
                auditLogVO.setDescribe(describe.toString());
                auditLogVO.setType(userLog.getType() == 0 ? "业务事件" : "系统事件");
                auditLogVO.setResult(userLog.getResult() == 0 ? "失败" : "成功");
                auditLogVO.setIp(userLog.getIp());
                if (userLog.getLevel() == 0) {
                    auditLogVO.setLevel("普通");
                }
                if (userLog.getLevel() == 1) {
                    auditLogVO.setLevel("中等");
                }
                if (userLog.getLevel() == 2) {
                    auditLogVO.setLevel("严重");
                }
                auditLogVOS.add(auditLogVO);
            }
        }
        //当前页数据
        page.setRecords(auditLogVOS);
        return page;
    }

    @Override
    @Async("asyncExecutor")
    public void saveAuditLog(HttpServletRequest request, AuditParam auditParam, String methodDescribe) {
        //处理审计日志
        String loginName;
        String userName;
        String userIndex;
        loginName = RequestUtil.getLoginNameByPayload(request);
        userName = RequestUtil.getUserNickname(request);
        userIndex = RequestUtil.getUserIndex(request);
        String result = CommonResponseEnum.SUCCESS.getMessage();
        String ip = RequestUtil.getRealIp(request);
        String type = LogEnum.SYSTEM_COMMON.getOperateType();
        String level = LogEnum.SYSTEM_COMMON.getOperateLevel();
        String operateType = OperateType.QUERY;
        Integer severity = levelStringToNumber(level);
        if (auditParam.isExport()) {
            methodDescribe = "审计日志列表导出";
            LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, userName, ip, methodDescribe, operateType, "失败".equalsIgnoreCase(result) ? 0 : 1, "", severity, "业务事件".equalsIgnoreCase(type) ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now());
            redisMessageQueueUtil.pushMessage(
                    RedisKeyEnum.USER_LOG_QUEUE.getKey(),
                    PubUtils.obj2json(logInfoDTO)
            );
//            publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false);
        } else {
            if (StrUtil.isNotBlank(auditParam.getSortBy()) && StrUtil.isNotBlank(auditParam.getOrderBy())) {
                methodDescribe = methodDescribe.concat("并以")
                        .concat(auditParam.getSortName())
                        .concat("进行")
                        .concat(DbConstant.DESC.equalsIgnoreCase(auditParam.getOrderBy()) ? "降序" : "升序")
                        .concat("查询");
                LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, userName, ip, methodDescribe, operateType, "失败".equalsIgnoreCase(result) ? 0 : 1, "", severity, "业务事件".equalsIgnoreCase(type) ? 0 : 1, generalInfo.getMicroServiceName(), userIndex, LocalDateTime.now());
                redisMessageQueueUtil.pushMessage(
                        RedisKeyEnum.USER_LOG_QUEUE.getKey(),
                        PubUtils.obj2json(logInfoDTO)
                );
//                publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false);

            }
        }


    }

    @Override
    public void logFileWriter() {
        TimeInterval timeInterval = new TimeInterval();
        //限制多次点击
        redisUtil.delete("logFileWriter");
        String logFileWriter = redisUtil.getStringByKey("logFileWriter");
        if (StrUtil.isNotBlank(logFileWriter) || ObjectUtil.equals(logFileWriter, "1")) {
            throw new BusinessException(SystemResponseEnum.MULTIPLE_CLICKS_LOG_FILE_WRITER);
        }
        redisUtil.saveByKeyWithExpire("logFileWriter", "1", 600L);


        Config config = iConfigService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getState, DataStateEnum.ENABLE.getCode()));
        LocalDateTime nowDate = LocalDateTime.now();
        LocalDateTime agoDate = nowDate.minusMonths(config.getLogTime()).with(TemporalAdjusters.firstDayOfMonth());
        String date = agoDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
        //结束时间
        String endTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH_mm_ss").format(nowDate);
        //文件名
        QueryWrapper<UserLog> aa = new QueryWrapper<>();
        aa.select("id");
        aa.ge("sys_user_log.update_time", date);
        aa.le("sys_user_log.update_time", endTime);
        String nowTime = date + "至" + endTime;

        //必须放到循环外，否则会刷新流
        ExcelWriter excelWriter =null;
        FileInputStream fileInputStream;
        File file = null;
        try {
            if (generalInfo.getBusinessFileStorage() == GeneralConstant.LOCAL_DISK) {
                file = new File(generalInfo.getBusinessTempPath() + File.separator + OssPath.LOGBAK);
                if (!file.exists() && !file.isDirectory()) {
                    file.mkdir();
                }
                excelWriter = EasyExcel.write(generalInfo.getBusinessTempPath() + File.separator + OssPath.LOGBAK + nowTime + ExcelTypeEnum.XLSX.getValue(), UserLogExcel.class).build();
            } else if (generalInfo.getBusinessFileStorage() == GeneralConstant.HUAWEI_OBS || generalInfo.getBusinessFileStorage() == GeneralConstant.MINIO_OSS) {
                file = File.createTempFile(date+"_"+endTime,".xlsx");
                excelWriter = EasyExcel.write(file, UserLogExcel.class).build();
            }
        }catch (Exception e){
            log.error("获取文件服务器异常");
            redisUtil.delete("logFileWriter");
            e.printStackTrace();
        }


        try {
            //记录总数:实际中需要根据查询条件进行统计即可:一共多少条
            int totalCount = this.count(aa);
            //每一个Sheet存放100w条数据
            int sheetDataRows = 1000000;
            //每次写入的数据量20w,每页查询20W
            int writeDataRows = 200000;
            //计算需要的Sheet总数量
            int sheetNum = totalCount % sheetDataRows == 0 ? (totalCount / sheetDataRows) : (totalCount / sheetDataRows + 1);
            //计算一般情况下每一个Sheet需要写入的次数(一般情况不包含最后一个sheet,因为最后一个sheet不确定会写入多少条数据)
            int oneSheetWriteCount = sheetDataRows / writeDataRows;
            //计算最后一个sheet需要写入的次数
            int lastSheetWriteCount = totalCount % sheetDataRows == 0 ? oneSheetWriteCount : (totalCount % sheetDataRows % writeDataRows == 0 ? (totalCount / sheetDataRows / writeDataRows) : (totalCount / sheetDataRows / writeDataRows + 1));
            //开始分批查询分次写入
            for (int i = 0; i < sheetNum; i++) {

                //循环写入次数: j的自增条件是当不是最后一个Sheet的时候写入次数为正常的每个Sheet写入的次数,如果是最后一个就需要使用计算的次数lastSheetWriteCount
                for (int j = 0; j < (i != sheetNum - 1 ? oneSheetWriteCount : lastSheetWriteCount); j++) {
                    //分页查询一次20w
                    //查询分页列表---按照自己的业务查列表，分页这个一定要使用这个：page1.getPageNum(),page1.getPageSize()！！！
                    Page<UserLogExcel> userLogExcelPage = auditMapper.queryExportLimit(new Page<>(j + 1 + oneSheetWriteCount * i, writeDataRows), date, endTime);
                    List<UserLogExcel> list = userLogExcelPage.getRecords();
                    //写入到excel:
                    WriteSheet writeSheet = EasyExcel.writerSheet(i, "Sheet" + (i + 1)).head(UserLogExcel.class)
                            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();

                    System.out.println("备份日志文件执行到这一步aaaa"+":"+list.size());
                    excelWriter.write(list, writeSheet);
                }
            }
            excelWriter.finish();
            if (generalInfo.getBusinessFileStorage() == GeneralConstant.HUAWEI_OBS || generalInfo.getBusinessFileStorage() == GeneralConstant.MINIO_OSS) {
                try {
                    System.out.println("备份日志文件执行到这一步"+file.getName()+":"+file.length()/1024/1024+"MB");
                    fileInputStream = new FileInputStream(file);
                    fileStorageUtil.uploadStream(fileInputStream,OssPath.LOGBAK,file.getName());
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                }finally {
                    file.delete();
                }
            }
        } catch (Exception e) {
            redisUtil.delete("logFileWriter");
            e.printStackTrace();
        } finally {

        }


        redisUtil.delete("logFileWriter");
        System.out.println("日志备份结束，共花费时间" + timeInterval.intervalSecond() + "S");
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void recoverLogFile() {
        String logFileWriter = redisUtil.getStringByKey("recoverLogFile");
        if (StrUtil.isNotBlank(logFileWriter) || ObjectUtil.equals(logFileWriter, "1")) {
            throw new BusinessException(SystemResponseEnum.MULTIPLE_CLICKS_LOG_FILE_WRITER);
        }
        redisUtil.saveByKeyWithExpire("recoverLogFile", "1", 600L);
        FileInputStream in = null;
        File newFile = null;
        try {
            newFile = getLastFile();
            if (FileUtil.isEmpty(newFile)) {
                throw new BusinessException(SystemResponseEnum.NOT_FIND_FILE);
            }
            in = new FileInputStream(newFile);
            Set<String> logIndex = new HashSet<>(this.baseMapper.getAllIndex());
            List<UserLog> userLogs = new ArrayList<>();
            EasyExcel.read(newFile.getPath(), UserLog.class, new AnalysisEventListener<UserLog>() {
                @Override
                public void invoke(UserLog userLog, AnalysisContext analysisContext) {
                    // 将读取到的每一行存入reportDetails集合中
                    if (!logIndex.contains(userLog.getId())) {
                        userLogs.add(userLog);
                    }
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                }
            }).sheet().doRead();
            if (CollUtil.isNotEmpty(userLogs)) {
                // 执行批量插入
                saveLogsBatch(userLogs, 1500);
            }
        } catch (Exception e) {
            redisUtil.delete("recoverLogFile");
            throw new BusinessException(SystemResponseEnum.LOG_EXCEPTION);
        } finally {
            IOUtils.closeQuietly(in);

            if(generalInfo.getBusinessFileStorage() == GeneralConstant.HUAWEI_OBS || generalInfo.getBusinessFileStorage() == GeneralConstant.MINIO_OSS) {
                newFile.delete();
            }
        }
        redisUtil.delete("recoverLogFile");
    }


    /***
     * 批量插入日志
     * @author hongawen
     * @date 2023/5/30 15:56
     * @return boolean
     */
    public boolean saveLogsBatch(Collection<UserLog> userLogs, int batchSize) {
        try {
            int size = userLogs.size();
            int idxLimit = Math.min(batchSize, size);
            List<UserLog> userLogTemp = new ArrayList<>(userLogs);
            //保存单批提交的数据集合
            if (idxLimit == batchSize) {
                int times = size / idxLimit + 1;
                for (int i = 1; i <= times; i++) {
                    if (size > idxLimit) {
                        List<UserLog> temp = userLogTemp.subList(0, idxLimit);
                        this.baseMapper.insertBatchSomeColumn(temp);
                        temp.clear();
                        size = size - idxLimit;
                    } else {
                        this.baseMapper.insertBatchSomeColumn(userLogTemp);
                    }
                }
            } else {
                this.baseMapper.insertBatchSomeColumn(userLogTemp);
            }
        } catch (Exception e) {
            log.error("saveBatch fail", e);
            return false;
        }
        return true;
    }


    @Override
    public Page<AuditLogCusVO> censusAuditLog(AuditParam auditParam) {
        auditParam.setSearchBeginTime(DateUtil.beginOfDay(DateUtil.parse(auditParam.getSearchBeginTime())).toString());
        auditParam.setSearchEndTime(DateUtil.endOfDay(DateUtil.parse(auditParam.getSearchEndTime())).toString());
        //待分页数据总量
        return auditMapper.selectCensusAuditLog(new Page<>(auditParam.getPageNum(), auditParam.getPageSize()), auditParam);
    }

    @Override
    public void clearHistoryLog() {
        Config config = iConfigService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getState, DataStateEnum.ENABLE.getCode()));
        Integer logTime;
        if (ObjectUtil.isNotNull(config)) {
            logTime = config.getLogTime();
        } else {
            logTime = clearHistoryLog;
        }
        LocalDateTime nowDate = LocalDateTime.now();
        LocalDateTime agoDate = nowDate.minusMonths(logTime).with(TemporalAdjusters.firstDayOfMonth());
        String date = agoDate.format(DateTimeFormatter.ISO_LOCAL_DATE);

        QueryWrapper<UserLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("sys_user_log.create_time", date);
        auditMapper.deleteByTime(queryWrapper);
    }

    @Override
    public Float getMemoInfo() {
        // 1. 判空兜底，防止@Value注入为空/空字符串
        if (StrUtil.isBlank(urls)) {
            log.error("getMemoInfo error: 数据库链接地址urls为空，无法截取schema");
            return 0.0F;
        }
        String schema = null;
        try {
            // 2. 先获取最后一个/的下标，截取库名起始位
            int lastSlashIndex = urls.lastIndexOf("/");
            // 3. 先获取?的下标，截取库名结束位
            int questionMarkIndex = urls.indexOf("?");
            // 4. 兼容两种场景：有问号参数、无问号参数
            if (lastSlashIndex > -1) {
                if (questionMarkIndex > lastSlashIndex) {
                    // 正常场景：url带?后缀参数 → 截取 / 和 ? 之间的库名
                    schema = urls.substring(lastSlashIndex + 1, questionMarkIndex);
                } else {
                    // 兼容场景：url不带?后缀参数 → 截取 / 之后的全部内容作为库名
                    schema = urls.substring(lastSlashIndex + 1);
                }
            }
        } catch (Exception e) {
            // 5. 捕获所有异常（下标越界、格式异常等），兜底处理
            log.error("getMemoInfo 截取数据库schema失败，urls={}, 异常信息:{}", urls, e);
            return 0.0F;
        }
        // 6. 最终判空，防止截取结果为空
        if (StrUtil.isBlank(schema)) {
            log.error("getMemoInfo 截取到的数据库schema为空，urls={}", urls);
            return 0.0F;
        }
        // 7. 调用mapper查询，返回结果
        Float memoInfo = this.baseMapper.getMemoInfo(schema);
        // 8. 兼容mapper返回null的情况，避免接口返回null报错
        return ObjectUtil.isNull(memoInfo) ? 0.0F : memoInfo;
    }

    @Override
    public List<OnlineUsersVO> getOnlineUsers() throws ParseException {
        List<OnlineUsersVO> info = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        Map<String, Long> time = new HashMap<>();
        List<UserTokenInfo> listAllValues = (List<UserTokenInfo>) redisUtil.getLikeListAllValues(SecurityConstants.TOKEN_ONLINE_PREFIX);
        for (UserTokenInfo listAllValue : listAllValues) {
            String payload = StrUtil.toString(JWSObject.parse(listAllValue.getRefreshToken()).getPayload());
            cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(payload);
            time.put(jsonObject.getStr(SecurityConstants.USER_INDEX_KEY), Long.valueOf(jsonObject.getStr("exp")));
            ids.add(jsonObject.getStr(SecurityConstants.USER_INDEX_KEY));
        }

        List<User> data = userFeignClient.getUserByIdList(ids).getData();
        OnlineUsersVO vo;
        if (CollUtil.isNotEmpty(data)) {
            for (User datum : data) {
                vo = BeanUtil.copyProperties(datum, OnlineUsersVO.class);
                Long integer = time.get(datum.getId());
                DateTime date = DateUtil.date(integer * 1000);
                vo.setTime(date.toString());
                info.add(vo);
            }
        }
        return info;
    }

    @Override
    public LogParamVO saveLogParam() {
        LogParamVO logParamVO = new LogParamVO();
        List<UserLog> userLogs = auditMapper.selectUserLog();
        List<ValuePO> loginNameList = userLogs.stream().map(UserLog::getLoginName).distinct().map(temp -> {
            ValuePO valuePO = new ValuePO();
            valuePO.setValue(temp);
            return valuePO;
        }).collect(Collectors.toList());

        List<ValuePO> operateTypeList = userLogs.stream().map(UserLog::getOperateType).distinct().map(temp -> {
            ValuePO valuePO = new ValuePO();
            valuePO.setValue(temp);
            return valuePO;
        }).collect(Collectors.toList());
        logParamVO.setLoginName(loginNameList);
        logParamVO.setOperateType(operateTypeList);
        return logParamVO;
    }

    /**
     * 返回一个最新修改日期的文件
     */
    public File getLastFile() {
        File parentFile = null;
        if(generalInfo.getBusinessFileStorage() == GeneralConstant.LOCAL_DISK){
            parentFile = new File(generalInfo.getBusinessTempPath() + File.separator + OssPath.LOGBAK);
        }else if(generalInfo.getBusinessFileStorage() == GeneralConstant.HUAWEI_OBS || generalInfo.getBusinessFileStorage() == GeneralConstant.MINIO_OSS){
            try {
                parentFile = fileStorageUtil.getLastFile("excelreport",OssPath.LOGBAK);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        //文件夹下的所有子文件数组
        File[] files = parentFile.listFiles();
        List<Date> list;
        if (ArrayUtil.isNotEmpty(files)) {
            list = Arrays.stream(files).map(FileUtil::lastModifiedTime).collect(Collectors.toList());
            list.sort(Comparator.reverseOrder());
            return Arrays.stream(files).filter(tempFile -> FileUtil.lastModifiedTime(tempFile).equals(list.get(0))).collect(Collectors.toList()).get(0);
        }
        return parentFile;
    }

    /**
     * 严重度 文字 转 数字
     */
    private Integer levelStringToNumber(String level) {
        switch (level) {
            case "中等":
                return 1;
            case "严重":
                return 2;
            default:
                return 0;
        }
    }

}
