
package com.lideeyunji.core.framework.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.lideeyunji.core.framework.config.btncommand.filter.CriteriaList;
import com.lideeyunji.core.framework.config.btncommand.filter.FormatCriteriaList;
import com.lideeyunji.core.framework.config.btncommand.filter.RemoveFieldCriteriaList;
import com.lideeyunji.core.framework.config.btncommand.filter.ViewFieldCriteriaList;
import com.lideeyunji.core.framework.config.excel.check.ExcelCheckEnums;
import com.lideeyunji.core.framework.config.excel.check.IExcelCheckStrategy;
import com.lideeyunji.core.framework.config.excel.check.param.ExcelCheckParams;
import com.lideeyunji.core.framework.entity.*;
import com.lideeyunji.core.framework.mapper.*;
import com.lideeyunji.core.framework.params.SaveImportDataParam;
import com.lideeyunji.core.framework.params.vo.DbFormConfigVo;
import com.lideeyunji.core.framework.params.vo.role.DbFormRoleFieldVo;
import com.lideeyunji.core.framework.service.*;
import com.lideeyunji.core.framework.utils.Func;
import com.lideeyunji.tool.framework.common.util.json.JsonUtils;
import com.lideeyunji.tool.framework.excel.model.ExcelTitleModel;
import com.lideeyunji.tool.framework.excel.model.MoreSheetConfig;
import com.lideeyunji.tool.framework.exception.lideeYunJiException;
import com.lideeyunji.tool.framework.ip.core.utils.AreaUtils;
import com.lideeyunji.tool.framework.yunji.enums.LideeYunJiFieldTypeEnum;
import com.lideeyunji.tool.framework.yunji.tool.spring.SpringUtils;
import com.lideeyunji.tool.framework.sql.SqlHelper;
import com.lideeyunji.tool.framework.sql.build.buildmodel.wrapper.SqlInfoQueryWrapper;
import com.lideeyunji.tool.framework.yunji.adapter.IlideeYunjiAdapter;
import com.lideeyunji.tool.framework.yunji.component.redis.lideeYunjiRedisUtils;
import com.lideeyunji.tool.framework.yunji.enums.TableTypeEnum;
import com.lideeyunji.tool.framework.yunji.enums.YNEnum;
import com.lideeyunji.tool.framework.yunji.model.ResultDataModel;
import com.lideeyunji.tool.framework.yunji.utils.FuncBase;
import com.lideeyunji.tool.framework.yunji.utils.lideeYunJiUtils;
import com.lideeyunji.core.framework.params.model.ExcelImportDataDictModel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lideeyunji.tool.framework.sql.enums.DbTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.LinkedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 *
 */
@Slf4j
@Service
public class ExcelServiceImpl implements IExcelService {

    @Autowired
    private IFormService formService;

    @Autowired
    private LideeYunJiMapper lideeYunJiMapper;

    @Autowired
    private IFrameService frameService;

    @Autowired
    private IFrameSqlService sqlService;

    @Autowired
    private IExcelFileDataService excelDataService;

    @Autowired
    private lideeYunjiRedisUtils lideeYunjiRedisUtils;

    @Autowired
    private IExcelFileService excelFileService;

    @Autowired
    private IReportService reportService;

    @Autowired
    private ReportFieldMapper reportFieldMapper;

    @Autowired
    private IlideeYunjiAdapter lideeYunJiAdapter;

    @Autowired
    private IDbFormRoleService dbFormRoleService;


    @Autowired
    private FormFieldExportMapper exportMapper;

    @Autowired
    private FormFieldWebMapper fieldWebMapper;

    @Autowired
    private IlideeYunjiAdapter proxyAdapter;

    @Autowired
    private IFormService dbFormService;

    @Autowired
    private AdapterMapper adapterMapper;

    @Autowired
    private IEnhanceJavaService enhanceJavaService;

