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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.tzs.api.dto.*;
import com.yeejoin.amos.boot.module.tzs.api.entity.*;
import com.yeejoin.amos.boot.module.tzs.api.enums.EquimentEnum;
import com.yeejoin.amos.boot.module.tzs.api.enums.EquipmentCategoryEnum;
import com.yeejoin.amos.boot.module.tzs.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.tzs.api.mapper.*;
import com.yeejoin.amos.boot.module.tzs.api.service.IEquipmentCategoryService;
import com.yeejoin.amos.boot.module.tzs.api.vo.EquipExportVo;
import com.yeejoin.amos.boot.module.tzs.biz.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.tzs.biz.utils.JsonUtils;
import com.yeejoin.amos.boot.module.tzs.flc.api.feign.IdxFeignService;
import com.yeejoin.amos.boot.module.tzs.flc.api.feign.PrivilegeFeginService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.DateUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.toJSONString;

/**
 * 装备分类服务实现类
 *
 * @author system_generator
 * @date 2021-10-20
 */
@Service
@Slf4j
public class EquipmentCategoryServiceImpl extends BaseService<EquipmentCategoryDto, EquipmentCategory, EquipmentCategoryMapper> implements IEquipmentCategoryService {

    @Autowired
    ESEquipmentCategory esEquipmentCategory;

    @Autowired
    private SuperviseInfoMapper superviseInfoMapper;

    @Autowired
    private UseInfoMapper useInfoMapper;


    @Autowired
    EquipmentCategoryMapper equipmentCategoryMapper;

    @Value("classpath:/json/equipCategory.json")
    private Resource equipCategory;

    @Autowired
    private JdbcTemplate bizJdbcTemplate;

    @Autowired
    CategoryOtherInfoMapper categoryOtherInfoMapper;

    @Autowired
    SupervisoryCodeInfoMapper supervisoryCodeInfoMapper;

    @Autowired
    SuperviseInfoService superviseInfoService;

    @Autowired
    EquipmentCategoryDataMapper equipmentCategoryDataMapper;

    @Autowired
    EquipmentCategoryDataServiceImpl equipmentCategoryDataService;

    @Autowired
    PrivilegeFeginService privilegeFeginService;
    @Autowired
    IdxFeignService idxFeignService;

    @Autowired
    private static final String TABLENAME = "tableName";

    @Value("${regulator.unit.code}")
    private String code;

    @Autowired
    private RedisUtils redisUtils;
    //管辖机构redis缓存key
    private static final String REGULATOR_UNIT_TREE = "REGULATOR_UNIT_TREE";
    //行政区划redis缓存key
    private static final String PROVINCE = "PROVINCE";
    private static final String CITY = "CITY";
    private static final String REGION = "REGION";
    private static final String STREET = "STREET";
    //行政区划level
    private static final String PROVINCE_LEVEL = "1";
    private static final String CITY_LEVEL = "2";
    private static final String REGION_LEVEL = "3";
    private static final String STREET_LEVEL = "4";
    //西安行政区划code
    private static final String XIAN = "610100";
    //判断行政区划查询市还是区
    private static final String END_CODE = "0000";
    //判断行政区划查询街道
    private static final String STREET_END_CODE = "00";
    //一码通监督管理表单id
    private static final String SUPERVISION_FROM_ID = "1627903532906602497";

    //一码通使用信息表单id
    private static final String USE_INFO_FROM_ID = "1627903393253056514";

    //一码通码自动生成
    final static String CREATE = "1";
    //一码通码手动输入
    final static String NOT_CREATE = "0";


    //一码通复制功能url参数key
    private static final String COPY_KEY = "stashType";

    @Value("${biz.elasticsearch.address}")
    private String esAddress;

    @Value("${biz.elasticsearch.port}")
    private Integer esPort;

    @Value("${elasticsearch.username}")
    private String esUserName;

    @Value("${elasticsearch.password}")
    private String esPwd;

    private static String USE_CODE = "use_code";

    private static String ORG_BRANCH_CODE = "supervise_org_code";

    /**
     * 分页查询
     */
    public Page<EquipmentCategoryDto> queryForEquipmentCategoryPage(Page<EquipmentCategoryDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<EquipmentCategoryDto> queryForEquipmentCategoryList() {
        return this.queryForList("", false);
    }

    public List<EquipmentCategoryDto> selectClassify() {
        return equipmentCategoryMapper.selectClassify();
    }

    @Override
    public List<Map<String, Object>> equipTree(String type) {
        List<Map<String, Object>> menus = new ArrayList<>();
        Map<String, List<Map<String, Object>>> resourceJson = JsonUtils.getResourceJson(equipCategory);
        List<Map<String, Object>> mapList;
        if (ValidationUtil.isEmpty(type)) {
            mapList = resourceJson.get(EquipmentClassifityEnum.BDLS.getCode());
        } else {
            mapList = resourceJson.get(type);
        }
        for (Map map : mapList) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("instanceName", map.get("name"));
            resultMap.put("instanceId", map.get("code"));
            menus.add(resultMap);
        }
        return menus;
    }

    @Override
    public Page equipClaimOverview() {
        Page page = new Page<>();
        Map<String, List<Map<String, Object>>> resourceJson = JsonUtils.getResourceJson(equipCategory);
        List<Map<String, Object>> mapList = resourceJson.get(EquipmentClassifityEnum.BDLS.getCode());
        List<Map<String, Object>> list = new ArrayList<>();
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        if (ObjectUtils.isEmpty(reginParams)) {
            return null;
        }
        String level = reginParams.getUserModel().getCompanys().get(0).getLevel();
        String orgCode = reginParams.getUserModel().getCompanys().get(0).getOrgCode();
        String companyCode = reginParams.getUserModel().getCompanys().get(0).getCompanyCode();
        List<Map<String, Object>> listMap = equipmentCategoryMapper.getCategoryData(level, orgCode, companyCode);
        for (Map<String, Object> map : mapList) {
            for (Map<String, Object> map1 : listMap) {
                for (String s : map1.keySet()) {
                    HashMap<String, Object> jsonMap = JSON.parseObject(map1.get(s).toString(), new TypeReference<HashMap<String, Object>>() {
                    });
                    if (s.equals(map.get("type"))) {
                        map.put("waitClaim", Long.valueOf(map.get("waitClaim").toString()) + Long.valueOf(jsonMap.get("waitClaim").toString()));
                        map.put("alreadyClaim", Long.valueOf(map.get("alreadyClaim").toString()) + Long.valueOf(jsonMap.get("alreadyClaim").toString()));
                        map.put("refuseClaim", Long.valueOf(map.get("refuseClaim").toString()) + Long.valueOf(jsonMap.get("refuseClaim").toString()));
                        Long sum = Long.valueOf(jsonMap.get("waitClaim").toString()) + Long.valueOf(jsonMap.get("alreadyClaim").toString()) + Long.valueOf(jsonMap.get("refuseClaim").toString());
                        map.put("sum", Long.valueOf(map.get("sum").toString()) + sum);
                    }
                }
            }
            list.add(map);
        }
        page.setCurrent(1);
        page.setTotal(list.size());
        page.setRecords(list);
        return page;
    }

