package com.storlead.sales.controller.excel;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.storlead.framework.common.constant.CodeGenerateInterface;
import com.storlead.framework.annotate.Dict;
import com.storlead.framework.auth.vo.LoginUser;
import com.storlead.framework.common.constant.CodeGenerateInterface;
import com.storlead.framework.common.util.ConvertUtils;
import com.storlead.framework.common.util.HttpUtil;
import com.storlead.framework.common.util.MD5Util;
import com.storlead.framework.common.util.SpringContextUtils;
import com.storlead.framework.common.util.generate.CodeGenerate;
import com.storlead.framework.annotate.Dict;
import com.storlead.framework.annotate.OrgAutoMateAnnotate;
import com.storlead.framework.redis.RedisService;
import com.storlead.framework.util.LoginUserUtil;
import com.storlead.framework.auth.vo.LoginUser;
import com.storlead.framework.common.result.Result;
import com.storlead.framework.mybatis.entity.SysBaseField;
import com.storlead.framework.mybatis.service.MyBaseService;
import com.storlead.framework.redis.RedisService;
import com.storlead.sales.pojo.dto.customer.CustomerAddDTO;
import com.storlead.sales.pojo.dto.customer.LiaisonAddDTO;
import com.storlead.sales.pojo.entity.customer.CustomerCompanyEntity;
import com.storlead.sales.pojo.entity.customer.CustomerEntity;
import com.storlead.sales.pojo.entity.customer.LiaisonEntity;
import com.storlead.sales.pojo.dto.excel.*;
import com.storlead.sales.pojo.vo.excel.*;
import com.storlead.sales.util.excel.*;
import com.storlead.sales.service.customer.CustomerCompanyService;
import com.storlead.sales.service.customer.CustomerService;
import com.storlead.sales.service.customer.LiaisonService;
import com.storlead.sales.service.CustomerMailBingMarkService;
import com.storlead.sales.util.SafeJsonParser;
import com.storlead.system.pojo.entity.*;
import com.storlead.system.service.*;
import com.storlead.user.pojo.entity.UserEntity;
import com.storlead.user.service.IDepartService;
import com.storlead.user.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import javax.annotation.Resource;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @program: sp-sales-platform
 * @description:
 * @author: chenkq
 * @create: 2024-04-09 16:47
 */
@Api(tags = "销售: Excel导入导出操作")
@Log4j2
@RestController
@RequestMapping("/excel")
public class ExcelMangeApiController {

    @Resource
    private Environment environment;

    @Resource
    private SysDictService dictService;

    @Resource
    private SysDictDetailService dictDetailService;

    @Resource
    private IUserService userService;

    @Resource
    private IDepartService departService;

    @Resource
    private CustomerService customerService;

    @Resource
    private CustomerCompanyService customerCompanyService;

    @Resource
    private LiaisonService liaisonService;

    @Resource
    private RedisService redisService;

    @Resource
    private SysDictService sysDictService;

    @Resource
    private SysDictDetailService sysDictDetailService;

    public MyBaseService getMyBaseService() {
        MyBaseService rt = (MyBaseService) SpringContextUtils.getBean("userServiceImpl");
        return rt;
    }

    @Resource
    private ExcelExportTemplateService excelExportTemplateService;

    @Resource
    private ExcelExportColumnRuleService excelExportColumnRuleService;

    @Resource
    private ExcelImportTemplateService excelImportTemplateService;

    @Resource
    private CustomerMailBingMarkService customerMailBingMarkService;