    /**
     * 导入Excel模版
     *
     * @param dbformId
     */
    @Override
    public MoreSheetConfig getImportExcelTemplate(Long dbformId) {
        FormEntity formEntity = formService.getById(dbformId);
        String sheetName = formEntity.getTableDescribe();//表描述

        List<Map<String, Object>> excelFieldList = lideeYunJiMapper.getExcelImportFieldList(dbformId);

        //Excel头部
        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();

        //Excel内容
        List<Map<String, Object>> dataList = new ArrayList<>();

        Map<String, Object> excelDataMap = new HashMap<>();

        for (Map<String, Object> dataMap : excelFieldList) {
            String field_code = lideeYunJiUtils.getMap2Str(dataMap, "field_code");
            String field_name = lideeYunJiUtils.getMap2Str(dataMap, "field_name");
            String import_example_txt = lideeYunJiUtils.getMap2Str(dataMap, "import_example_txt");

            //封装头部
            ExcelTitleModel titleModel = new ExcelTitleModel();
            titleModel.setTitle(field_name);
            //处理字典表
            Map<String, String> dictMap = formService.getDictKeyLabelMap(dbformId, field_code);
            List<String> dictLabelList = dictMap.values().stream()
                    .collect(Collectors.toList());
            titleModel.setDropdownOptionList(dictLabelList);

            //封装头部
            headMap.put(field_code, titleModel);

            //封装数据内容
            excelDataMap.put(field_code, import_example_txt);
        }
        dataList.add(excelDataMap);

        //移除没有权限的字段
        this.removeNotRoleFieldExport(dbformId, headMap);

        MoreSheetConfig resultModel = new MoreSheetConfig();
        resultModel.setSheetName(sheetName);
        resultModel.setHeadMap(headMap);
        resultModel.setDataList(dataList);
        return resultModel;

    }

    /**
     * 获取导出基本信息
     *
     * @param dbformId
     */
    @Override
    public MoreSheetConfig getExportExcelField(Long dbformId) {
        FormEntity formEntity = formService.getById(dbformId);
        String sheetName = formEntity.getTableDescribe();//表描述

        List<Map<String, Object>> excelFieldList = lideeYunJiMapper.getExcelExportFieldList(dbformId);

        //Excel头部
        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();

        for (Map<String, Object> dataMap : excelFieldList) {
            String field_code = lideeYunJiUtils.getMap2Str(dataMap, "field_code");
            String field_name = lideeYunJiUtils.getMap2Str(dataMap, "field_name");
            //封装头部
            ExcelTitleModel titleModel = new ExcelTitleModel();
            titleModel.setTitle(field_name);
            //处理字典表
            Map<String, String> dictMap = formService.getDictKeyLabelMap(dbformId, field_code);
            if (Func.isNotEmpty(dictMap) && dictMap.size() <= 20) {
                List<String> dictLabelList = dictMap.values().stream()
                        .collect(Collectors.toList());
                titleModel.setDropdownOptionList(dictLabelList);
            }
            headMap.put(field_code, titleModel);
        }
        //移除没有权限的字段
        this.removeNotRoleFieldExport(dbformId, headMap);

        MoreSheetConfig resultModel = new MoreSheetConfig();
        resultModel.setSheetName(sheetName);
        resultModel.setHeadMap(headMap);
        return resultModel;
    }