    /**
     * 生成监管码和电梯96333识别码
     */
    @Override
    public Map<String, String> createSupervisorCode(Map<String, Object> map, String record) {
        String city, county, equipCategory;
        EquInfoDto equInfoDto = new EquInfoDto();
        if (ObjectUtils.isEmpty(record)) {
            //获取对应行政区划
            county = EquipmentCategoryEnum.XZQH.getCode();
            city = map.get("regionCode").toString();
            //获取对应设备分类
            equipCategory = map.get("equCategory").toString();
        } else {
            equInfoDto = categoryOtherInfoMapper.selectEquipInfo(record);
            //判断这条数据认领状态是否为已认领,否则直接返回
            if (!ObjectUtils.isEmpty(equInfoDto) && EquipmentCategoryEnum.YRL.getName().equals(equInfoDto.getStatus())) {
                city = equInfoDto.getCity();
                county = equInfoDto.getCounty();
                equipCategory = equInfoDto.getEquipCategory();
            } else {
                return new HashMap<>();
            }
        }
        //生成码
        EquipmentCategoryServiceImpl categoryService = (EquipmentCategoryServiceImpl) AopContext.currentProxy();
        Map<String, String> codeMap = categoryService.creatCode(city, county, equipCategory, null, null);
        if (ObjectUtils.isEmpty(codeMap)) {
            return new HashMap<>();
        }
        log.info(record + "已生成对应监管码或96333电梯识别码");
        String equState = EquipmentCategoryEnum.CSZT.getCode();
        SupervisoryCodeInfo supervisoryCodeInfo = new SupervisoryCodeInfo();
        supervisoryCodeInfo.setCode96333(codeMap.get("code96333"));
        supervisoryCodeInfo.setSupervisoryCode(codeMap.get("superviseCode"));
        supervisoryCodeInfo.setStatus(equState);
        if (!ObjectUtils.isEmpty(record)) {
            String supervisorCode, elevatorCode;
            //设备状态为报废，对应电梯码作废
            equState = EquipmentCategoryEnum.BF.getCode().equals(equInfoDto.getEquState()) ? EquipmentCategoryEnum.WSY.getCode() : EquipmentCategoryEnum.YSY.getCode();
            supervisorCode = codeMap.get("superviseCode");
            elevatorCode = EquipmentCategoryEnum.BF.getCode().equals(equInfoDto.getEquState()) ? null : codeMap.get("code96333");
            List<CategoryOtherInfo> categoryOtherInfo = categoryOtherInfoMapper.selectList(new QueryWrapper<CategoryOtherInfo>().eq("SUPERVISORY_CODE", supervisorCode));
            if (categoryOtherInfo.size() > 0) {
                supervisoryCodeInfoMapper.update(supervisoryCodeInfo,new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code",supervisoryCodeInfo.getSupervisoryCode()));
            } else {
                supervisoryCodeInfo.setStatus(equState);
                supervisoryCodeInfoMapper.insert(supervisoryCodeInfo);
            }
            //修改源数据的电梯码
            categoryOtherInfoMapper.updateSupervisorCode(supervisorCode, elevatorCode, record);
        } else {
            supervisoryCodeInfoMapper.insert(supervisoryCodeInfo);
        }
        return codeMap;
    }

    @Override
    public List<LinkedHashMap> getTree() {
        List<LinkedHashMap> result = (List<LinkedHashMap>) redisUtils.get(REGULATOR_UNIT_TREE);
        //判断redis是否存在管辖机构树
        return !ObjectUtils.isEmpty(result) ? result : creatTree();
    }

    @Override
    public List<LinkedHashMap> creatTree() {
        FeignClientResult tree = privilegeFeginService.tree(RequestContext.getToken(),RequestContext.getAppKey(),RequestContext.getProduct());
        List<LinkedHashMap> result = (List<LinkedHashMap>) tree.getResult();
        List<LinkedHashMap> treeData = deleteRegulatorTreeData(result);
        List<LinkedHashMap> supervisionTree = treeData.stream().filter(e -> code.equals(e.get("orgCode"))).collect(Collectors.toList());
        List<LinkedHashMap> resultTree = updateNullChildren(supervisionTree);
        redisUtils.set(REGULATOR_UNIT_TREE, resultTree);
        return resultTree;
    }

    /**
     * 将管辖机构树中children为[]的修改为null
     *
     * @param result
     * @return
     */
    private List<LinkedHashMap> updateNullChildren(List<LinkedHashMap> result) {
        Iterator it = result.iterator();
        while (it.hasNext()) {
            LinkedHashMap e = (LinkedHashMap) it.next();
            //将管辖机构树中children为[]的修改为null
            if (e.get("children") != null) {
                if (((List<LinkedHashMap>) e.get("children")).size() == 0) {
                    e.put("children", null);
                }
            }
            if (!ObjectUtils.isEmpty(e.get("children"))) {
                updateNullChildren((List<LinkedHashMap>) e.get("children"));
            }
        }
        return result;
    }

    /**
     * 删除管辖机构树中level为使用单位的数据
     *
     * @param result 管辖机构树
     * @return 筛选过滤后不包含使用单位的管辖机构树
     */
    private List<LinkedHashMap> deleteRegulatorTreeData(List<LinkedHashMap> result) {
        Iterator it = result.iterator();
        while (it.hasNext()) {
            LinkedHashMap e = (LinkedHashMap) it.next();
            //删除使用单位
            if ("company".equals(e.get("level"))) {
                it.remove();
            }
            if (e.get("companyName").toString().contains("行政审批局")) {
                it.remove();
            }
            if (!ObjectUtils.isEmpty(e.get("children"))) {
                deleteRegulatorTreeData((List<LinkedHashMap>) e.get("children"));
            }
        }
        return result;
    }


    @Override
    public List<LinkedHashMap> getRegion(String level, String parentId) {
        List<LinkedHashMap> list = new ArrayList<>();
        if (!ObjectUtils.isEmpty(level)) {
            list = (List<LinkedHashMap>) redisUtils.get(PROVINCE);
            return ObjectUtils.isEmpty(list) ? getProvinceList(level) : list;
        } else if (!ObjectUtils.isEmpty(parentId)) {
            String regionCode = parentId.split("_")[0];
            //regionCode不是以00结尾查询街道，以0000结果查询市、否则查询区
            if (!regionCode.endsWith(STREET_END_CODE)) {
                list = ObjectUtils.isEmpty(redisUtils.get(STREET)) ? getProvinceList(STREET_LEVEL) : (List<LinkedHashMap>) redisUtils.get(STREET);
            } else if (regionCode.endsWith(END_CODE)) {
                list = ObjectUtils.isEmpty(redisUtils.get(CITY)) ? getProvinceList(CITY_LEVEL) : (List<LinkedHashMap>) redisUtils.get(CITY);
            } else {
                list = ObjectUtils.isEmpty(redisUtils.get(REGION)) ? getProvinceList(REGION_LEVEL) : (List<LinkedHashMap>) redisUtils.get(REGION);
            }
            return list.stream().filter(r -> regionCode.equals(r.get("parentRegionCode").toString())).collect(Collectors.toList());
        } else {
            return new ArrayList<>();
        }
    }

    public List<LinkedHashMap> getProvinceList(String level) {
        FeignClientResult result = privilegeFeginService.getProvince(level);
        List<LinkedHashMap> list = (List<LinkedHashMap>) result.getResult();
        for (LinkedHashMap linkedHashMap : list) {
            linkedHashMap.put("sequenceNbr", linkedHashMap.get("regionCode"));
        }
        switch (level) {
            case PROVINCE_LEVEL:
                redisUtils.set(PROVINCE, list);
                break;
            case CITY_LEVEL:
                redisUtils.set(CITY, list);
                break;
            case REGION_LEVEL:
                redisUtils.set(REGION, list);
                break;
            case STREET_LEVEL:
                redisUtils.set(STREET, list);
                break;
            default:
                log.error("不支持的行政区划：{}", level);
                break;
        }
        return list;
    }

    @Override
    public Map<String, Object> getCategoryAndDefineByRecord(String record) {
        if (ObjectUtils.isEmpty(record)) {
            return new HashMap<>();
        }
        return equipmentCategoryMapper.getCategoryAndDefineByRecord(record);
    }

    @Override
    public List<CategoryOtherInfo> checkCode(Map<String, Object> obj) {
        List<CategoryOtherInfo> codeList;
        if ("save".equals(obj.get("type"))) {
            codeList = categoryOtherInfoMapper.selectList(new QueryWrapper<CategoryOtherInfo>().eq("CODE96333", obj.get("CODE96333")));
        } else {
            codeList = categoryOtherInfoMapper.selectList(new QueryWrapper<CategoryOtherInfo>().ne("RECORD", obj.get("id")).eq("CODE96333", obj.get("CODE96333")));
        }
        return codeList;
    }

    @Override
    public List<String> updateOtherInfo(Map<String, Object> map) {
        List<String> supervisoryCodeList = (ArrayList) map.get("supervisoryCode");
        List<String> list = new ArrayList<>();
        for (String supervisoryCode : supervisoryCodeList) {
            CategoryOtherInfo categoryOtherInfo = categoryOtherInfoMapper.selectOne(new QueryWrapper<CategoryOtherInfo>().eq("SUPERVISORY_CODE", supervisoryCode));
            if (ObjectUtils.isEmpty(categoryOtherInfo)) {
                list.add(supervisoryCode + "：对应的数据修改失败，请查询对应监管码是否正确");
            } else {
                list.add(supervisoryCode + (categoryOtherInfoMapper.updateOtherInfo(supervisoryCode, "1") == 1 ? "：对应的数据已经修改成功" : "：对应的数据修改失败，请查询对应监管码是否正确"));
            }
        }
        return list;
    }

    /**
     * 具体生成监管码和电梯96333识别码逻辑
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public synchronized Map<String, String> creatCode(String city, String county, String equipCategory, String code96333,String supervisionCode) {
        Map<String, String> resultMap = new HashMap<>();
        StringBuilder supervisorCode = new StringBuilder();
        StringBuilder elevatorCode = new StringBuilder();
        CategoryOtherInfo categoryOtherInfo = new CategoryOtherInfo();
        String prefix;
        //判断是否需要生成96333电梯码
        if (equipCategory.startsWith("3") && !XIAN.equals(city)) {
            //判断数据是否携带96333电梯码，携带则使用，不携带则生成
            if("null".equals(code96333)){
                Map<String, Object> elevatorMap = equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQHDT.getCode(), county);
                prefix = ObjectUtils.isEmpty(elevatorMap) ? equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQHDT.getCode(), city).get("code").toString() : elevatorMap.get("code").toString();
                //查询未使用的电梯码
                categoryOtherInfo = categoryOtherInfoMapper.selectElevatorCode(prefix, EquipmentCategoryEnum.WSY.getCode());
                //如果存在未使用的电梯码则启用未使用的否则创建
                String elevator = ObjectUtils.isEmpty(categoryOtherInfo) ? createElevatorCode(prefix) : categoryOtherInfo.getCode();
                if(!ObjectUtils.isEmpty(categoryOtherInfo)){
                    supervisoryCodeInfoMapper.delete(new QueryWrapper<SupervisoryCodeInfo>().eq("code96333",categoryOtherInfo.getCode()));
                }
                elevatorCode.append(elevator);
                resultMap.put("creatStatus",CREATE);
            } else {
                elevatorCode.append(code96333);
                resultMap.put("creatStatus",NOT_CREATE);
            }
        }
        //判断原数据是否存在监管码，存在则用原监管码即可，不存在则生成
        if("null".equals(supervisionCode)){
            String supervisor = createSupervisorCode(city, county, equipCategory);
            supervisorCode.append(supervisor);
        } else {
            supervisorCode = new StringBuilder(supervisionCode);
        }

        if (ObjectUtils.isEmpty(supervisorCode) && ObjectUtils.isEmpty(elevatorCode)) {
            return new HashMap<>();
        }

        SupervisoryCodeInfo supervisoryCodeInfo = new SupervisoryCodeInfo();
        SupervisoryCodeInfo selectOne = supervisoryCodeInfoMapper.selectOne(new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code", supervisionCode));
        //将生成的码添加到码表中，码的使用状态为初始状态
        String equState = EquipmentCategoryEnum.CSZT.getCode();
        supervisoryCodeInfo.setCode96333(String.valueOf(elevatorCode));
        supervisoryCodeInfo.setCreateStatus(resultMap.get("creatStatus"));
        supervisoryCodeInfo.setSupervisoryCode(String.valueOf(supervisorCode));
        supervisoryCodeInfo.setStatus(equState);
        if(ObjectUtils.isEmpty(selectOne)){
            supervisoryCodeInfoMapper.insert(supervisoryCodeInfo);
        } else {
            selectOne.setCode96333(String.valueOf(elevatorCode));
            supervisoryCodeInfoMapper.update(selectOne,
                    new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code",selectOne.getSupervisoryCode()));
        }
        resultMap.put("superviseCode", ObjectUtils.isEmpty(supervisorCode) ? null : supervisorCode.toString());
        resultMap.put("code96333", ObjectUtils.isEmpty(elevatorCode) ? null : elevatorCode.toString());
        resultMap.put("qrCode", ObjectUtils.isEmpty(supervisorCode) ? null : supervisorCode.toString());
        return resultMap;
    }

    private String getPrefix(String type, String county) {
        return equipmentCategoryMapper.getAdministrativeDivision(type, county).get("code").toString();
    }

    /**
     * 生成监管码
     *
     * @param city   行政区划市
     * @param county 行政区划区
     * @return 监管码
     */
    public String createSupervisorCode(String city, String county, String equipCategory) {
        StringBuilder supervisorCode = new StringBuilder();
        //生成监管码前缀
        Map<String, Object> divisionMap = equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQH.getCode(), county);
        String division = ObjectUtils.isEmpty(divisionMap) ? equipmentCategoryMapper.getAdministrativeDivision(EquipmentCategoryEnum.XZQH.getCode(), city).get("code").toString() : divisionMap.get("code").toString();
        supervisorCode.append(division).append(equipCategory).append("-");
        //获取行政区划区县、市是否存在历史监管码
        CategoryOtherInfo supervisor = categoryOtherInfoMapper.selectSupervisorCode(supervisorCode.toString());
        //生成对应监管码
        if (!ObjectUtils.isEmpty(supervisor) && supervisor.getSupervisoryCode() != null) {
            //获取补零位长度
            String supervisoryCode = supervisor.getSupervisoryCode().substring(6);
            long num = Long.valueOf(supervisoryCode) + 1;
            int numLength = String.valueOf(num).length();
            int a = 7 - numLength;
            StringBuilder zero = new StringBuilder();
            for (int i = 0; i < a; i++) {
                zero.append(EquipmentCategoryEnum.BLW.getCode());
            }
            zero.append(num);
            supervisorCode.append(zero);
        } else {
            supervisorCode.append(EquipmentCategoryEnum.JGM.getCode());
        }
        return supervisorCode.toString();
    }