    @RequestMapping(value = "import_excel", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
    @ApiOperation(value = "导入", response = Result.class)
    //添加事务，异常回滚
    public  <T extends ExcelVerifyEntityOfMode> @ResponseBody Result importExcel(HttpServletResponse response, @RequestParam(value = "file", required = true) MultipartFile file, ExcelImportDTO dto) {
        LoginUser loginUser = LoginUserUtil.getLoginUser();

        String code = loginUser.getUserName()+System.currentTimeMillis()+dto.getTemplateCode();
        String key = MD5Util.MD5Encode(code, "utf-8");
        ExcelImportTemplateEntity importTemplate = excelImportTemplateService.getOne(new LambdaQueryWrapper<ExcelImportTemplateEntity>().eq(ExcelImportTemplateEntity::getTemplateCode,dto.getTemplateCode()));
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        params.setNeedVerify(true);
        try {

            Class<?> entityClass = loadClass(importTemplate.getPackageName(), importTemplate.getClassName());
            Field[] fields  = entityClass.getDeclaredFields();
            ExcelImportResult<T> result = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    entityClass, params);

            ExcelExportDataVO dataVO = new ExcelExportDataVO();
            List<ExcelExportEntity> titleList = new ArrayList();
            for(Field field : fields) {
                if (field.isAnnotationPresent(Excel.class)) {
                    Excel column = field.getAnnotation(Excel.class);
                    NotNull ntn = field.getAnnotation(NotNull.class);
                    String columnName = column.name();
                    ExcelExportEntity exportColumn = new ExcelExportEntity(columnName, field.getName(),25);
                    titleList.add(exportColumn);
                }
            }
            if (!CollectionUtils.isEmpty(result.getFailList())) {
                SysBaseField.dictFileds(result.getFailList());
                List<T> entities = result.getFailList();
                Iterator<T> iterator = entities.iterator();
                while (iterator.hasNext()) {
                    T t = iterator.next();
                    Field[] fieldls  = t.getClass().getDeclaredFields();
                    Boolean error = false;
                    Boolean lxr = false;
                    if (t.getClass().equals(LiaisonExcelVerifyEntity.class)) {
                        lxr = true;
                    }
                    if (Objects.isNull(t.getErrorMsg())) {
                        t.setErrorMsg("");
                    }
                    Long userId = loginUser.getId();
                    for(Field field : fieldls) {
                        if (field.isAnnotationPresent(Dict.class)) {
                            Dict column = field.getAnnotation(Dict.class);
                            String fieldName = StrUtil.isNotBlank(column.valueField()) ? column.valueField() : column.keyField();
                            Field field1 = t.getClass().getDeclaredField(fieldName);
                            field.setAccessible(true);
                            Object lable = field.get(t);
                            field1.setAccessible(true);
                            Object value = field1.get(t);

                            if (Objects.nonNull(lable) && StrUtil.isNotBlank(lable.toString())) {
                                if (Objects.isNull(value) || StrUtil.isBlank(value.toString())) {
                                    Excel excelAm = field.getAnnotation(Excel.class);
                                    String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                    t.setErrorMsg(t.getErrorMsg()+fgf+excelAm.name()+"值["+lable+"]没有匹配到数据");
                                    error = true;
                                }
                            }

                        } else if (lxr && field.getName().equals("customerName")){
                            if (t.getClass().equals(LiaisonExcelVerifyEntity.class)) {
                                field.setAccessible(true);
                                Object customerName = field.get(t);
                                if (Objects.isNull(customerName)) {
                                    error = true;
                                    String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                    t.setErrorMsg(t.getErrorMsg()+fgf+"客户名不能为空");
                                } else {
                                    String customerNameStr = customerName.toString();
                                    CustomerEntity customer = customerService.getCustomerIdByNameAndOwnerBy(customerNameStr,userId);
                                    if (Objects.isNull(customer)) {
                                        error = true;
                                        String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                        t.setErrorMsg(t.getErrorMsg()+fgf+"客户名["+customerNameStr+"]没有匹配到客户");
                                    }
                                }
                            }
                        } else if (field.getName().equals("ownerAccount")){
                            if (t.getClass().equals(CustomExcelVerifyEntity.class) || t.getClass().equals(ClueExcelVerifyEntity.class)) {
                                field.setAccessible(true);
                                Object ownerAccount = field.get(t);
                                if (Objects.isNull(ownerAccount)) {
                                    error = true;
                                    String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                    t.setErrorMsg(t.getErrorMsg()+fgf+"归属账号不能为空");
                                } else {
                                    UserEntity user = userService.getUserByMobile(ownerAccount.toString());
                                    if (Objects.isNull(user)) {
                                        error = true;
                                        String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                        t.setErrorMsg(t.getErrorMsg()+fgf+"归属账号["+ownerAccount+"]没匹配到用户");
                                    } else {
                                        userId = user.getId();
                                    }
                                }
                            }
                        }

                    }
                }
            }
            if (!CollectionUtils.isEmpty(result.getList())) {
                SysBaseField.dictFileds(result.getList());
                List<T> entities = result.getList();
                Iterator<T> iterator = entities.iterator();
                while (iterator.hasNext()) {
                    T t = iterator.next();
                    if (Objects.isNull(t.getErrorMsg())) {
                        t.setErrorMsg("");
                    }
                    Field[] fieldls  = t.getClass().getDeclaredFields();
                    Boolean error = false;
                    Boolean lxr = false;
                    if (t.getClass().equals(LiaisonExcelVerifyEntity.class)) {
                        lxr = true;
                    }
                    Long userId = loginUser.getId();
                    for(Field field : fieldls) {
                        field.setAccessible(true);
                        String columnName = field.getName();

                        if (columnName.equals("areaName")
                                || columnName.equals("ownerName")
                                || columnName.equals("ownerAccount")
                                || columnName.equals("name")
                                || columnName.equals("lname")
                                || columnName.equals("customerName")) {
                            Object value = field.get(t);
                            if (Objects.nonNull(value)) {
                              String value1 = ConvertUtils.replaceTrimBlank(value.toString());
                              field.set(t,value1);
                            }
                        }
                        if (columnName.equals("website")
                                || columnName.equals("lemail")
                                || columnName.equals("email")) {
                            Object value = field.get(t);
                            if (Objects.nonNull(value)) {
                                String value1 = ConvertUtils.replaceBlank(value.toString());
                                field.set(t,value1);
                            }
                        }

                        if (field.isAnnotationPresent(Dict.class)) {
                            Dict column = field.getAnnotation(Dict.class);
                            String fieldName = StrUtil.isNotBlank(column.valueField()) ? column.valueField() : column.keyField();
                            Field field1 = t.getClass().getDeclaredField(fieldName);
                            field.setAccessible(true);
                            Object lable = field.get(t);
                            field1.setAccessible(true);
                            Object value = field1.get(t);
                            if (StrUtil.isBlank(t.getErrorMsg())) {
                                t.setErrorMsg("");
                            }
                            if (Objects.nonNull(lable) && StrUtil.isNotBlank(lable.toString())) {
                                if (Objects.isNull(value) || StrUtil.isBlank(value.toString())) {
                                    Excel excelAm = field.getAnnotation(Excel.class);
                                    String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                    t.setErrorMsg(t.getErrorMsg()+fgf+excelAm.name()+"值["+lable+"]没有匹配到数据");
                                    error = true;
                                }
                            }

                        }
                        else if (lxr && field.getName().equals("customerName")){
                            if (t.getClass().equals(LiaisonExcelVerifyEntity.class)) {
                                field.setAccessible(true);
                                Object customerName = field.get(t);
                                if (Objects.isNull(customerName)) {
                                    error = true;
                                    String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                    t.setErrorMsg(t.getErrorMsg()+fgf+"客户名不能为空");
                                } else {
                                    CustomerEntity customer = customerService.getCustomerIdByNameAndOwnerBy(customerName.toString(),userId);
                                    if (Objects.isNull(customer)) {
                                        error = true;
                                        String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                        t.setErrorMsg(t.getErrorMsg()+fgf+"客户名["+customerName+"]没有匹配到客户");
                                    }
                                }
                            }
                        } else if (field.getName().equals("ownerAccount")){
                            if (t.getClass().equals(CustomExcelVerifyEntity.class) || t.getClass().equals(ClueExcelVerifyEntity.class)) {
                                field.setAccessible(true);
                                Object ownerAccount = field.get(t);
                                if (Objects.isNull(ownerAccount)) {
                                    error = true;
                                    String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                    t.setErrorMsg(t.getErrorMsg()+fgf+"归属账号不能为空");
                                } else {
                                    UserEntity user = userService.getUserByMobile(ownerAccount.toString());
                                    if (Objects.isNull(user)) {
                                        error = true;
                                        String fgf = StrUtil.isBlank(t.getErrorMsg()) ? "" : ",";
                                        t.setErrorMsg(t.getErrorMsg()+fgf+"归属账号["+ownerAccount+"]没匹配到用户");
                                    } else {
                                        userId = user.getId();
                                    }
                                }
                            }
                        }

                    }
                    if (error) {
                        result.getFailList().add(t);
                        iterator.remove();
                    }
                }
            }
            Class<?> superClass = entityClass.getSuperclass();
            if (Objects.nonNull(superClass)) {
                Field field = superClass.getDeclaredField("errorMsg");
                if (Objects.nonNull(field)) {
                    field.setAccessible(true);
                    Excel column = field.getAnnotation(Excel.class);
                    if (Objects.nonNull(column)) {
                        ExcelExportEntity exportColumn = new ExcelExportEntity(column.name(), field.getName(),125);
                        titleList.add(exportColumn);
                    }
                }
            }
            List<T> entities = result.getList();
            entities.addAll(result.getFailList());
            List datas = new ArrayList();
            for(T d: entities) {
                JSONObject json = (JSONObject) JSONObject.toJSON(d);
                Map<String,String> map = new HashMap<>();
                for (ExcelExportEntity entity : titleList) {
                    String key1 = entity.getKey().toString();
                    String value1 = json.getString(entity.getKey().toString());
                    if (key1.equals("areaName")
                            || key1.equals("ownerName")
                            || key1.equals("ownerAccount")
                            || key1.equals("name")
                            || key1.equals("lname")
                            || key1.equals("customerName")) {
                        value1 = ConvertUtils.replaceTrimBlank(value1);
                    }
                    if (key1.equals("website")
                            || key1.equals("lemail")
                            || key1.equals("email")) {
                        value1 = ConvertUtils.replaceBlank(value1);
                    }
                    map.put(key1,value1);
                 }
                datas.add(map);
            }

            dataVO.setExcelExportData(titleList);
            dataVO.setDictCode(importTemplate.getDictCode());
            if (CollectionUtils.isEmpty(result.getFailList())) {
                dataVO.setImportData(result.getList());
            }
            dataVO.setDatas(datas);
            dataVO.setTitleAlert(importTemplate.getTitleAlert());
            dataVO.setFileName(file.getOriginalFilename());
            dataVO.setTitleRow(importTemplate.getTitleRow());
            ExcelResutVO resultVO = new ExcelResutVO();
            if (CollectionUtils.isEmpty(result.getFailList())) {
                // 处理业务数据
                resultVO.setSuccessNum(result.getList().size());
                resultVO.setExcelFileName(file.getName());

                redisService.setCacheObject(key, dataVO, 60 * 5L, TimeUnit.SECONDS);
                resultVO.setTempCode(key);
                List<T> cdatas = result.getList();

                List<ExcelViewVO> vos = new ArrayList<>();
                for(T d : cdatas) {
                    ExcelViewVO view = new ExcelViewDataVO().getExcelViewDataVOS(d);
                    vos.add(view);
                }
                resultVO.setIsSuccess(true);
                resultVO.setDatas(vos);
                return Result.result(resultVO);
                // 处理发挥的数据
            } else {
                resultVO.setSuccessNum(result.getList().size());
                resultVO.setErrorNum(result.getFailList().size());
                List<String> errorMsg = new ArrayList<>();
                for (int row = 0; row < entities.size(); row++) {
                    int vrow = row + 3;
                    String errorStr = entities.get(row).getErrorMsg();
                    if (StrUtil.isNotBlank(errorStr)) {
                        String str = "第" + vrow+"行";
                        errorMsg.add(str + errorStr);
                    }
                }
                resultVO.setErrorMsg(errorMsg);
                resultVO.setIsSuccess(false);
                resultVO.setExcelFileName(file.getName());
                resultVO.setTempCode(key);
                redisService.setCacheObject(key, dataVO, 60 * 5L, TimeUnit.SECONDS);
                return Result.result(resultVO);
            }
        }catch (Exception e) {
            log.error("导入产品 -e",e);
            return Result.error("导入错误");
        }

    }