    //移除没有权限的字段
    private void removeNotRoleFieldExport(Long dbformId, LinkedMap<String, ExcelTitleModel> headTitleMap) {
        List<DbFormRoleFieldVo> roleFieldVoList = dbFormRoleService.listRoleField(lideeYunJiAdapter.getTenantId(), dbformId, false);
        if (Func.isEmpty(roleFieldVoList)) {
            return;
        }
        Map<String, DbFormRoleFieldVo> roleDisableMap = roleFieldVoList.stream()
                .collect(Collectors.toMap(DbFormRoleFieldVo::getFieldCode, entity -> entity));

        Iterator<Map.Entry<String, ExcelTitleModel>> iterator = headTitleMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, ExcelTitleModel> entry = iterator.next();
            String key = entry.getKey();
            if (!roleDisableMap.containsKey(key)) {//存在权限问题
                continue;
            }
            DbFormRoleFieldVo roleVo = roleDisableMap.get(key);
            //如果全部为空话，看最大的那个,最大的那个为N说明是没有权限，需要剔除
            if (Func.isEmpty(roleVo.getFormIsEdit()) && Func.isEmpty(roleVo.getFormIsView()) && Func.isEmpty(roleVo.getListIsView()) && Func.equals(roleVo.getEnableState(), YNEnum.N.getCode())) {
                iterator.remove();
            }
        }
    }

    /**
     * 获取导出基本信息
     */
    @Override
    public List<MoreSheetConfig> getExportExcelSheetList(Long dbFormId, Map<String, Object> params) {

        Map<Long, List<Map<String, Object>>> excelExportDataMap = new LinkedHashMap<>();

        ResultDataModel excelData = frameService.getExportDataList(dbFormId, params);
        List<Map<String, Object>> dataMapList = excelData.getRecords();
        excelExportDataMap.put(dbFormId, dataMapList);//添加主表数据

        FormEntity formEntity = formService.getFormEntityById(dbFormId);
        String tableName = formEntity.getTableName();
        Integer tableType = formEntity.getTableType();
        //------------把附表的数据也导出--------------------------
        if (Func.isNotEmpty(dataMapList) && Func.equals(tableType, TableTypeEnum.MAIN.getType())) {
            List<String> subTableNameList = formService.getAllSubTableNameList(dbFormId);//获取所有附表
            List<Long> subDbFormIdList = formService.getDbFormIdByTableName(subTableNameList);//所有附表的dbformId
            for (Long subDbFormId : subDbFormIdList) {
                FormEntity subFormEntity = formService.getFormEntityById(subDbFormId);
                String subTableName = subFormEntity.getTableName();

                FormFieldForeignkeyEntity foreignkeyEntity = formService.getFieldForeignkeyEntity(subDbFormId, tableName);
                String mainField = foreignkeyEntity.getMainField();//主表=-字段
                String fieldCode = foreignkeyEntity.getFieldCode();//外键字段
                //获取where值
                List<Object> whereObjList = dataMapList.stream()
                        .map(dataMap -> dataMap.get(mainField))
                        .filter(Func::isNotEmpty)
                        .collect(Collectors.toList());

                SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                        .select("*")
                        .setTableName(subTableName)
                        .setWhere(where -> {
                            where.in(fieldCode, whereObjList);
                            where.eq("is_deleted", 0);
                        })
                        .orderByAsc(fieldCode)
                        .build();
                List<Map<String, Object>> subDataMapList = sqlService.getDataListByPlus(wrapper);
                excelExportDataMap.put(subDbFormId, subDataMapList);//添加附表数据
            }
        }

        List<MoreSheetConfig> sheetList = new ArrayList<>();
        //遍历map
        for (Map.Entry<Long, List<Map<String, Object>>> entry : excelExportDataMap.entrySet()) {
            Long id = entry.getKey();
            List<Map<String, Object>> list = entry.getValue();

            CriteriaList formatCriteriaList = new FormatCriteriaList();//字典格式化
            formatCriteriaList.meetCriteria(id, list);

            CriteriaList viewFieldCriteriaList = new ViewFieldCriteriaList();//处理虚拟化字段
            viewFieldCriteriaList.meetCriteria(id, list);

            CriteriaList removeFieldCriteriaList = new RemoveFieldCriteriaList();//移除不是列表显示的字段
            removeFieldCriteriaList.meetCriteria(id, list);

            //获取基本信息
            MoreSheetConfig sheetConfig = getExportExcelField(id);
            sheetConfig.setDataList(list);

            //封装config
            sheetList.add(sheetConfig);
        }

        return sheetList;
    }

    /**
     * 获取导出基本信息
     */
    @Override
    public MoreSheetConfig getExcelReportModel(String reportCode) {
        ReportEntity reportEntity = reportService.getReportEntityByCode(reportCode);

        String sheetName = reportEntity.getReportName();//表描述

        LambdaQueryWrapper<ReportFieldEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ReportFieldEntity::getReportId, reportEntity.getId());
        wrapper.eq(ReportFieldEntity::getIsExport, YNEnum.Y.getCode());
        List<ReportFieldEntity> fieldEntityList = reportFieldMapper.selectList(wrapper);

        //Excel头部
        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();

        for (ReportFieldEntity fieldEntity : fieldEntityList) {
            String fieldCode = fieldEntity.getFieldCode();
            String fieldName = fieldEntity.getFieldName();

            //封装头部
            ExcelTitleModel titleModel = new ExcelTitleModel();
            titleModel.setTitle(fieldName);
            headMap.put(fieldCode, titleModel);
        }

        MoreSheetConfig resultModel = new MoreSheetConfig();
        resultModel.setSheetName(sheetName);
        resultModel.setHeadMap(headMap);
        return resultModel;
    }


    /**
     * 处理临时库的数据
     *
     * @param batchCode 批次号
     */
    @Async("asyncPoolTaskExecutor")
    public void handleTempTable(Long dbFormId, Long batchCode) {
        //获取未处理的记录
        LambdaQueryWrapper<ExcelFileDataEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExcelFileDataEntity::getExcelFileId, batchCode);
        wrapper.eq(ExcelFileDataEntity::getHandleState, YNEnum.N.getCode());//未处理
        wrapper.orderByAsc(ExcelFileDataEntity::getSort);
        List<ExcelFileDataEntity> entityList = excelDataService.list(wrapper);
        if (Func.isEmpty(entityList)) {
            return;
        }
        //获取字典
        ExcelImportDataDictModel dictModel = this.formatExcelImportDataList(dbFormId);
        //处理导入
        IExcelService excelService = SpringUtils.getBean(IExcelService.class);

        SaveImportDataParam param = new SaveImportDataParam();
        param.setBatchCode(batchCode);
        param.setEntityList(entityList);
        param.setDictModel(dictModel);
        excelService.handleImportData(dbFormId, param);
    }


    //处理导入数据
    @DSTransactional(rollbackFor = Exception.class)
    @Override
    public void handleImportData(Long dbFormId, SaveImportDataParam param) {

        Long batchCode = param.getBatchCode();
        List<ExcelFileDataEntity> entityList = param.getEntityList();
        ExcelImportDataDictModel dictModel = param.getDictModel();

        //基本校验
        DbFormConfigVo dbFormConfig = dbFormService.getDetailDbFormConfig(dbFormId);

        //增强列表
        List<EnhanceJavaEntity> javaEntityList = enhanceJavaService.getSlectList(dbFormId);
        boolean hashEnhanceJavaFlag = Func.isNotEmpty(javaEntityList);

        //获取是否有去重字段
        List<FormFieldExportEntity> duplicateFieldList = exportMapper.getDuplicateByFormId(dbFormId);
        boolean duplicateFlag = FuncBase.isNotEmpty(duplicateFieldList);
        String duplicateType = this.getDuplicateType(dbFormId, duplicateFieldList, duplicateFlag);//去重类型
        String duplicateField = this.getDuplicateField(dbFormId, duplicateFieldList, duplicateFlag);//去重字段

        //web字段
        List<String> userKeyList = fieldWebMapper.getUserControlTypeFieldCodeList(dbFormId);//用户控件字段
        List<String> deptKeyList = fieldWebMapper.getDeptControlTypeFieldCodeList(dbFormId);//部门控件字段
        List<String> areaKeyList = fieldWebMapper.getAreaControlTypeFieldCodeList(dbFormId);//区域控件字段

        // 获取数据库并且是导入字段列表
        List<FormFieldEntity> allFieldEntityList = formService.getFieldList(dbFormId);

        //EXcel字段类型
        List<Map<String, Object>> excelFieldList = lideeYunJiMapper.getExcelImportFieldList(dbFormId);

        //处理map
        Map<String,String> fieldNameDbTypeMap=new HashMap<>();
        excelFieldList.forEach(map -> {
            String fieldCode = Func.getMap2Str(map, "field_code");
            String fieldType = Func.getMap2Str(map, "field_type");
            String jdbcType = Func.getJdbcType(fieldType);
            fieldNameDbTypeMap.put(fieldCode,jdbcType);
        });

        //所有字段类型
        Map<String,String> fieldNameJavaTypeMap=new HashMap<>();
        allFieldEntityList.forEach(entity -> {
            String fieldCode = entity.getFieldCode();
            String fieldType = entity.getFieldType();
            fieldNameJavaTypeMap.put(fieldCode,fieldType);
        });


        Long tenantId = proxyAdapter.getTenantId();
        Long onlineUserId = proxyAdapter.getOnlineUserId();
        String tableName = dbFormService.getTableName(dbFormId);//获取表名

        String importStateRedisKey = "excel:import:task_" + batchCode;//判断是否中断
        Integer importState = 1;//1=成功  -2=取消

        //校验返回新的map数据
        List<Map<String, Object>> dataMapList = new ArrayList<>();

        ForkJoinPool pool = null;
        try {
            pool = FuncBase.lideeyunjiForkJoinPool(50);
            pool.submit(() -> entityList.stream().forEach(entity -> {
                Map<String, Object> dataMap = Func.json2Bean(entity.getDataJson(), Map.class);
                Map<String, Object> saveDataMap = dataMap.entrySet().stream()
                        .filter(item -> "id".equals(item.getKey().toLowerCase()) || fieldNameDbTypeMap.containsKey(item.getKey()))
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                //处理字典，字典值回显
                this.handleDict(dictModel, saveDataMap);
                //处理人
                this.handleUser(tenantId, userKeyList, saveDataMap);
                //处理部门
                this.handleDept(tenantId, deptKeyList, saveDataMap);
                //处理区域
                this.handleArea(areaKeyList, saveDataMap);
                //处理数据类型
                this.handleDataType(fieldNameJavaTypeMap,saveDataMap);

                //导入增强，增强修改的
                if(hashEnhanceJavaFlag){
                    frameService.importEnhanceData(dbFormId, saveDataMap);
                }


                //其他基础校验
                try{
                    ExcelCheckParams checkParams = new ExcelCheckParams();
                    checkParams.setDataMap(saveDataMap);
                    checkParams.setDbFormConfigVo(dbFormConfig);

                    ExcelCheckEnums[] excelCheckEnums = ExcelCheckEnums.values();
                    for (ExcelCheckEnums checkEnums : excelCheckEnums) {
                        IExcelCheckStrategy strategy = checkEnums.getStrategy();
                        strategy.check(checkParams);
                    }
                }catch (Exception e){
                    e.printStackTrace();

                    this.saveImportCou("fail", batchCode, 1);//失败条数
                    this.saveImportCou("total", batchCode, 1);//总条数

                    Long dataId = Func.getMap2Long(saveDataMap, "id");
                    ExcelFileDataEntity updateEntity = new ExcelFileDataEntity();
                    updateEntity.setId(dataId);
                    updateEntity.setHandleState(YNEnum.Y.getCode());//已处理
                    updateEntity.setHandleResult("FAIL");
                    updateEntity.setHandleTime(DateUtil.date());
                    updateEntity.setErrorReason(e.getMessage());
                    updateEntity.setCreateUser(onlineUserId);
                    updateEntity.setUpdateUser(onlineUserId);
                    excelDataService.updateById(updateEntity);

                    return;
                }

                //map是正常数据，一般没有出错，直接入库
                dataMapList.add(saveDataMap);
            })).get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if (pool != null) {
                pool.shutdown();
            }
        }


        DbTypeEnum dbTypeEnum = SqlHelper.getDbTypeEnum();


        //校验完成，进行入库
        int insertCou = 500;//每500条入库一次
        //去重和oracle数据库，都是要一条条入库
        if (duplicateFlag || Func.equals(dbTypeEnum, DbTypeEnum.ORACLE) ) {//如果需要去重，则一条条入库处理
            insertCou = 1;
        }

        List<Map<String, Object>> insertDataMapList = new ArrayList<>();
        for (int i = 0; i < dataMapList.size(); i++) {
            Map<String, Object> dataMap = dataMapList.get(i);
            insertDataMapList.add(dataMap);
            //每X条入库一次,或者最后一条入库
            if (insertDataMapList.size() != insertCou && i != dataMapList.size() - 1) {
                continue;
            }
            //记录是否成功
            Map<Long, String> importStateMap = new HashMap<>();
            for (Map<String, Object> insertDataMap : insertDataMapList) {
                Long dataId = Func.getMap2Long(insertDataMap, "id");
                importStateMap.put(dataId, "成功");//默认成功
            }

            try {
                if (!duplicateFlag) {//不用去重校验，则直接入库
                    sqlService.insertDataListByPlus(tableName, fieldNameDbTypeMap, insertDataMapList);
                } else {//需要去重校验
                    this.saveOrUpdate(dbFormId, tableName, duplicateType, duplicateField, insertDataMapList);
                }

                this.saveImportCou("total", batchCode, insertDataMapList.size());//总条数
                this.saveImportCou("success", batchCode, insertDataMapList.size());//成功条数
            } catch (Exception e) {
                if(insertCou==1){//有出错，并且是一条条入库的，则不需要继续循环了
                    e.printStackTrace();
                    String errorReason = e.getMessage();
                    Map<String, Object> insertDataMap = insertDataMapList.get(0);
                    Long dataId = Func.getMap2Long(insertDataMap, "id");
                    importStateMap.put(dataId, "失败：" + errorReason);
                    this.saveImportCou("fail", batchCode, 1);//失败条数
                    this.saveImportCou("total", batchCode, 1);//总条数
                }else{//多套的话，需要拆开为单条
                    //有异常，则一条条入库
                    for (Map<String, Object> insertDataMap : insertDataMapList) {
                        Long dataId = Func.getMap2Long(insertDataMap, "id");

                        String errorReason = "";
                        try {
                            //单条入库
                            List<Map<String, Object>> tmpMapList = new ArrayList<>();
                            tmpMapList.add(insertDataMap);
                            sqlService.insertDataListByPlus(tableName, fieldNameDbTypeMap, tmpMapList);
                            this.saveImportCou("success", batchCode, 1);//成功条数
                        } catch (lideeYunJiException je) {
                            errorReason = je.getMessage();
                            importStateMap.put(dataId, "失败：" + errorReason);
                            this.saveImportCou("fail", batchCode, 1);//失败条数
                        } catch (Exception e1) {//有异常，则记录异常的那条
                            errorReason = "数据格式有误";
                            importStateMap.put(dataId, "失败：" + errorReason);
                            this.saveImportCou("fail", batchCode, 1);//失败条数
                            e1.printStackTrace();
                        }
                        this.saveImportCou("total", batchCode, 1);//总条数
                    }
                }

            }

            //更新表
            List<ExcelFileDataEntity> updateEntityList = new ArrayList<>();
            importStateMap.forEach((dataId, reason) -> {
                String handleResult = Func.equals(reason, "成功") ? "SUCCESS" : "FAIL";

                ExcelFileDataEntity updateEntity = new ExcelFileDataEntity();
                updateEntity.setId(dataId);
                updateEntity.setHandleState(YNEnum.Y.getCode());//已处理
                updateEntity.setHandleResult(handleResult);
                updateEntity.setHandleTime(DateUtil.date());
                updateEntity.setErrorReason(reason);
                updateEntity.setCreateUser(onlineUserId);
                updateEntity.setUpdateUser(onlineUserId);
                updateEntityList.add(updateEntity);
            });
            //批量更新
            excelDataService.updateBatchById(updateEntityList);

            //入库完成，清空
            insertDataMapList.clear();

            //判断是否存在暂停，取消
            if (!lideeYunjiRedisUtils.hasKey(importStateRedisKey)) {//是否存在暂停，取消
                continue;
            }
            String redisVal = (String) lideeYunjiRedisUtils.get(importStateRedisKey);
            if (Func.equals(redisVal, "STOP_TASK")) {//暂停
                lideeYunjiRedisUtils.del(importStateRedisKey);
                break;
            } else if (Func.equals(redisVal, "CANCLE_TASK")) {//取消
                lideeYunjiRedisUtils.del(importStateRedisKey);
                importState = -2;
                break;
            }

        }

        //---------------------------------------------------------

        //如果是取消的话，需要回滚事务
        if (importState == -2) {//取消，需要删除数据
            excelFileService.rollback(batchCode);
        }

        //获取成功总数
        LambdaQueryWrapper<ExcelFileDataEntity> successWrapper = new LambdaQueryWrapper<>();
        successWrapper.eq(ExcelFileDataEntity::getExcelFileId, batchCode);
        successWrapper.eq(ExcelFileDataEntity::getHandleResult, "SUCCESS");
        long successNum = excelDataService.count(successWrapper);

        //获取失败总数
        LambdaQueryWrapper<ExcelFileDataEntity> errorWrapper = new LambdaQueryWrapper<>();
        errorWrapper.eq(ExcelFileDataEntity::getExcelFileId, batchCode);
        errorWrapper.eq(ExcelFileDataEntity::getHandleResult, "FAIL");
        long failNum = excelDataService.count(errorWrapper);


        //1.存入标题
        ExcelFileEntity fileEntity = new ExcelFileEntity();
        fileEntity.setId(batchCode);
        fileEntity.setImportState(Func.toStr(importState));//修改状态
        fileEntity.setSuccessNum(Func.toInt(successNum));
        fileEntity.setErrorNum(Func.toInt(failNum));
        fileEntity.setCreateUser(onlineUserId);
        fileEntity.setUpdateUser(onlineUserId);
        excelFileService.updateById(fileEntity);

        if(hashEnhanceJavaFlag){
            Map<String,Object> importEndMap = new HashMap<>();
            importEndMap.put("dbFormId",dbFormId);
            importEndMap.put("batchCode",batchCode);
            importEndMap.put("id",batchCode);
            frameService.importEnhanceDataEnd(dbFormId, importEndMap);
        }
    }

    private void saveOrUpdate(Long dbFormId,
                              String tableName,
                              String duplicateType,
                              String duplicateFieldListStr,
                              List<Map<String, Object>> insertDataMapList) {
        List<String> duplicateFieldList = Func.toStrList(duplicateFieldListStr);
        Map<String, Object> insertMap = insertDataMapList.get(0);


        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .select("id")
                .setWhere(where -> {
                    where.eq("is_deleted", 0);
                    for (String duplicateField : duplicateFieldList) {
                        where.eq(duplicateField, insertMap.get(duplicateField));
                    }
                })
                .build();

        FrameServiceImpl proxyService = SpringUtils.getBean(FrameServiceImpl.class);

        Map<String, Object> selectMap = sqlService.getDataOneByPlus(wrapper);
        if (FuncBase.isEmpty(selectMap)) {//表里面不存在
            proxyService.savePublicData(dbFormId, insertMap);
            return;
        }
        Long id = FuncBase.getMap2Long(selectMap, "id");
        //根据类型，来判断是那种形式：update=直接更新  delete_update=先删除再插入
        switch (duplicateType) {
            case "update":
                proxyService.editPublicData(dbFormId, id, insertMap);
                return;
            case "delete_update":
                Map<String, Object> delMap = new HashMap<>();
                delMap.put("dataIdList", Func.toLongList(id + ""));
                delMap.put("whereFieldCode", "id");
                proxyService.delData(dbFormId, delMap);
                proxyService.savePublicData(dbFormId, insertMap);
                return;
        }
        throw new lideeYunJiException("去重类型有误");
    }

    //处理人员
    private void handleUser(Long tenantId, List<String> keyList, Map<String, Object> dataMap) {
        if (Func.isEmpty(keyList)) {
            return;
        }

        for (String key : keyList) {
            String nikeNameListStr = lideeYunJiUtils.getMap2Str(dataMap, key);//值 超级管理员、开发管理员
            if (FuncBase.isEmpty(nikeNameListStr)) {
                continue;
            }
            List<String> idList = new ArrayList<>();
            List<String> nikeNameList = Func.toStrList("、", nikeNameListStr);
            for (String nikeName : nikeNameList) {
                //根据nikeName获取id
                List<Long> userIdList = adapterMapper.getUserIdByNikeName(tenantId, nikeName);
                if (Func.isEmpty(userIdList)) {
                    continue;
                }
                Long userId = userIdList.get(0);
                idList.add(Func.toStr(userId));
            }

            dataMap.put(key, String.join(",", idList));
        }
    }

    //处理部门
    private void handleDept(Long tenantId, List<String> keyList, Map<String, Object> dataMap) {
        if (Func.isEmpty(keyList)) {
            return;
        }

        for (String key : keyList) {
            String deptNameListStr = lideeYunJiUtils.getMap2Str(dataMap, key);//值 超级管理员、开发管理员
            if (FuncBase.isEmpty(deptNameListStr)) {
                continue;
            }
            List<String> idList = new ArrayList<>();
            List<String> deptNameList = Func.toStrList("、", deptNameListStr);
            for (String deptName : deptNameList) {
                //根据nikeName获取id
                List<Long> deptIdList = adapterMapper.getDeptIdByDeptName(tenantId, deptName);
                if (Func.isEmpty(deptIdList)) {
                    continue;
                }
                Long deptId = deptIdList.get(0);
                idList.add(Func.toStr(deptId));
            }

            dataMap.put(key, String.join(",", idList));
        }
    }

    private void handleArea(List<String> keyList, Map<String, Object> dataMap) {
        if (Func.isEmpty(keyList)) {
            return;
        }

        Map<String, String> provinceCityDistrict_nameIdMap = AreaUtils.getChinaProvinceCityDistrictMap();//值 北京/北京市/东城区、天津/天津市/和平区
        Map<String, String> provinceCity_nameIdMap = AreaUtils.getChinaProvinceCityMap();//值 北京/北京市、天津/天津市
        Map<String, String> province_nameIdMap = AreaUtils.getChinaProvinceMap();//值 北京、天津
        for (String key : keyList) {
            String areaListStr = lideeYunJiUtils.getMap2Str(dataMap, key);//值 北京/北京市/东城区、天津/天津市/和平区
            if (FuncBase.isEmpty(areaListStr)) {
                continue;
            }
            List<List<String>> idList = new ArrayList<>();
            List<String> areaNameList = Func.toStrList("、", areaListStr);
            for (String subNameListStr : areaNameList) {
                String nameIdListStr = "";
                int count = subNameListStr.split("/").length;
                switch (count) {
                    case 1:
                        nameIdListStr = province_nameIdMap.get(subNameListStr);
                        break;
                    case 2:
                        nameIdListStr = provinceCity_nameIdMap.get(subNameListStr);
                        break;
                    case 3:
                        nameIdListStr = provinceCityDistrict_nameIdMap.get(subNameListStr);
                        break;
                }

                List<String> nameIdList = Func.toStrList(",", nameIdListStr);
                idList.add(nameIdList);
            }
            dataMap.put(key, JsonUtils.toJsonString(idList));
        }
    }

    //处理字典
    private void handleDict(ExcelImportDataDictModel dictModel, Map<String, Object> dataMap) {
        if (Func.isEmpty(dictModel)) {
            return;
        }
        Map<String, Map<String, String>> dictMaps = dictModel.getDictMaps();
        List<String> keyList = dictModel.getKeyList();
        if (Func.isEmpty(keyList)) {
            return;
        }

        for (String key : keyList) {
            String val = lideeYunJiUtils.getMap2Str(dataMap, key);//值 男
            if (FuncBase.isEmpty(val)) {
                continue;
            }
            Map<String, String> valMap = dictMaps.get(key);// 男-》1
            String valStr = valMap.get(val);
            if (FuncBase.isEmpty(valStr)) {//有可能是多选，导致匹配不到值
                if (val.contains(",") || val.contains("，") || val.contains("、")) {
                    val = val.replaceAll("[,，、]", ",");
                    List<String> valList = FuncBase.toStrList(val);
                    List<String> tmpValList = new ArrayList<>();
                    for (String tmpVal : valList) {
                        String tmpValStr = valMap.get(tmpVal);
                        tmpValList.add(tmpValStr);
                    }
                    valStr = String.join(",", tmpValList);
                } else {
                    continue;
                }

            }
            dataMap.put(key, valStr);
        }
    }


    //处理数据类型
    private void handleDataType(Map<String,String> fieldNameTypeMap, Map<String, Object> dataMap) {
        Map<String, Object> tmpMap=new HashMap<>();
        dataMap.forEach((fieldCode, value) -> {
            String fieldType = fieldNameTypeMap.get(fieldCode);
            if (FuncBase.isEmpty(fieldType)) {
                tmpMap.put(fieldCode, value);
                return;
            }
            Object newVal = Func.paramParse2Object(value, LideeYunJiFieldTypeEnum.getByFieldType(fieldType));
            tmpMap.put(fieldCode, newVal);
        });
        dataMap.clear();
        dataMap.putAll(tmpMap);
    }
    //获取字典
    private ExcelImportDataDictModel formatExcelImportDataList(Long dbformId) {

        List<FormFieldEntity> fieldList = formService.getDbFieldList(dbformId);
        //字典集合
        Map<String, Map<String, String>> dictMaps = new HashMap<>();
        List<String> keyList = new ArrayList<>();
        for (FormFieldEntity formFieldEntity : fieldList) {
            String fieldCode = formFieldEntity.getFieldCode();
            Map<String, String> dictMap = formService.getDictKeyLabelMap(dbformId, fieldCode);//字典列表 男：1
            if (FuncBase.isEmpty(dictMap)) {
                continue;
            }
            //进行反转 key=男  value =1
            Map<String, String> labelKeyMap = new HashMap<>();
            for (Map.Entry<String, String> entry : dictMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                labelKeyMap.put(value, key);
            }
            dictMaps.put(fieldCode, labelKeyMap);
            keyList.add(fieldCode);
        }
        ExcelImportDataDictModel dictModel = new ExcelImportDataDictModel();
        dictModel.setDictMaps(dictMaps);
        dictModel.setKeyList(keyList);
        return dictModel;

    }


    //获取去重类型
    private String getDuplicateType(Long dbFormId, List<FormFieldExportEntity> duplicateFieldList, boolean duplicateFlag) {
        String duplicateType = "";
        if (duplicateFlag) {
            duplicateType = dbFormService.getDuplicateType(dbFormId);
        }
        return duplicateType;
    }

    //获取去重字段
    private String getDuplicateField(Long dbFormId, List<FormFieldExportEntity> duplicateFieldList, boolean duplicateFlag) {
        String duplicateField = "";
        if (duplicateFlag) {
            duplicateField = duplicateFieldList.stream()
                    .map(FormFieldExportEntity::getFieldCode)
                    .collect(Collectors.joining(","));
        }
        return duplicateField;
    }

    //保存导入条数
    private void saveImportCou(String type, Long batchCode, int addCou) {
        String redisKey = "";
        switch (type) {
            case "total":
                redisKey = "excel:import_cou:total_" + batchCode;//总条数
                break;
            case "success":
                redisKey = "excel:import_cou:success_" + batchCode;//成功条数
                break;
            case "fail":
                redisKey = "excel:import_dcou:fail_" + batchCode;//失败条数
                break;
        }

        Object couStr = lideeYunjiRedisUtils.get(redisKey);//

        long cou = Func.isEmpty(couStr) ? 0L : Func.toLong(couStr);


        cou = cou + addCou;

        //重新保存
        lideeYunjiRedisUtils.set(redisKey, Func.toStr(cou), 2, TimeUnit.DAYS);//存2天
    }
}