    /**
     * 生成96333电梯识别码
     *
     * @param prefix   电梯码前缀
     * @return 96333电梯识别码
     */
    public String createElevatorCode(String prefix) {
        StringBuilder elevatorCode = new StringBuilder();
        //生成生成96333电梯码前缀
        elevatorCode.append(prefix);
        String initCode = elevatorCode + EquipmentCategoryEnum.getValue.get(elevatorCode.toString());
        CategoryOtherInfo initSupervisoryCode = categoryOtherInfoMapper.queryInitCode(initCode); // 查询是否已经生成过初始值
        if (ValidationUtil.isEmpty(initSupervisoryCode)) {
            elevatorCode.append(EquipmentCategoryEnum.getValue.get(prefix));
        } else {
            //获取行政区划区县、市是否存在历史96333电梯码
            CategoryOtherInfo elevatorOtherInfo = categoryOtherInfoMapper.selectElevatorCode(elevatorCode.toString(), null);
            if (!ObjectUtils.isEmpty(elevatorOtherInfo) && elevatorOtherInfo.getCode() != null) {
                //获取补零位长度
                String elevatorCode1 = elevatorOtherInfo.getCode().substring(2);
                long num = Long.parseLong(elevatorCode1) + 1;
                int numLength = String.valueOf(num).length();
                int a = 5 - numLength;
                StringBuilder zero = new StringBuilder();
                for (int i = 0; i < a; i++) {
                    zero.append(EquipmentCategoryEnum.BLW.getCode());
                }
                zero.append(num);
                elevatorCode.append(zero);
            }
        }
        return elevatorCode.toString();
    }