    @RequestMapping(value = "save_import_new_data", method = RequestMethod.POST)
    @ApiOperation(value = "获取临时excel")
    public <T extends ExcelVerifyEntityOfMode> Result saveImportData(ExcelImportDTO dto)  {
        try {
            Object var1 =  redisService.getCacheObject(dto.getTempCode());
            ExcelExportDataVO dataVO = (ExcelExportDataVO)var1;
            if (Objects.isNull(dataVO)) {
                return Result.error("参数错误");
            }
            Long currentUserId = LoginUserUtil.getCurrentUserId();
            List datas = dataVO.getImportData();
            List<T> customExcelVos = datas;
            SysBaseField.dictFileds(customExcelVos);
            for(T customVo : customExcelVos) {
                if (customVo.getClass().equals(CustomExcelVerifyEntity.class)) {
                    //0:未成交客户,1:成交客户,2:公海客户,3:无效客户,4: 重点客户
                    CustomExcelVerifyEntity customExcel = (CustomExcelVerifyEntity) customVo;
                    CustomerAddDTO addDTO = CustomExcelVerifyEntity.getCustomerAddDTO(customExcel);
                    if (StrUtil.isNotBlank(customExcel.getOwnerAccount())) {
                        UserEntity user = userService.getUserByMobile(customExcel.getOwnerAccount());
                        if (Objects.nonNull(user)) {
                            user.setOwnerBy(user.getId());
                        } else {
                            addDTO.setOwnerBy(currentUserId);
                        }
                    } else {
                        addDTO.setOwnerBy(currentUserId);
                    }
                    if ("0".equals(dto.getImportType()) || "1".equals(dto.getImportType())) {
                        addDTO.setHasOrderForm(Integer.valueOf(dto.getImportType()));
                    }  else if ("2".equals(dto.getImportType())) {
                        addDTO.setHasPublicCustomer(true);
                        addDTO.setOwnerBy(null);
                    } else if ("3".equals(dto.getImportType())) {
                        addDTO.setHasGarbageCustomer(true);
                    } else if ("4".equals(dto.getImportType())) {
                        addDTO.setHasFollowCustomer(true);
                    }
                    addDTO.setCustomerForm(Integer.valueOf(dto.getResourceType()));
                    Result t = customerService.addNoCheckCustomer(addDTO);
                } else if (customVo.getClass().equals(ClueExcelVerifyEntity.class)) {
                    ClueExcelVerifyEntity customExcel = (ClueExcelVerifyEntity) customVo;
                    CustomerAddDTO addDTO = ClueExcelVerifyEntity.getCustomerAddDTO(customExcel);
                    if (StrUtil.isNotBlank(customExcel.getOwnerAccount())) {
                        UserEntity user = userService.getUserByMobile(customExcel.getOwnerAccount());
                        if (Objects.nonNull(user)) {
                            user.setOwnerBy(user.getId());
                        } else {
                            addDTO.setOwnerBy(currentUserId);
                        }
                    } else {
                        addDTO.setOwnerBy(currentUserId);
                    }
                    if ("2".equals(dto.getImportType())) {
                        addDTO.setHasPublicCustomer(true);
                        addDTO.setOwnerBy(null);
                    }
                    addDTO.setCustomerForm(Integer.valueOf(dto.getResourceType()));
                    Result t = customerService.addNoCheckCustomer(addDTO);
                } else if (customVo.getClass().equals(BusinessExcelVerifyEntity.class)) {
                    // 商机
                } else if (customVo.getClass().equals(OrderExcelVerifyEntity.class)) {
                    // 订单
                }else if (customVo.getClass().equals(WorkOrderExcelVerifyEntity.class)) {
                    // 工单
                }else if (customVo.getClass().equals(TaskExcelVerifyEntity.class)) {
                    // 任务
                }else if (customVo.getClass().equals(LiaisonExcelVerifyEntity.class)) {
                    // 联系人
                    LiaisonExcelVerifyEntity liaisonExcel = (LiaisonExcelVerifyEntity) customVo;
                    LiaisonAddDTO liaisondto = LiaisonExcelVerifyEntity.getLiaisonAddDTO(liaisonExcel);
                    String customerName = ((LiaisonExcelVerifyEntity) customVo).getCustomerName();
                    customerName = ConvertUtils.replaceTrimBlank(customerName);
                    if (StrUtil.isNotBlank(customerName)) {
                         CustomerEntity customer = customerService.getCustomerIdByNameAndOwnerBy(customerName, currentUserId);
                         if (Objects.nonNull(customer)) {
                             liaisondto.setCustomerId(customer.getId());
                             liaisondto.setOwnerBy(customer.getOwnerBy());
                         }
                     }
                     liaisonService.addOrEdit(liaisondto);
                }
            }
        }catch (Exception e) {
            log.error("----------",e);
            return Result.error(e.getMessage());
        }
        return Result.ok();
    }

    @RequestMapping(value = "save_import_data", method = RequestMethod.POST)
    @ApiOperation(value = "保存")
    @Transactional(rollbackFor = Throwable.class)
    public <T extends ExcelVerifyEntityOfMode> Result saveImportNewData(ExcelImportDTO dto)  {
        try {
            Object var1 =  redisService.getCacheObject(dto.getTempCode());
            ExcelExportDataVO dataVO = (ExcelExportDataVO)var1;
            if (Objects.isNull(dataVO)) {
                return Result.error("参数错误");
            }
            Long currentUserId = LoginUserUtil.getCurrentUserId();
            List datas = dataVO.getImportData();
            List<T> customExcelVos = datas;
            SysBaseField.dictFileds(customExcelVos);
            T excelVo = customExcelVos.get(0);
            if (excelVo.getClass().equals(CustomExcelVerifyEntity.class)) {
                List<CustomExcelVerifyEntity> customVos = new ArrayList<>();
                for(T customVo : customExcelVos) {
                    customVos.add((CustomExcelVerifyEntity)customVo);
                }
                Set<String> accountls = customVos.stream().map(CustomExcelVerifyEntity::getOwnerAccount).collect(Collectors.toSet());
                Map<String,UserEntity> customerUserMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(accountls)) {
                    List<UserEntity> userls = userService.list(new LambdaQueryWrapper<UserEntity>().in(UserEntity::getUserName, accountls));
                    if (!CollectionUtils.isEmpty(userls)) {
                        customerUserMap =  userls.stream().collect(Collectors.toMap(UserEntity::getUserName,a ->a));
                    }
                }
                List<CustomerAddDTO> dtos = new ArrayList<>();
                for (CustomExcelVerifyEntity customVo : customVos) {
                    CustomerAddDTO addDTO = CustomExcelVerifyEntity.getCustomerAddDTO(customVo);
                    addDTO.setDataCode(CodeGenerate.generate10Code(CodeGenerateInterface.CUSTOMER_CODE));
                    if (StrUtil.isNotBlank(customVo.getOwnerAccount())) {
                        UserEntity user = customerUserMap.get(customVo.getOwnerAccount());
                        if (Objects.nonNull(user)) {
                            addDTO.setOwnerBy(user.getId());
                        } else {
                            addDTO.setOwnerBy(currentUserId);
                        }
                    } else {
                        addDTO.setOwnerBy(currentUserId);
                    }
                    if ("0".equals(dto.getImportType()) || "1".equals(dto.getImportType())) {
                        addDTO.setHasOrderForm(Integer.valueOf(dto.getImportType()));
                    }  else if ("2".equals(dto.getImportType())) {
                        addDTO.setHasPublicCustomer(true);
                        addDTO.setOwnerBy(null);
                    } else if ("3".equals(dto.getImportType())) {
                        addDTO.setHasGarbageCustomer(true);
                    } else if ("4".equals(dto.getImportType())) {
                        addDTO.setHasFollowCustomer(true);
                    }
                    addDTO.setCustomerForm(Integer.valueOf(dto.getResourceType()));
                    dtos.add(addDTO);
                }

                List<String> customerNames = dtos.stream().filter(a -> StrUtil.isNotBlank(a.getCooperativeCustomerName())).map(CustomerAddDTO::getCooperativeCustomerName).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(customerNames)) {
                    List<CustomerEntity> customerls = customerService.list(new LambdaQueryWrapper<CustomerEntity>().in(CustomerEntity::getCustomerName,customerNames).eq(CustomerEntity::getOwnerBy,currentUserId).eq(CustomerEntity::getIsDelete,0));
                    if (!CollectionUtils.isEmpty(customerls)) {
                        Map<String,Long> customerMap =  customerls.stream().collect(Collectors.toMap(CustomerEntity::getCustomerName,CustomerEntity::getId, (existing, replacement) -> existing));
                        dtos.forEach(e -> {
                            if (StrUtil.isNotBlank(e.getCooperativeCustomerName())) {
                                e.setCooperativeCustomerId(customerMap.get(e.getCooperativeCustomerName()));
                            }
                        });
                    }
                }

                List<CustomerEntity> customers = customerService.assembleCustomerLs(dtos);
                if (CollectionUtils.isEmpty(customers)) {
                    return Result.error("客户数据异常");
                }

                customerService.saveOrUpdateBatch(customers);
                Map<String,Long> customerCodeMap  = customers.stream().collect(Collectors.toMap(CustomerEntity::getDataCode,CustomerEntity::getId));
                List<Long> ids =  customers.stream().map(CustomerEntity::getId).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(ids)) {
                    return Result.error("客户数据异常");
                }
                Map<String, Long> finalCustomerCodeMap = customerCodeMap;
                dtos.forEach(addDTO -> {
                    addDTO.setCustomerId(finalCustomerCodeMap.get(addDTO.getDataCode()));
                    if (StrUtil.isNotBlank(addDTO.getCooperativeCustomerName())) {
                        addDTO.setCooperativeCustomerId(finalCustomerCodeMap.get(addDTO.getCooperativeCustomerName()));
                    }
                });
                List<CustomerCompanyEntity> companys = customerService.assembleCustomerCompanyLs(dtos);
                if (!CollectionUtils.isEmpty(companys)) {
                    customerCompanyService.saveOrUpdateBatch(companys);
                }
                List<LiaisonEntity> liaisons = customerService.assembleLiaisonLs(dtos);
                if (!CollectionUtils.isEmpty(liaisons)) {
                    liaisonService.saveOrUpdateBatch(liaisons);
                }
                if ("2".equals(dto.getImportType())) {
                    LambdaUpdateWrapper<CustomerEntity> customerEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    customerEntityLambdaUpdateWrapper.in(CustomerEntity::getId,ids);
                    customerEntityLambdaUpdateWrapper.set(CustomerEntity::getOwnerBy,null);
                    customerService.update(customerEntityLambdaUpdateWrapper);
                    if (!CollectionUtils.isEmpty(liaisons)) {
                        LambdaUpdateWrapper<LiaisonEntity> liaisonEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                        liaisonEntityLambdaUpdateWrapper.eq(LiaisonEntity::getId,liaisons.stream().map(LiaisonEntity::getId).collect(Collectors.toList()));
                        liaisonEntityLambdaUpdateWrapper.set(LiaisonEntity::getOwnerBy, null);
                        liaisonService.update(liaisonEntityLambdaUpdateWrapper);
                    }
                }