    /**
     * 获取当前登录人单位类型
     *
     * @return
     */

    public List<JSONObject> getCompanyType() {


        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        List<CompanyModel> companys = reginParams.getUserModel().getCompanys();

        List<JSONObject> objectList = new ArrayList<>();
        for (CompanyModel company : companys) {
            JSONObject object = new JSONObject();
            object.put("level", company.getLevel());
            object.put("orgCode", company.getOrgCode());
            object.put("companyCode", company.getCompanyCode());
            objectList.add(object);
        }
        return objectList;
    }


    @Override
    public Map<String, Map<String, Object>> getFormRecordById(Map<String, Object> map) {
        ResponseModel<Map<String, Map<String, Object>>> responseModel = idxFeignService.getFormRecordById(map);
        Map<String, Map<String, Object>> result = responseModel.getResult();
        if (!ObjectUtils.isEmpty(map.get(COPY_KEY))) {
            result.get(SUPERVISION_FROM_ID).remove("CLAIM_STATUS");
            result.get(SUPERVISION_FROM_ID).remove("CODE96333");
            result.get(SUPERVISION_FROM_ID).remove("SUPERVISORY_CODE");
        }
        return result;
    }

    /**
     * 分页查询数据
     */
    public Page<Map<String, Object>> getPage(Map<String, Object> map) {
        String tableName = map.get(TABLENAME).toString();
        Object sort = map.get("sort");
        Integer number = ValidationUtil.isEmpty(map.get("number")) ? 0 : Integer.valueOf(map.get("number").toString());
        Integer size = ValidationUtil.isEmpty(map.get("size")) ? 0 : Integer.valueOf(map.get("size").toString());

        Page<Map<String, Object>> page = new Page<>(number, size);
        Assert.hasText(tableName, "表名不能为空");
        String selectSql = "SELECT * FROM  " + tableName;
        String countSql = " SELECT COUNT(*) count FROM  " + tableName;

        StringJoiner andJoiner = new StringJoiner(" AND ");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!(entry.getKey().equals("tableName") || entry.getKey().equals("number") || entry.getKey().equals("size") || entry.getKey().equals("sort")) && !ValidationUtil.isEmpty(entry.getValue())) {
                if (!ValidationUtil.isEmpty(entry.getValue()) && entry.getValue().toString().contains("[") && entry.getValue().toString().contains("]")) {
                    String jsonValue = entry.getValue().toString().replace("[", "[\"").replace("]", "\"]").replaceAll(" ", "").replaceAll(",", "\",\"");
                    StringJoiner orJoiner = new StringJoiner(" or ");
                    // 兼容数据库存储String和list格式
                    JSON.parseArray(jsonValue).stream().forEach(x -> {
                        orJoiner.add(entry.getKey() + " like '%" + x + "%'");
                    });
                    andJoiner.add("(" + orJoiner + ")");
                } else {
                    andJoiner.add(entry.getKey() + " like '%" + entry.getValue().toString() + "%'");
                }
            }
        }

        if (!ValidationUtil.isEmpty(andJoiner.toString())) {
            selectSql = selectSql + " WHERE " + andJoiner;
            countSql = countSql + " WHERE " + andJoiner;
        }
        if (!ValidationUtil.isEmpty(sort)) {
            String[] split = sort.toString().split(",");
            selectSql = selectSql + " ORDER BY " + split[0] + (split[1].equals("descend") ? " DESC " : " ASC ");
        }
        int begin = (number - 1) * size;
        if (size > 0) {
            selectSql += " LIMIT " + begin + "," + size;
        }
        Long count = bizJdbcTemplate.queryForObject(countSql, Long.class);
        String finalSelectSql = selectSql;
        System.out.println("列表查询sql为--------->>>>>>>>" + finalSelectSql);
        List<Map<String, Object>> mapList = bizJdbcTemplate.queryForList(finalSelectSql);
        page.setTotal(count);
        page.setRecords(mapList);
        return page;
    }

    /**
     * levlel=company,是企业,如果不是都是监管单位,
     * * 在接口中查询当前登录人所属单位是监管单位还是企业。
     * * 如果为监管单位添加监管机构查询参数（ORG_BRANCH_CODE）；
     * * 如果为企业添加使用单位查询参数(USE_UNIT_CREDIT_CODE)
     */
    private static final String LEVEL = "company";
    private static final String EQUSTATE = "EQU_STATE";
    private static final String USEPLACE = "USE_PLACE";

    public Page<Map<String, Object>> getTable(Map<String, Object> map) {

        if (!ValidationUtil.isEmpty(map.get(EQUSTATE))) {
            map.put(EQUSTATE, EquimentEnum.getCode.get(map.get(EQUSTATE).toString()).toString());
        }
        ResponseModel<Page<Map<String, Object>>> model = new ResponseModel<>();
        List<JSONObject> objectList = getCompanyType();
        List<Map<String, Object>> res = new ArrayList<>();
        if (!ObjectUtils.isEmpty(map.get(USEPLACE))) {
            String uesPlace = map.get(USEPLACE).toString();
            String address = uesPlace.substring(1, uesPlace.length() - 1);
            address = address.replace(", ", "/");
            map.put(USEPLACE, address);
        }
        Long total = 0L;
        for (JSONObject object : objectList) {
            String level = object.getString("level");
            String code = object.getString("orgCode");
            String companyCode = object.getString("companyCode");
            if (!ValidationUtil.isEmpty(level)) {
                Page<Map<String, Object>> m = new Page<>();
                if (LEVEL.equals(level)) {
                    //企业
                    map.put("USE_UNIT_CREDIT_CODE", companyCode);
                    m = this.getPage(map);
                    map.remove("USE_UNIT_CREDIT_CODE");
                } else {
                    //监管单位
                    map.put("ORG_BRANCH_CODE", code);
                    m = this.getPage(map);
                    map.remove("ORG_BRANCH_CODE");
                }
                total += m.getTotal();
                if (!ValidationUtil.isEmpty(m) && !ValidationUtil.isEmpty(m.getRecords())) {
                    res.addAll(m.getRecords());
                }
            }
        }

        Page<Map<String, Object>> objectPage = new Page<>();
        objectPage.setRecords(res);
        objectPage.setTotal(total);
        objectPage.setSize(Long.valueOf(map.get("size").toString()));
        objectPage.setCurrent(Long.valueOf(map.get("number").toString()));
        model.setResult(objectPage);
        //设备状态码对应枚举值
        List<Map<String, Object>> records = model.getResult().getRecords();
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> record : records) {
            if (!ValidationUtil.isEmpty(record.get(EQUSTATE))) {
                Integer integer = Integer.valueOf(record.get(EQUSTATE).toString());
                String status = EquimentEnum.getName.get(integer);
                record.put(EQUSTATE, status);
            }
            result.add(record);
        }
        Page<Map<String, Object>> mapPage = model.getResult().setRecords(result);
        return mapPage;
    }


    public List<Map<String, Object>> scalp(Map<String, Object> map) {
        List<Map<String, Object>> list = new ArrayList<>();
        if (!ValidationUtil.isEmpty(map.get("orgBranchName"))) {
            list = equipmentCategoryMapper.getSrcee(map.get(TABLENAME).toString(),
                    map.get("orgBranchName").toString(), null, null, null, null);
        }
        if (!ValidationUtil.isEmpty(map.get("equList"))) {
            list = equipmentCategoryMapper.getSrcee(map.get(TABLENAME).toString(),
                    null, map.get("equList").toString(), null, null, null);
        }
        if (!ValidationUtil.isEmpty(map.get("equCategory"))) {
            list = equipmentCategoryMapper.getSrcee(map.get(TABLENAME).toString(),
                    null, null, map.get("equCategory").toString(), null, null);
        }
        if (!ValidationUtil.isEmpty(map.get("usePlace"))) {
            list = equipmentCategoryMapper.getSrcee(map.get(TABLENAME).toString(),
                    null, null, null, map.get("usePlace").toString(), null);
        }
        if (!ValidationUtil.isEmpty(map.get("equState"))) {
            list = equipmentCategoryMapper.getSrcee(map.get(TABLENAME).toString(),
                    null, null, null, null, map.get("equState").toString());
        }
        return list;
    }

    public List<EquipExportVo> getEquipExportData(EquipExportDto dto){
        ArrayList<EquipExportVo> list = new ArrayList<>();
        List<JSONObject> objectList = getCompanyType();
        if (!ValidationUtil.isEmpty(dto.getEQU_STATE())) {
            dto.setEQU_STATE(EquimentEnum.getCode.get(dto.getEQU_STATE()).toString());
        }
        for (JSONObject object : objectList) {
            String level = object.getString("level");
            String orgCode = object.getString("orgCode");
            String companyCode = object.getString("companyCode");
            if (!ValidationUtil.isEmpty(level)) {
                if (LEVEL.equals(level)) {
                    //企业
                    dto.setUSE_UNIT_CREDIT_CODE(companyCode);
                } else {
                    //监管单位
                    dto.setORG_BRANCH_CODE(orgCode);
                }
                List<EquipExportVo> equipExportData = equipmentCategoryMapper.getEquipExportData(dto);
                if (!ObjectUtils.isEmpty(equipExportData) ) {
                    list.addAll(equipExportData);
                }
            }
        }
        return list;
    }


    public List<EquipExportVo> exportImageZip(EquipExportDto dto, Long pageNum, Long size) {
        ArrayList<EquipExportVo> list = new ArrayList<>();
        List<JSONObject> objectList = getCompanyType();
        if (!ValidationUtil.isEmpty(dto.getEQU_STATE())) {
            dto.setEQU_STATE(EquimentEnum.getCode.get(dto.getEQU_STATE()).toString());
        }
        for (JSONObject object : objectList) {
            String level = object.getString("level");
            String orgCode = object.getString("orgCode");
            String companyCode = object.getString("companyCode");
            if (!ValidationUtil.isEmpty(level)) {
                Page<EquipExportVo> equipExportVoPage = new Page<>(pageNum, size);
                if (LEVEL.equals(level)) {
                    //企业
                    dto.setUSE_UNIT_CREDIT_CODE(companyCode);
                } else {
                    //监管单位
                    dto.setORG_BRANCH_CODE(orgCode);
                }
                Page<EquipExportVo> equipExportData = equipmentCategoryMapper.exportImageZip(equipExportVoPage, dto);
                if (!ObjectUtils.isEmpty(equipExportData) && !ObjectUtils.isEmpty(equipExportData.getRecords())) {
                    list.addAll(equipExportData.getRecords());
                }
            }
        }
        return list;
    }

    /**
     * 设备字典,通过设备父类code,获得子类
     */
    public List<EquipmentCategory> getChildren(String code) {
        LambdaQueryWrapper<EquipmentCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentCategory::getCode, code);
        EquipmentCategory equipmentCategory = baseMapper.selectOne(wrapper);
        LambdaQueryWrapper<EquipmentCategory> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(EquipmentCategory::getParentId, equipmentCategory.getId());
        List<EquipmentCategory> equipmentCategories = baseMapper.selectList(wrapper2);
        return equipmentCategories;
    }


    @Override
    public void checkEsData(String id) {
        Map<String, Object> map = categoryOtherInfoMapper.selectDataById(id);
        UseInfo useInfo = new UseInfo();
        useInfo.setIsNotEs(1);
        useInfoMapper.update(useInfo, new QueryWrapper<UseInfo>().eq("RECORD", id));
        ESEquipmentCategoryDto dto = JSON.parseObject(toJSONString(map), ESEquipmentCategoryDto.class);
        Optional<ESEquipmentCategoryDto> data = esEquipmentCategory.findById(id);
        if (!ObjectUtils.isEmpty(data)) {
            esEquipmentCategory.deleteById(id);
        }
        if (!ObjectUtils.isEmpty(dto)) {
            dto.setREC_DATE(System.currentTimeMillis());
            esEquipmentCategory.save(dto);
        }
    }



    @Override
    @Async
    public void createEquipmentCategoryData() {
        if(log.isInfoEnabled()){
            log.info("初始化一码通总览数据开始");
        }
        equipmentCategoryDataService.remove(new QueryWrapper<>());
        getCategoryData(null,null);
    }

    private List<EquipmentCategoryData> getCategoryData(List<String> unitCodes,List<String> orgBranchCodes) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<EquipmentCategoryData> list = new ArrayList<>();
        // 查询所有单位
        List<Map<String, Object>> allUnitList = equipmentCategoryMapper.getAllUnit(unitCodes,orgBranchCodes);
        // 统计查询不同单位、不同装备定义、不同状态下的设备数量
        List<UseUnitCreditCodeCategoryDto> equipCountList = equipmentCategoryMapper.useUnitCreditCodeCategoryCount();
        // 查询8大类设备定义
        List<EquipmentCategory> equipmentCategories = getEquipmentCategories();
        // 组织EquipmentCategoryData表数据
        for (Map<String, Object> map : allUnitList) {
            EquipmentCategoryData equipmentCategoryData = new EquipmentCategoryData();
            if(ObjectUtils.isEmpty(map.get("supervise_org_code")) || ObjectUtils.isEmpty(map.get(USE_CODE))){
                continue;
            }
            equipmentCategoryData.setOrgBranchCode(map.get("supervise_org_code").toString());
            equipmentCategoryData.setUnitCode(map.get(USE_CODE).toString());
            // 指定单位的设备统计信息
            List<UseUnitCreditCodeCategoryDto> unitEquipCountList = equipCountList.stream().filter(r->map.get(USE_CODE).toString().equals(r.getUseUnitCreditCode())).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(unitEquipCountList)) {
                unitEquipCountList = unitEquipCountList.stream().filter(r -> map.get(ORG_BRANCH_CODE).toString().equals(r.getOrgBranchCode())).collect(Collectors.toList());
                for (EquipmentCategory category : equipmentCategories) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("waitClaim", unitEquipCountList.stream().filter(r -> r.getEquList().equals(category.getCode()) && EquipmentCategoryEnum.DRL.getName().equals(r.getClaimStatus())).collect(Collectors.summarizingLong(UseUnitCreditCodeCategoryDto::getTotal)).getSum());
                    data.put("alreadyClaim", unitEquipCountList.stream().filter(r -> r.getEquList().equals(category.getCode()) && EquipmentCategoryEnum.YRL.getName().equals(r.getClaimStatus())).collect(Collectors.summarizingLong(UseUnitCreditCodeCategoryDto::getTotal)).getSum());
                    data.put("refuseClaim", unitEquipCountList.stream().filter(r -> r.getEquList().equals(category.getCode()) && EquipmentCategoryEnum.YJL.getName().equals(r.getClaimStatus())).collect(Collectors.summarizingLong(UseUnitCreditCodeCategoryDto::getTotal)).getSum());
                    this.set8CategoryCountData(equipmentCategoryData, category, data);
                }
                equipmentCategoryData.setRecDate(new Date());
                list.add(equipmentCategoryData);
            }
        }
        if(!ObjectUtils.isEmpty(unitCodes)){
            equipmentCategoryDataMapper.delete(new QueryWrapper<EquipmentCategoryData>().in("unit_code",unitCodes));
        }
        equipmentCategoryDataService.saveOrUpdateBatch(list);
        stopWatch.stop();
        if(log.isInfoEnabled()){
            log.info("总览数据刷新结束，耗时：{} 秒",stopWatch.getTotalTimeSeconds());
        }
        return list;
    }

    private void set8CategoryCountData(EquipmentCategoryData equipmentCategoryData, EquipmentCategory category, Map<String, Object> data) {
        switch (category.getCode()) {
            case "1000":
                equipmentCategoryData.setBoiler(toJSONString(data));
                break;
            case "2000":
                equipmentCategoryData.setVessel(toJSONString(data));
                break;
            case "3000":
                equipmentCategoryData.setElevator(toJSONString(data));
                break;
            case "4000":
                equipmentCategoryData.setLifting(toJSONString(data));
                break;
            case "5000":
                equipmentCategoryData.setVehicle(toJSONString(data));
                break;
            case "6000":
                equipmentCategoryData.setRides(toJSONString(data));
                break;
            case "8000":
                equipmentCategoryData.setPipeline(toJSONString(data));
                break;
            case "9000":
                equipmentCategoryData.setRopeway(toJSONString(data));
                break;
            default:
                log.error("不支持的分类：{}", toJSONString(category));
                break;
        }
    }

    private List<EquipmentCategory> getEquipmentCategories() {
        LambdaQueryWrapper<EquipmentCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.likeLeft(EquipmentCategory::getCode,"000");
        lambdaQueryWrapper.ne(EquipmentCategory::getCode,"7000");
        lambdaQueryWrapper.ne(EquipmentCategory::getCode,"F000");
        return equipmentCategoryMapper.selectList(lambdaQueryWrapper);
    }


    private List<EquipmentCategoryData> updateEquipmentCategoryData(String unitCode,String orgBranchCode) {
        List<String> unitCodeList = new ArrayList<>();
        unitCodeList.add(unitCode);
        List<String> orgBranchCodeList = new ArrayList<>();
        orgBranchCodeList.add(orgBranchCode);
        List<EquipmentCategoryData> equipmentCategoryData = getCategoryData(unitCodeList,null);
        return equipmentCategoryData;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> deleteBatch(Map<String, Object> map) {
        Object recordList = map.get("recordList");
        List<String> records = new ArrayList<>();
        List<ESEquipmentCategoryDto> list = new ArrayList<>();

        if(recordList.toString().contains("[")){
            for (String record : (List<String>) recordList) {
                records.add(record);
                ESEquipmentCategoryDto esEquipmentCategoryDto = new ESEquipmentCategoryDto();
                esEquipmentCategoryDto.setSEQUENCE_NBR(record);
                list.add(esEquipmentCategoryDto);
            }
        } else {
            records.add(recordList.toString());
            ESEquipmentCategoryDto esEquipmentCategoryDto = new ESEquipmentCategoryDto();
            esEquipmentCategoryDto.setSEQUENCE_NBR(recordList.toString());
            list.add(esEquipmentCategoryDto);
        }
        //删除监管码表数据
        List<String> superviseCodeList = superviseInfoMapper.selectSuperviseCodeList(records);
        List<Map<String, Object>> unitCodeAndOrgBranchCodeList = superviseInfoMapper.selectUnitCodeList(records);
        List<String> unitCodeList = new ArrayList<>();
        List<String> orgBranchCodeList = new ArrayList<>();
        for (Map<String, Object> objectMap : unitCodeAndOrgBranchCodeList) {
            unitCodeList.add(String.valueOf(objectMap.get("unitCode")));
            orgBranchCodeList.add(String.valueOf(objectMap.get("orgBranchCode")));
        }

        if(!ObjectUtils.isEmpty(superviseCodeList)){
            supervisoryCodeInfoMapper.updateStatus(superviseCodeList);
        }

        //删除涉及的19张表的数据
        superviseInfoMapper.deleteDataAll(records);
        // 根据统一信用代码更新总览表
        if(!ObjectUtils.isEmpty(unitCodeList)){
            getCategoryData(unitCodeList,orgBranchCodeList);
        }
        //删除es中的数据
        esEquipmentCategory.deleteAll(list);
        return records;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseModel submit(Map<String, Object> map) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        SupervisoryCodeInfo supervisoryCodeInfo = new SupervisoryCodeInfo();
        ResponseModel responseModel = new ResponseModel();
        LinkedHashMap useInfoFrom = (LinkedHashMap) map.get(USE_INFO_FROM_ID);
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        useInfoFrom.put("REC_DATE", dateFormat.format(calendar.getTime()));
        String unitCode = String.valueOf(useInfoFrom.get("USE_UNIT_CREDIT_CODE"));
        LinkedHashMap supervisionMap = (LinkedHashMap) map.get(SUPERVISION_FROM_ID);
        String orgBranchCode = String.valueOf(supervisionMap.get("ORG_BRANCH_CODE"));
        try {
            LinkedHashMap superviseMap = (LinkedHashMap) map.get("data");
            String claimStatus = String.valueOf(superviseMap.get("claimStatus"));
            String code96333 = String.valueOf(superviseMap.get("code96333"));
            String operateType = String.valueOf(superviseMap.get("operateType"));
            //生成码
            Map<String, String> codeMap;
            if (EquipmentCategoryEnum.YRL.getName().equals(claimStatus)) {
                log.info("准备生成监管码或96333电梯识别码");
                String city = String.valueOf(superviseMap.get("city"));
                String county = String.valueOf(superviseMap.get("county"));
                String equCategory = String.valueOf(superviseMap.get("equCategory"));
                String supervisionCode = String.valueOf(superviseMap.get("supervisionCode"));
                EquipmentCategoryServiceImpl categoryService = (EquipmentCategoryServiceImpl) AopContext.currentProxy();
//                EquipmentCategoryServiceImpl categoryService = SpringUtils.getBean(EquipmentCategoryServiceImpl.class);
                //生成码
                codeMap = categoryService.creatCode(city, county, equCategory, code96333, supervisionCode);
                log.info("已生成对应监管码或96333电梯识别码");
                //删除map中的冗余数据，添加对应监管码和96333码调用idx多表单页提交接口吧保存数据
                map.remove("data");
                supervisionMap.put("CODE96333", codeMap.get("code96333"));
                supervisionMap.put("SUPERVISORY_CODE", codeMap.get("superviseCode"));
                map.put(SUPERVISION_FROM_ID, supervisionMap);
                //根据操作状态判断是调用新增还是修改接口
                responseModel = "save".equals(operateType) ? idxFeignService.batchSubmit(null, null, null, null, map) :
                        idxFeignService.batchUpdate(null, null, map);
                if (!ObjectUtils.isEmpty(responseModel) && "200".equals(String.valueOf(responseModel.getStatus()))) {
                    supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.YSY.getCode());
                } else {
                    supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.BF.getCode());
                }
            } else if (EquipmentCategoryEnum.DRL.getName().equals(claimStatus)) {
                map.remove("data");
                supervisionMap.put("CODE96333", "null".equals(code96333) ? null : code96333);
                map.put(SUPERVISION_FROM_ID, supervisionMap);
                //根据操作状态判断是调用新增还是修改接口
                responseModel = "save".equals(operateType) ? idxFeignService.batchSubmit(null, null, null, null, map) :
                        idxFeignService.batchUpdate(null, null, map);
            } else {
                map.remove("data");
                responseModel = idxFeignService.batchUpdate(null, null, map);
            }
            stopWatch.stop();
            if(log.isInfoEnabled()){
                log.info("通用提交耗时：{} 秒",stopWatch.getTotalTimeSeconds());
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            supervisoryCodeInfo.setStatus(EquipmentCategoryEnum.BF.getCode());
            ResponseModel<Object> response = new ResponseModel<>();
            response.setDevMessage(e.getMessage());
            response.setResult(null);
            response.setMessage("操作失败，请检查数据输入后重新提交");
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            return response;
        } finally {
            log.info("已生成对应监管码" + supervisionMap.get("SUPERVISORY_CODE"));
            log.info("已生成对应96333电梯识别码" + supervisionMap.get("CODE96333"));
            updateEquipmentCategoryData(unitCode,orgBranchCode);
            supervisoryCodeInfoMapper.update(supervisoryCodeInfo,new QueryWrapper<SupervisoryCodeInfo>().eq("supervisory_code",supervisionMap.get("SUPERVISORY_CODE")));
        }
        return responseModel;
    }


    //分页查询所有数据
    public Page<Map<String, Object>> getAll(Map<String, Object> map) {
        String tableName = map.get(TABLENAME).toString();
        Assert.hasText(tableName, "表名不能为空");
        String selectSql = " SELECT * FROM  " + tableName + " WHERE IS_NOT_ES <> 1 or IS_NOT_ES IS NULL ";
        Integer number = ValidationUtil.isEmpty(map.get("number")) ? 0 : Integer.valueOf(map.get("number").toString());
        Integer size = ValidationUtil.isEmpty(map.get("size")) ? 0 : Integer.valueOf(map.get("size").toString());
        Page<Map<String, Object>> page = new Page<>(number, size);
        int begin = (number - 1) * size;
        if (size > 0) {
            selectSql = selectSql + " LIMIT " + begin + "," + size;
        }
        List<Map<String, Object>> mapList = bizJdbcTemplate.queryForList(selectSql);
        page.setRecords(mapList);
        page.setTotal(mapList.size());
        return page;
    }

    //查询总条数
    public Long counts(Map<String, Object> map) {
        String tableName = map.get(TABLENAME).toString();
        Assert.hasText(tableName, "表名不能为空");
        String countSql = " SELECT COUNT(SEQUENCE_NBR) count FROM  " + tableName + " WHERE IS_NOT_ES <> 1 or IS_NOT_ES IS NULL";
        Long count = bizJdbcTemplate.queryForObject(countSql, Long.class);
        return count;
    }
    /**
     * es数据同步
     *
     * @return
     */

    public void saveEs() {
        long start = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<>();
        map.put(TABLENAME, "idx_biz_view_jg_all");
        Long counts = counts(map);
        Long times = counts / 1000;
        Long yushu = counts % 1000;
        if (yushu > 0) {
            times++;
        }
        long total = 0;
        for (int i = 1; i <= times; i++) {
            map.put("number", 1);
            map.put("size", 1000);
            Page<Map<String, Object>> page = getAll(map);
            total = total + page.getTotal();
            saveBatchEquipment2Es(page.getRecords());
//            for (Map<String, Object> record : page.getRecords()) {
//                if (ValidationUtil.isEmpty(record.get("IS_NOT_ES"))) {
//                    saveESEquipmentCategory(record);
//                }
//            }
        }
        long end = System.currentTimeMillis();
        log.info("本次一码通同步设备数据：【" + total + "】条，耗时：" + (end - start) + " 毫秒");
    }

    public void saveBatchEquipment2Es(List<Map<String, Object>> equipList) {
        List<ESEquipmentCategoryDto> esEquipDtoList = Lists.newArrayList();
        List<String> recordList = Lists.newArrayList();
        if (ValidationUtil.isEmpty(equipList)) {
            return;
        }
        for (Map<String, Object> e : equipList) {
            String recDate1 = "";
            if (ValidationUtil.isEmpty(e.get("REC_DATE"))) {
                try {
                    recDate1 = DateUtil.formatDate(new Date(), "yyyy-MM-dd hh:mm:ss");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            } else {
                recDate1 = e.get("REC_DATE").toString().substring(0, 19);
            }
            long time = Timestamp.valueOf(recDate1).getTime();
            e.put("REC_DATE", time);
            ESEquipmentCategoryDto esEquipDto = JSONObject.parseObject(toJSONString(e),
                    ESEquipmentCategoryDto.class);
            esEquipDtoList.add(esEquipDto);

            recordList.add((String) e.get("SEQUENCE_NBR"));
        }
        long start = System.currentTimeMillis();
        esEquipmentCategory.saveAll(esEquipDtoList);
        long end = System.currentTimeMillis();
        long cost = end - start;
        System.out.println("批量存入es1000条数据耗时：" + cost);

        long start1 = System.currentTimeMillis();
        superviseInfoMapper.updateRecordBatch(recordList);
        long end1 = System.currentTimeMillis();
        long cost1 = end1 - start1;
        System.out.println("批量更新1000条业务数据耗时：" + cost1);
    }

    /**
     * es保存设备数据
     */
    public ESEquipmentCategoryDto saveESEquipmentCategory(Map<String, Object> map) {
        //处理时间问题
        String recDate1 = map.get("REC_DATE").toString().substring(0,19);
        long time = Timestamp.valueOf(recDate1).getTime();

        map.put("REC_DATE",time);
        ESEquipmentCategoryDto dto = JSONObject.parseObject(toJSONString(map), ESEquipmentCategoryDto.class);
        ESEquipmentCategoryDto save = esEquipmentCategory.save(dto);
        if (!ObjectUtils.isEmpty(save)) {
            //同步到es后修改
            UseInfo useInfo = new UseInfo();
            useInfo.setIsNotEs(1);
            useInfoMapper.update(useInfo, new QueryWrapper<UseInfo>().eq("RECORD",
                    map.get("SEQUENCE_NBR").toString()));
        }
        return save;
    }
    public Page<JSONObject> queryByKeys(JSONObject map) {
        //根据当前登录人查询
        if (!ValidationUtil.isEmpty(map.get(EQUSTATE))) {
            map.put(EQUSTATE, EquimentEnum.getCode.get(map.get(EQUSTATE).toString()).toString());
        }
        ResponseModel<Page<Map<String, Object>>> model = new ResponseModel<>();
        JSONObject object = getCompanyType().get(0);
        String level = object.getString("level");
        String code = object.getString("orgCode");
        String companyCode = object.getString("companyCode");
        if (!ValidationUtil.isEmpty(level)) {
            if (LEVEL.equals(level)) {
                //企业
                map.put("USE_UNIT_CREDIT_CODE", companyCode);
            } else {
                //监管单位
                map.put("ORG_BRANCH_CODE", code);
            }
        }
        Page<JSONObject> result = new Page<>(map.getInteger("number"), map.getInteger("size"));
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(esUserName, esPwd));  //es账号密码
        RestHighLevelClient esClient = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost(esAddress, esPort)
                ).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        httpClientBuilder.disableAuthCaching();
                        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                })
        );
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        //通用匹配规则，条件构建
        //SEQUENCE_NBR
        if (!ObjectUtils.isEmpty(map.getString("SEQUENCE_NBR"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchPhraseQuery("SEQUENCE_NBR", "*"+map.getString("SEQUENCE_NBR")+"*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("ORG_BRANCH_NAME"))) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchPhraseQuery("ORG_BRANCH_NAME", "*"+map.getString("ORG_BRANCH_NAME")+"*" ));
            boolMust.must(query);
        }
        if (!ObjectUtils.isEmpty(map.getString("ORG_BRANCH_CODE"))) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchPhraseQuery("ORG_BRANCH_CODE", "*" + map.getString("ORG_BRANCH_CODE") + "*"));
            boolMust.must(query);
        }
        if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_NAME"))) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchPhraseQuery("USE_UNIT_NAME",  "*"+map.getString("USE_UNIT_NAME")+"*"));
            boolMust.must(query);
        }
        if (!ObjectUtils.isEmpty(map.getString("USE_UNIT_CREDIT_CODE"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchPhraseQuery("USE_UNIT_CREDIT_CODE", "*"+map.getString("USE_UNIT_CREDIT_CODE")+"*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("EQU_LIST_CODE"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchPhraseQuery("EQU_LIST_CODE", "*" + map.getString("EQU_LIST_CODE") + "*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("EQU_LIST"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchPhraseQuery("EQU_LIST", "*"+map.getString("EQU_LIST")+"*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("EQU_CATEGORY"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchPhraseQuery("EQU_CATEGORY", "*"+map.getString("EQU_CATEGORY")+"*"));
            boolMust.must(meBuilder);

        }
        if (!ObjectUtils.isEmpty(map.getString("USE_ORG_CODE"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"+map.getString("USE_ORG_CODE").toLowerCase()+"*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("CODE96333"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.wildcardQuery("CODE96333", "*"+map.getString("CODE96333").toLowerCase()+"*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("EQU_CODE"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.wildcardQuery("EQU_CODE", "*" + map.getString("EQU_CODE") + "*"));
            boolMust.must(meBuilder);
        }

        if (!ObjectUtils.isEmpty(map.getString("SUPERVISORY_CODE"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.wildcardQuery("SUPERVISORY_CODE", "*"+map.getString("SUPERVISORY_CODE").toLowerCase()+"*"));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("USE_PLACE"))) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchPhraseQuery("USE_PLACE", "*" + map.getString("USE_PLACE") + "*"));
            boolMust.must(query);
        }
        if (!ObjectUtils.isEmpty(map.getString("ADDRESS"))) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchPhraseQuery("ADDRESS", "*" + map.getString("ADDRESS") + "*"));
            boolMust.must(query);
        }
        if (!ObjectUtils.isEmpty(map.getString("EQU_STATE"))  ) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchQuery("EQU_STATE", map.getLong("EQU_STATE")));
            boolMust.must(meBuilder);
        }
        if (!ObjectUtils.isEmpty(map.getString("STATUS"))) {
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.matchPhraseQuery("STATUS", "*"+map.getString("STATUS")+"*"));
            boolMust.must(meBuilder);
        }
        builder.query(boolMust);
        builder.sort("REC_DATE", SortOrder.DESC);
        builder.from((map.getInteger("number") - 1) * map.getInteger("size"));
        builder.size(map.getInteger("size"));
        request.source(builder);
        List<JSONObject> list = new LinkedList<>();
        long totle = 0;
        try {
            SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
            for (org.elasticsearch.search.SearchHit hit : response.getHits().getHits()) {
                System.out.println(hit);
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(hit);
                JSONObject dto2 = jsonObject.getJSONObject("sourceAsMap");
                if (!ValidationUtil.isEmpty(dto2.get(EQUSTATE))) {
                    Integer integer = Integer.valueOf(dto2.get(EQUSTATE).toString());
                    String status = EquimentEnum.getName.get(integer);
                    dto2.put(EQUSTATE, status);
                }
                list.add(dto2);
            }
            totle = response.getInternalResponse().hits().getTotalHits().value;
            result.setRecords(list);
            result.setTotal(totle);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                esClient.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return result;
    }

    //es统计总记录数
    public Long getCount(String indexs, RestHighLevelClient esClient) {
        Long totle = 0L;
        SearchRequest searchRequest = new SearchRequest(indexs);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchSourceBuilder.trackTotalHits(true);
        searchRequest.source(searchSourceBuilder);
        try {
            SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
            totle = searchResponse.getInternalResponse().hits().getTotalHits().value;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return totle;
    }
}