                if (!CollectionUtils.isEmpty(companys)) {
                    for (CustomerCompanyEntity customerCompany : companys) {
                        try {
                            LiaisonEntity liaison = null;
                            if (!CollectionUtils.isEmpty(liaisons)) {
                                Optional<LiaisonEntity> optional = liaisons.stream().filter(e ->customerCompany.getCustomerId().equals(e.getCustomerId())).findFirst() ;
                                liaison = optional.isEmpty() ? null : optional.get();
                            }
                            customerMailBingMarkService.updateCustomerMailBingMark(customerCompany.getCustomerId(),Arrays.asList(customerCompany.getEmail()),(Objects.nonNull(liaison) ? liaison.getId() : null),(Objects.nonNull(liaison) ? Arrays.asList(liaison.getEmail()) : null));
                        }catch (Exception e) {
                            log.error("export -- updateCustomerLiaisonMailBingMark -- error :",e);
                        }
                    }
                }
            } else if (excelVo.getClass().equals(ClueExcelVerifyEntity.class)) {
                List<ClueExcelVerifyEntity> customVos = new ArrayList<>();
                for(T customVo : customExcelVos) {
                    customVos.add((ClueExcelVerifyEntity)customVo);
                }
                Set<String> accountls = customVos.stream().map(ClueExcelVerifyEntity::getOwnerAccount).collect(Collectors.toSet());
                Map<String,UserEntity> customerUserMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(accountls)) {
                    List<UserEntity> userls = userService.list(new LambdaQueryWrapper<UserEntity>().in(UserEntity::getUserName,accountls));
                    if (!CollectionUtils.isEmpty(userls)) {
                        customerUserMap =  userls.stream().collect(Collectors.toMap(UserEntity::getUserName,a ->a));
                    }
                }
                List<CustomerAddDTO> dtos = new ArrayList<>();
                for (ClueExcelVerifyEntity customVo : customVos) {
                    CustomerAddDTO addDTO = ClueExcelVerifyEntity.getCustomerAddDTO(customVo);
                    addDTO.setDataCode(CodeGenerate.generate10Code(CodeGenerateInterface.CUSTOMER_CODE));
                    if (StrUtil.isNotBlank(customVo.getOwnerAccount())) {
                        UserEntity user = customerUserMap.get(customVo.getOwnerAccount());
                        if (Objects.nonNull(user)) {
                            addDTO.setOwnerBy(user.getId());
                        } else {
                            addDTO.setOwnerBy(currentUserId);
                        }
                    } else {
                        addDTO.setOwnerBy(currentUserId);
                    }
                    if ("0".equals(dto.getImportType()) || "1".equals(dto.getImportType())) {
                        addDTO.setHasOrderForm(Integer.valueOf(dto.getImportType()));
                    }  else if ("2".equals(dto.getImportType())) {
                        addDTO.setHasPublicCustomer(true);
                        addDTO.setOwnerBy(null);
                    }
                    addDTO.setCustomerForm(Integer.valueOf(dto.getResourceType()));
                    dtos.add(addDTO);
                }
                List<CustomerEntity> customers = customerService.assembleCustomerLs(dtos);
                if (CollectionUtils.isEmpty(customers)) {
                    return Result.error("客户数据异常");
                }
                customerService.saveOrUpdateBatch(customers);
                Map<String,Long> customerCodeMap  = customers.stream().collect(Collectors.toMap(CustomerEntity::getDataCode,CustomerEntity::getId));
                List<Long> ids =  customers.stream().map(CustomerEntity::getId).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(ids)) {
                    return Result.error("客户数据异常");
                }
                dtos.forEach(addDTO -> {
                    addDTO.setCustomerId(customerCodeMap.get(addDTO.getDataCode()));
                });
                List<CustomerCompanyEntity> companys = customerService.assembleCustomerCompanyLs(dtos);
                if (!CollectionUtils.isEmpty(companys)) {
                    customerCompanyService.saveOrUpdateBatch(companys);
                }
                List<LiaisonEntity> liaisons = customerService.assembleLiaisonLs(dtos);
                if (!CollectionUtils.isEmpty(liaisons)) {
                    liaisonService.saveOrUpdateBatch(liaisons);
                }
                if ("2".equals(dto.getImportType())) {
                    LambdaUpdateWrapper<CustomerEntity> customerEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    customerEntityLambdaUpdateWrapper.in(CustomerEntity::getId,ids);
                    customerEntityLambdaUpdateWrapper.set(CustomerEntity::getOwnerBy,null);
                    customerService.update(customerEntityLambdaUpdateWrapper);
                    List<Long> lIds = liaisons.stream().map(LiaisonEntity::getId).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(lIds)) {
                        LambdaUpdateWrapper<LiaisonEntity> liaisonEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                        liaisonEntityLambdaUpdateWrapper.in(LiaisonEntity::getId,lIds);
                        liaisonEntityLambdaUpdateWrapper.set(LiaisonEntity::getOwnerBy, null);
                        liaisonService.update(liaisonEntityLambdaUpdateWrapper);
                    }
                }
                if (!CollectionUtils.isEmpty(companys)) {
                    for (CustomerCompanyEntity customerCompany : companys) {
                        try {
                            LiaisonEntity liaison = null;
                            if (!CollectionUtils.isEmpty(liaisons)) {
                                Optional<LiaisonEntity> optional = liaisons.stream().filter(e ->customerCompany.getCustomerId().equals(e.getCustomerId())).findFirst() ;
                                liaison = optional.isEmpty() ? null : optional.get();
                            }
                            customerMailBingMarkService.updateCustomerMailBingMark(customerCompany.getCustomerId(),Arrays.asList(customerCompany.getEmail()),(Objects.nonNull(liaison) ? liaison.getId() : null),(Objects.nonNull(liaison) ? Arrays.asList(liaison.getEmail()) : null));
                        }catch (Exception e) {
                            log.error("export -- updateCustomerLiaisonMailBingMark -- error :",e);
                        }
                    }
                }
            } else if (excelVo.getClass().equals(LiaisonExcelVerifyEntity.class)) {

                List<LiaisonExcelVerifyEntity> customVos = new ArrayList<>();
                for(T customVo : customExcelVos) {
                    customVos.add((LiaisonExcelVerifyEntity)customVo);
                }
                Set<String> customerNames = customVos.stream().filter(s -> StrUtil.isNotBlank(s.getCustomerName())).map(LiaisonExcelVerifyEntity::getCustomerName).collect(Collectors.toSet());
                Map<String,CustomerEntity> customerMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(customerNames)) {
                    List<CustomerEntity> customerls = customerService.list(new LambdaQueryWrapper<CustomerEntity>().in(CustomerEntity::getCustomerName,customerNames).eq(CustomerEntity::getOwnerBy,currentUserId).eq(CustomerEntity::getIsDelete,0));
                    if (!CollectionUtils.isEmpty(customerls)) {
//                        customerMap =  customerls.stream().collect(Collectors.toMap(CustomerEntity::getCustomerName,CustomerEntity::getId,(existing, replacement) -> existing));
                        customerMap = customerls.stream().collect(Collectors.toMap(CustomerEntity::getCustomerName,a ->a));
                    }
                }
                List<LiaisonAddDTO> liaisonDtos = new ArrayList<>();
                for(T customVo : customExcelVos) {
                    LiaisonExcelVerifyEntity liaisonExcel = (LiaisonExcelVerifyEntity) customVo;
                    LiaisonAddDTO liaisondto = LiaisonExcelVerifyEntity.getLiaisonAddDTO(liaisonExcel);
                    liaisondto.setOwnerBy(LoginUserUtil.getCurrentUserId());
                    if (!CollectionUtils.isEmpty(customerMap)) {
                        CustomerEntity customer = customerMap.get(liaisonExcel.getCustomerName());
                        if (Objects.nonNull(customer)) {
                            liaisondto.setCustomerId(customer.getId());
                            liaisondto.setOwnerBy(customer.getOwnerBy());
                        }
                    }
                    liaisonDtos.add(liaisondto);
                }
                if (CollectionUtils.isEmpty(liaisonDtos)) {
                    return Result.error("联系人数据异常");
                }
                List<LiaisonEntity> liaisons = LiaisonExcelVerifyEntity.assembleLiaisonLs(liaisonDtos);
                liaisonService.saveOrUpdateBatch(liaisons);
                if (!CollectionUtils.isEmpty(liaisons)) {
                    for (LiaisonEntity liaison : liaisons) {
                        try {
                            customerMailBingMarkService.updateCustomerLiaisonMailBingMark(liaison.getCustomerId(),liaison.getId(),Arrays.asList(liaison.getEmail()));
                        }catch (Exception e) {
                            log.error("export -- updateCustomerLiaisonMailBingMark -- error :",e);
                        }
                    }
                }
            }
        }catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("----------",e);
            return Result.error(e.getMessage());
        }
        return Result.ok();
    }
    /**
     * 获取redis 缓存的excel 数据进行导出
     */
    @RequestMapping(value = "export_temp", method = RequestMethod.POST)
    @ApiOperation(value = "获取错误临时excel")
    public void exportTemp(HttpServletResponse response,ExcelImportDTO dto) throws Exception {

//        ExcelExportDataVO dataVO =  redisService.getCacheObject(dto.getTemplateCode());
        ExcelExportDataVO dataVO =  redisService.getCacheObject(dto.getTempCode());
        if (Objects.isNull(dataVO)) {
            return;
        }
        List datas = dataVO.getDatas();
        List<ExcelExportEntity> titleList = dataVO.getExcelExportData();
        String fileName = dataVO.getFileName();

        int dataLen = datas.size();

        StringBuilder alertTitle = new StringBuilder();
        alertTitle.append(dataVO.getTitleAlert());
        int dictRow = Objects.nonNull(dataVO.getTitleRow()) ? dataVO.getTitleRow() : 2;
        List<SysDictEntity> dicts = getDictls(dataVO.getDictCode());
        if (!CollectionUtils.isEmpty(dicts)) {
            dictRow = dicts.size() + dictRow;
            String dictAppendStr = getDictAppendStr(dicts);
            alertTitle.append(dictAppendStr);
        }

        ExportParams exportParams = new ExportParams(alertTitle.toString(), dataVO.getFileName());
        exportParams.setFixedTitle(false);
        exportParams.setStyle(ExcelExportStyle.class);
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams,titleList,datas);
        Sheet sheet = workbook.getSheetAt(0);
        sheet.setDefaultRowHeight((short)(10*50));
        sheet.getRow(0).setHeight((short)(10*50*dictRow));
        sheet.getRow(1).setHeight((short)(10*50));

        Font font = workbook.createFont();
        font.setColor(HSSFColor.HSSFColorPredefined.RED.getIndex());

        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setFont(font);

        for(int i = 0; i< dataLen; i++) {
            sheet.getRow(i+2).getCell(titleList.size() - 1).setCellStyle(cellStyle);
        }
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        workbook.write(response.getOutputStream());
        workbook.close();
    }

//    @RequestMapping(value = "exportTemp", method = RequestMethod.POST)
//    @ApiOperation(value = "导出临时")
//    public void exportTemp(HttpServletResponse response, HttpServletRequest request,String tempCode) throws Exception {
//
//        String code = tempCode;
//
////        List<ExcelExportColumnRuleEntity> columns = excelExportColumnRuleService.list(new LambdaQueryWrapper<ExcelExportColumnRuleEntity>().eq(ExcelExportColumnRuleEntity::getExportTemplateId,exportTemplate.getId()));
////        Map<String, String> headers = new HashMap<>();
////        headers.put("Content-Type","application/json");
////        headers.put("token", request.getHeader("token"));
////
////        String port = environment.getProperty("server.port");
////        String path = environment.getProperty("server.servlet.context-path");
////        String url = exportTemplate.getInterfaceAddressUrl();
////        String res = HttpUtil.post("http://localhost:"+port+path+url,dto,headers,5000);
////        JSONObject jsonObject =  JSON.parseObject(res);
////        Result result = jsonObject.toJavaObject(Result.class);
////        List<JSONObject> ds;
////        if (result.getCode() != 200) {
////            return;
////        }
////        if (result.getResult().getClass().equals(List.class)) {
////            ds = (List<JSONObject>) result.getResult();
////        } else {
////            JSONObject json = (JSONObject) result.getResult();
////            ds = (List<JSONObject>) json.get("records");
////        }
//
//        List<ExcelExportEntity> titleList = new ArrayList();
//        for (ExcelExportColumnRuleEntity column : columns) {
//            ExcelExportEntity export = new ExcelExportEntity(column.getColumnName(),column.getColumnField(),column.getColumnWidth());
//            export.setOrderNum(column.getOrderNum());
//            titleList.add(export);
//        }
//
//        List datas = new ArrayList();
//        for(JSONObject json: ds) {
//            Map<String,String> map = new HashMap<>();
//            for (ExcelExportEntity entity : titleList) {
//                map.put(entity.getKey().toString(),json.getString(entity.getKey().toString()));
//            }
//            datas.add(map);
//        }
//        StringBuilder titleStr = new StringBuilder();
//        String queryCondition = dto.get("queryCondition").toString();
//        List<String> queryConditions = Arrays.asList(queryCondition.split(","));
//        for(String param : queryConditions) {
//            titleStr.append(param+"      ");
//        }
//        ExportParams exportParams = new ExportParams(titleStr.toString(), exportTemplate.getFileName());
//        exportParams.setFixedTitle(false);
//        exportParams.setHeight((short) 10);
//        exportParams.setStyle(ExcelExportStyle.class);
//        Workbook workbook = ExcelExportUtil.exportExcel(exportParams,titleList,datas);
//        Sheet sheet = workbook.getSheetAt(0);
//        sheet.setDefaultRowHeight((short)20);
//        sheet.getRow(0).setHeight((short)(25*50));
//        sheet.getRow(1).setHeight((short)(10*50));
//
//        response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(exportTemplate.getFileName()+ DateUtil.format(new Date(),"yyyyMMddHHmmss")+".xls", "UTF-8"));
//        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
//        try {
//            workbook.write(response.getOutputStream());
//        }catch (Exception e) {
//            log.error("error --workbook error = ",e);
//        }
//        workbook.close();
//    }


//    @RequestMapping(value = "import", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
//    @ApiOperation(value = "导入", response = Result.class)
//    public Result<?> importData(@RequestParam(value = "file", required = true) MultipartFile file) {
//
//        try {
//            ExcelImportTemplateEntity exportTemplate = excelImportTemplateService.getOne(new LambdaQueryWrapper<ExcelImportTemplateEntity>().eq(ExcelImportTemplateEntity::getTemplateCode,"IMPORT_USER_EXCEL"));
//
//            ImportParams params = new ImportParams();
//            params.setTitleRows(1);
//            params.setHeadRows(1);
//            List<Map<String, String>> list = ExcelImportUtil.importExcel(file.getInputStream(), Map.class, params);
//            Class<?> entityClass = loadClass(exportTemplate.getPackageName(), exportTemplate.getClassName());
//            List<ExcelImportColumnRuleEntity> columns = excelImportColumnRuleService.list(new LambdaQueryWrapper<ExcelImportColumnRuleEntity>().eq(ExcelImportColumnRuleEntity::getExportTemplateId,exportTemplate.getId()));
//
//            Map<String, Map<String, String>> dictMapMap = new HashMap<>();
//            Map<String, String>subCompanyMap = new HashMap<>();
//            Map<String, String> deptMap = new HashMap<>();
//            Map<String, String> userMap = new HashMap<>();
//            List importData = new ArrayList<>();
//            for(Map<String, String> dMap : list) {
//                Object entity = createInstance(entityClass);
//                for(ExcelImportColumnRuleEntity exportColumn : columns) {
//                    Object value = dMap.get(exportColumn.getColumnName());
//                    Field field = entity.getClass().getDeclaredField(exportColumn.getColumnField());
//                    field.setAccessible(true); // 允许访问私有字段
//                    Dict dict = AnnotationUtils.getAnnotation(field, Dict.class);
//                    String keyValue = value.toString();
//                    if(Objects.nonNull(dict)) {
//                        String v = convertDictByValue(dictMapMap, dict, keyValue);
//                        field.set(entity,v);
//                        continue;
//                    }
//                    OrgAutoMateAnnotate orgAnn =  AnnotationUtils.getAnnotation(field, OrgAutoMateAnnotate.class);
//                    if(Objects.nonNull(orgAnn)) {
//                        String v = null;
//                        if (orgAnn.annotationType().equals(AnnotateEnumType.SUB_COMPANY)) {
//                            if (CollectionUtils.isEmpty(subCompanyMap)) {
//                                List<SubCompanyEntity> subCompanys = subCompanyService.list();
//                                subCompanyMap = subCompanys.stream().collect(Collectors.toMap(SubCompanyEntity::getName,e -> String.valueOf(e.getId())));
//                            }
//                            v = convertOrgByValue(subCompanyMap, orgAnn, keyValue);
//                        }
//                        if (orgAnn.annotationType().equals(AnnotateEnumType.DEPT)) {
//                            if (CollectionUtils.isEmpty(deptMap)) {
//                                List<DeptEntity> depts = departService.list();
//                                deptMap = depts.stream().collect(Collectors.toMap(DeptEntity::getName, e -> String.valueOf(e.getId())));
//                            }
//                            v = convertOrgByValue(deptMap, orgAnn, keyValue);
//                        }
//                        if (orgAnn.annotationType().equals(AnnotateEnumType.USER)) {
//                            if (CollectionUtils.isEmpty(userMap)) {
//                                List<UserEntity> users = userService.list();
//                                userMap = users.stream().collect(Collectors.toMap(UserEntity::getRealName, e -> String.valueOf(e.getId())));
//                            }
//                            v = convertOrgByValue(userMap, orgAnn, keyValue);
//                        }
//                        field.set(entity,v);
//                        continue;
//                    }
//                    field.set(entity, value); // 设置字段值
//                }
//                importData.add(entity);
//           }
//            SysBaseField.dictFileds(importData);
//            this.getMyBaseService().saveBatch(importData);
//            return Result.result(importData);
//        }catch (Exception e) {
//            return Result.error("error-----"+e);
//        }
//    }

    /**
     * 处理字段为绑定的字典code 并且为dict字典value数据，然后转换为key值
     * @param dictMapMap
     * @param dict
     * @param keyValue
     * @return
     */
     private String convertDictByValue(Map<String, Map<String, String>> dictMapMap,Dict dict,String keyValue) {

         String valueStr = keyValue;
         Map<String,String> dictMap =dictMapMap.get(dict.dictCode());
         if (CollectionUtils.isEmpty(dictMap)) {
             dictMap = getDictVkMapByCode(dict.dictCode());
             dictMapMap.put(dict.dictCode(), dictMap);
         }
         if (CollectionUtils.isEmpty(dictMap)) {
             return "";
         }
         if (dict.multiple()) {
             if (valueStr.contains(",")) {
                 String[] values = valueStr.split(",");
                 StringBuilder dictValue = new StringBuilder();
                 for (String v : values) {
                     dictValue.append(dictMap.get(v)).append(",");
                 }
                 if (StrUtil.isNotBlank(dictValue)) {
                     dictValue.deleteCharAt(dictValue.length() - 1);
                 }
                 return dictValue.toString();
             }
         }
         return dictMap.get(valueStr);
     }

    @SneakyThrows
    public String convertOrgByValue(Map<String, String> orgMap,OrgAutoMateAnnotate orgAnn,String keyValue) {
        String valueStr = keyValue;
        Map<String,String> dictMap = orgMap;
        if (orgAnn.multiple()) {
            if (valueStr.contains(",")) {
                String[] values = valueStr.split(",");
                StringBuilder dictValue = new StringBuilder();
                for (String v : values) {
                    dictValue.append(dictMap.get(v)).append(",");
                }
                if (StrUtil.isNotBlank(dictValue)) {
                    dictValue.deleteCharAt(dictValue.length() - 1);
                }
                return dictValue.toString();
            }
        }
        return dictMap.get(valueStr);
    }


    private static Class<?> loadClass(String packageName, String className) {
        try {
            // 构建完整的类名
            String fullName = packageName + "." + className;
            // 加载类
            return Class.forName(fullName);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    private static Object createInstance(Class entityClass) throws Exception {
        // 获取无参构造器
        Constructor<?> constructor = entityClass.getConstructor();
        // 创建实例
        return constructor.newInstance();
    }

    private static void setFieldValues(Object entity, Map<String, Object> fieldValues) throws Exception {
        for (Map.Entry<String, Object> entry : fieldValues.entrySet()) {
            String fieldName = entry.getKey();
            Object value = entry.getValue();
            // 获取字段
            Field field = entity.getClass().getDeclaredField(fieldName);
            // 允许访问私有字段
            field.setAccessible(true);
            // 为字段赋值
            field.set(entity, value);
        }
    }

    public File transferToFile(MultipartFile multipartFile) {
//        选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
        File file = null;
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            String[] filename = originalFilename.split("\\.");
            file=File.createTempFile(filename[0], filename[1]);
            multipartFile.transferTo(file);
            file.deleteOnExit();
        } catch (IOException e) {
        }
        return file;
    }

//    @RequestMapping(value = "download_import_template", method = RequestMethod.POST)
//    @ApiOperation(value = "导出导入模板")
//    public void downloadImportTemplate(HttpServletResponse response,String templateCode) throws Exception{
////        ExcelImportTemplateEntity exportTemplate = excelImportTemplateService.getOne(new LambdaQueryWrapper<ExcelImportTemplateEntity>().eq(ExcelImportTemplateEntity::getTemplateCode,templateCode));
////
////        List<ExcelImportColumnRuleEntity> columns = excelImportColumnRuleService.list(new LambdaQueryWrapper<ExcelImportColumnRuleEntity>().eq(ExcelImportColumnRuleEntity::getExportTemplateId,exportTemplate.getId()));
//
//        ClassPathResource classPathResource = new ClassPathResource("templates/import_general_template.xlsx");
//        TemplateExportParams params = new TemplateExportParams(classPathResource.getPath(),true);
//        // 模板导出
//        Map<String, Object> map = new HashMap<String, Object>();
//        ArrayList<Object> list = new ArrayList<>();
//
//        Field[] fields  = ExcelVerifyEntity.class.getDeclaredFields();
//        for(Field field : fields) {
//            if (field.isAnnotationPresent(Excel.class)) {
//                Excel column = field.getAnnotation(Excel.class);
//                HashMap<String, String> lm = new HashMap<>();
//                NotNull ntn = field.getAnnotation(NotNull.class);
//                String str = "";
//                if (Objects.nonNull(ntn)) {
//                    str ="*";
//                }
//                lm.put("title",str+ "" + column.name());
//                list.add(lm);
//            }
//        }
//
//        map.put("list", list);
//        params.setColForEach(true);
//        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
//        Sheet sheet = workbook.getSheetAt(0);
//        sheet.setDefaultRowHeight((short)(10*50));
//        response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode("测试"+ DateUtil.format(new Date(),"yyyyMMddHHmmss")+".xls", "UTF-8"));
//        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
//
//        try {
//            workbook.write(response.getOutputStream());
//            workbook.close();
//        }catch (Exception e) {
//            log.error("error --workbook error = ",e);
//        }
//    }

    @RequestMapping(value = "download_import_template", method = RequestMethod.POST)
    @ApiOperation(value = "导出导入模板")
    public void downloadImportTemplate(HttpServletResponse response,String templateCode) throws Exception {
//        if ("IMPORT_CLUE_EXCEL".equals(templateCode)) {
//            return;
//        }
        ExcelImportTemplateEntity exportTemplate = excelImportTemplateService.getOne(new LambdaQueryWrapper<ExcelImportTemplateEntity>().eq(ExcelImportTemplateEntity::getTemplateCode,templateCode));
        Class<?> entityClass = loadClass(exportTemplate.getPackageName(), exportTemplate.getClassName());
        Field[] fields  = entityClass.getDeclaredFields();

        List<ExcelExportEntity> titleList = new ArrayList();
        int columnIndex = 0;
        List<Integer> columnIndexList = new ArrayList<>();
        for(Field field : fields) {
            if (field.isAnnotationPresent(Excel.class)) {
                Excel column = field.getAnnotation(Excel.class);
                NotNull ntn = field.getAnnotation(NotNull.class);
                String str = "";
                if (Objects.nonNull(ntn)) {
                    columnIndexList.add(columnIndex);
                }
                String columnName = str + "" + column.name();
                ExcelExportEntity exportColumn = new ExcelExportEntity(columnName, field.getName(),25);
                titleList.add(exportColumn);
                columnIndex++;
            }
        }
        try {

            List datas = new ArrayList();
            Map<String,String> map = new HashMap<>();
            for (ExcelExportEntity entity : titleList) {
                map.put(entity.getKey().toString(),"");
            }
            datas.add(map);
            StringBuilder alertTitle = new StringBuilder();
            alertTitle.append(exportTemplate.getTitleAlert());
            int dictRow = Objects.nonNull(exportTemplate.getTitleRow()) ? exportTemplate.getTitleRow() : 2;
            List<SysDictEntity> dicts = getDictls(exportTemplate.getDictCode());
            if (!CollectionUtils.isEmpty(dicts)) {
                dictRow = dicts.size() + dictRow;
                String dictAppendStr = getDictAppendStr(dicts);
                alertTitle.append(dictAppendStr);
            }

            ExportParams exportParams = new ExportParams(alertTitle.toString(), exportTemplate.getTemplateNme());
            exportParams.setFixedTitle(false);
            exportParams.setStyle(ExcelExportStyle.class);
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams,titleList,datas);
            Sheet sheet = workbook.getSheetAt(0);
            sheet.setDefaultRowHeight((short)(10*50));
            sheet.getRow(0).setHeight((short)(10*50*dictRow));
            sheet.getRow(1).setHeight((short)(10*50));

//            CellStyle style1 = workbook.createCellStyle();
//            //水平居中
//            style1.setAlignment(HorizontalAlignment.CENTER);
//            //上下居中
//            style1.setVerticalAlignment(VerticalAlignment.CENTER);
//            //设置自动换行
//            style1.setWrapText(true);
//            sheet.getRow(0).getCell(0).setCellStyle(style1);

            ExcelExportStyle style =new ExcelExportStyle();
            if (!CollectionUtils.isEmpty(columnIndexList)) {
                columnIndexList.forEach(cIndex -> {
                    CellStyle cellStyle = style.initTitleStyle(workbook);
                    Font font = workbook.createFont();
                    //字体样式
                    font.setFontName("宋体");
                    //是否加粗
                    font.setBold(true);
                    //字体大小
                    font.setFontHeightInPoints((short) 16);
                    font.setColor(HSSFColor.HSSFColorPredefined.RED.getIndex());
//                    cellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.RED.getIndex());
//                    cellStyle.setFillBackgroundColor(HSSFColor.HSSFColorPredefined.RED.getIndex());
//                    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                    cellStyle.setFont(font);
                    sheet.getRow(1).getCell(cIndex).setCellStyle(cellStyle);
                });

            }
            response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(exportTemplate.getTemplateNme()+".xls", "UTF-8"));
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            workbook.write(response.getOutputStream());
            workbook.close();
        }catch (Exception e) {
            log.error("error ---",e);
        }
    }

    public String getDictAppendStr(List<SysDictEntity> dicts) {
        List<Long> dictIds = dicts.stream().map(SysDictEntity::getDictId).collect(Collectors.toList());
        LambdaQueryWrapper<SysDictDetailEntity> detialWq = new LambdaQueryWrapper<SysDictDetailEntity>();
        detialWq.in(SysDictDetailEntity::getDictId,dictIds);
        detialWq.eq(SysDictDetailEntity::getIsDelete,Integer.valueOf(0));
        detialWq.eq(SysDictDetailEntity::getEnabled,1);
        List<SysDictDetailEntity> vos1 = sysDictDetailService.list(detialWq);
        if (CollectionUtils.isEmpty(vos1)) {
            return "";
        }
        StringBuilder subStr = new StringBuilder();
        for (SysDictEntity dict : dicts) {
            subStr.append("\n");
            subStr.append(dict.getName()+"：");
            List<SysDictDetailEntity> rs = vos1.stream().filter(s ->s.getDictId().equals(dict.getDictId())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(rs)) {
                subStr.append(rs.stream().map(SysDictDetailEntity::getLabel).collect(Collectors.joining(",")));
            }
        }
        return subStr.toString();
    }


    public List<SysDictEntity> getDictls(String dictCodes) {
         if (StrUtil.isBlank(dictCodes)) {
             return null;
         }
        String codes[] = dictCodes.split(",");
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(SysDictEntity::getIsDelete,Integer.valueOf(0));
        queryWrapper.eq(SysDictEntity::getEnabled,1);
        queryWrapper.in(SysDictEntity::getCode,Arrays.asList(codes));
        List<SysDictEntity> vos = sysDictService.list(queryWrapper);
        return vos;
    }

    @RequestMapping(value = "export", method = RequestMethod.POST)
    @ApiOperation(value = "导出")
    public void exportData(HttpServletResponse response, HttpServletRequest request,@RequestBody Map dto) throws Exception {

        String templateCode = dto.get("templateCode").toString();
        String desc =  "描述";

        ExcelExportTemplateEntity exportTemplate = excelExportTemplateService.getOne(new LambdaQueryWrapper<ExcelExportTemplateEntity>().eq(ExcelExportTemplateEntity::getTemplateCode,templateCode));
        if (Objects.isNull(exportTemplate)) {
            return;
        }

        List<ExcelExportColumnRuleEntity> columns = excelExportColumnRuleService.list(new LambdaQueryWrapper<ExcelExportColumnRuleEntity>().eq(ExcelExportColumnRuleEntity::getExportTemplateId,exportTemplate.getId()));
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type","application/json");
        headers.put("token", request.getHeader("token"));

        String port = environment.getProperty("server.port");
        String path = environment.getProperty("server.servlet.context-path");
        String url = exportTemplate.getInterfaceAddressUrl();
        String res = HttpUtil.post("http://localhost:"+port+path+url,dto,headers,15000);
//        JSONObject jsonObject =  JSON.parseObject(res);
        JSONObject jsonObject = SafeJsonParser.parseSafely(res);
        Result result =  jsonObject.toJavaObject(Result.class);

//        Gson gson = new GsonBuilder().setLenient().create();;
//        // 将JSON字符串转换回CustomerEntity对象
//        Result result = gson.fromJson(res.replace("\"",  "\\\""), Result.class);

        List<JSONObject> ds;
        if (result.getCode() != 200) {
            return;
        }
        if (result.getResult().getClass().equals(List.class)) {
            ds = (List<JSONObject>) result.getResult();
        } else {
            JSONObject json = (JSONObject) result.getResult();
            ds = (List<JSONObject>) json.get("records");
        }

        List<ExcelExportEntity> titleList = new ArrayList();
        for (ExcelExportColumnRuleEntity column : columns) {
            ExcelExportEntity export = new ExcelExportEntity(column.getColumnName(),column.getColumnField(),column.getColumnWidth());
            export.setOrderNum(column.getOrderNum());
            titleList.add(export);
        }

        List datas = new ArrayList();
        for(JSONObject json: ds) {
            Map<String,String> map = new HashMap<>();
            for (ExcelExportEntity entity : titleList) {
                String mapKey = entity.getKey().toString();
                if (mapKey.contains(".")) {
                    String [] mapKeys = mapKey.split("\\.");
                    JSONObject subJson = (JSONObject) json.get(mapKeys[0]);
                    if(Objects.isNull(subJson)) {
                        map.put(entity.getKey().toString(),"");
                    } else {
                        map.put(entity.getKey().toString(),subJson.getString(mapKeys[1]));
                    }
                }else {
                    map.put(entity.getKey().toString(),json.getString(entity.getKey().toString()));
                }
            }
            datas.add(map);
        }
        StringBuilder titleStr = new StringBuilder();
        //String queryCondition = dto.get("queryCondition").toString();
//        List<String> queryConditions = Arrays.asList(queryCondition.split(","));
//        for(String param : queryConditions) {
//            titleStr.append(param+"      ");
//        }
        titleStr.append(desc);
        ExportParams exportParams = new ExportParams(titleStr.toString(), exportTemplate.getFileName());
        exportParams.setFixedTitle(false);
        exportParams.setHeight((short) 10);
        exportParams.setStyle(ExcelExportStyle.class);
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams,titleList,datas);
        Sheet sheet = workbook.getSheetAt(0);
        sheet.setDefaultRowHeight((short)(10*50));
        sheet.getRow(0).setHeight((short)(35*50));
        sheet.getRow(1).setHeight((short)(10*50));

        response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(exportTemplate.getFileName()+ DateUtil.format(new Date(),"yyyyMMddHHmmss")+".xlsx", "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.addHeader("Access-Control-Expose-Headers","content-disposition");
        /*
         * 跨域配置
         * */
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
        try {
            workbook.write(response.getOutputStream());
        }catch (Exception e) {
            log.error("error --workbook error = ",e);
        }
        workbook.close();
    }

    private Map<String, String> getDictVkMapByCode(String dictCode) {
        QueryWrapper<SysDictEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysDictEntity::getCode,dictCode);
        List<SysDictEntity> dictList = dictService.list(wrapper);
        QueryWrapper<SysDictDetailEntity> detailWrapper = new QueryWrapper<>();
        List<Long> dIds = dictList.stream().map(SysDictEntity::getDictId).collect(Collectors.toList());
        detailWrapper.lambda().in(SysDictDetailEntity::getDictId,dIds);
        List<SysDictDetailEntity> detailList = dictDetailService.list(detailWrapper);
        if (CollectionUtils.isEmpty(detailList)) {
            return null;
        }
        return detailList.stream().collect(Collectors.toMap(SysDictDetailEntity::getLabel, SysDictDetailEntity::getValue));
    }



//    public static void main(String[] args) throws Exception {
//        // 创建一个密钥生成器，用于HMAC SHA256
//        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
//
//        // 初始化密钥生成器，密钥长度为256位
//        keyGenerator.init(256, new SecureRandom());
//
//        // 生成一个密钥
//        SecretKey secretKey = keyGenerator.generateKey();
//
//        // 转换为Base64编码的字符串，以便于在配置文件中存储或作为字符串使用
//        byte[] encodedKey = secretKey.getEncoded();
//        String base64EncodedKey = java.util.Base64.getEncoder().encodeToString(encodedKey);
//
//        // 打印Base64编码后的密钥
//        System.out.println("JWT Secret Key (Base64 encoded): " + base64EncodedKey);
//
//        // 在这里，你可以将base64EncodedKey的值复制到你的配置文件中
//    }
}
