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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.dao.mapper.DataDictionaryMapper;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.utils.QRCodeUtil;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.app.api.common.MobileLoginParam;
import com.yeejoin.amos.boot.module.app.api.dto.*;
import com.yeejoin.amos.boot.module.app.api.entity.*;
import com.yeejoin.amos.boot.module.app.api.enums.EquipmentCategoryEnum;
import com.yeejoin.amos.boot.module.app.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.app.api.mapper.CategoryOtherInfoMapper;
import com.yeejoin.amos.boot.module.app.api.mapper.EquipmentCategoryMapper;
import com.yeejoin.amos.boot.module.app.biz.utils.HttpUtils;
import com.yeejoin.amos.boot.module.app.biz.utils.JsonUtils;
import com.yeejoin.amos.boot.module.app.biz.utils.RedisUtil;
import com.yeejoin.amos.boot.module.app.flc.api.feign.IdxFeignService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.IdPasswordAuthModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TzsAppService {
    /**
     * 产品appkey
     */
    @Value("${amos.biz.appCode:AMOS_STUDIO}")
    private String appKey;
    /**
     * 产品product
     */
    private static final String product = "AMOS_STUDIO_WEB";
    private static final String regionRedis = "app_region_redis";
    private final int successsCode = 200;
    @Autowired
    DesignInfoService designInfoService;
    @Autowired
    DataDictionaryMapper dataDictionaryMapper;
    @Autowired
    IdxFeignService idxFeignService;
    @Autowired
    EquipmentCategoryMapper equipmentCategoryMapper;
    @Autowired
    EquipmentCategoryServiceImpl equipmentCategoryServiceImpl;
    @Autowired
    ProduceInfoService produceInfoService;
    @Autowired
    ConstructionInfoService constructionInfoService;
    @Autowired
    RegistrationInfoService registrationInfoService;
    @Autowired
    EquipTechParamBoilerService boilerService;
    @Autowired
    EquipTechParamElevatorService elevatorService;
    @Autowired
    EquipTechParamPipelineService pipelineService;
    @Autowired
    EquipTechParamRidesService ridesService;
    @Autowired
    EquipTechParamRopewayService ropewayService;
    @Autowired
    EquipTechParamVehicleService vehicleService;
    @Autowired
    EquipTechParamVesselService vesselService;
    @Autowired
    MainPartsServiceImpl mainPartsService;
    @Autowired
    ProtectionDevicesServiceImpl protectionDevicesService;
    @Autowired
    UseInfoService unseInfoService;
    @Autowired
    MaintenanceInfoService maintenanceInfoService;
    @Autowired
    InspectionDetectionInfoServiceImpl inspectionDetectionInfoService;
    @Autowired
    OtherInfoService otherInfoService;
    @Autowired
    CategoryOtherInfoMapper categoryOtherInfoMapper;
    @Autowired
    RedisUtils redisUtils;
    @Value("${tzs.WxApp.appId}")
    String WxAppAppId;
    @Value("${tzs.WxApp.secret}")
    String WxAppSecret;
    @Value("${tzs.WxApp.grant-type}")
    String WxAppGrantType;

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

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    private RedisUtil redisUtil;

    private static final String STREET = "STREET";


    public Map<String, Object> getEquipmentInfo(String record) {
        List<DataDictionary> dictionaryList = getDictionary();
        List<EquipmentCategory> equipmentCategories = equipmentCategoryMapper.selectList(null);
        Map<String, Object> map = new HashMap();
        map.put("SEQUENCE_NBR", record);
        map.put("tableName", "idx_biz_view_jg_claim");
        ResponseModel<Page<Map<String, Object>>> model = idxFeignService.getPage(map);
        List<Map<String, Object>> detailMapList = model.getResult().getRecords();
        if (!ValidationUtil.isEmpty(detailMapList)) {
            map = detailMapList.iterator().next();
        }
        map.putAll(getQRCode(record));

        JSONArray jsonArray = new JSONArray();
        // 出厂
        JSONObject exFactoryJsonObject = new JSONObject();
        List exFactoryList = new ArrayList();
        getGroupList(null, record, DesignInfo.class, DesignInfoModel.class, designInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
        getGroupList(null, record, ProduceInfo.class, ProduceInfoModel.class, produceInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
        exFactoryJsonObject.put("title", "出厂");
        exFactoryJsonObject.put("tabValue", exFactoryList);
        jsonArray.add(exFactoryJsonObject);

        // 施工
        JSONObject constructionJsonObject = new JSONObject();
        List constructionList = new ArrayList();
        getGroupList(null, record, ConstructionInfo.class, ConstructionInfoModel.class, constructionInfoService, constructionList, true, dictionaryList, equipmentCategories);
        constructionJsonObject.put("title", "施工");
        constructionJsonObject.put("tabValue", constructionList);
        jsonArray.add(constructionJsonObject);

        // 注册
        JSONObject registrationJsonObject = new JSONObject();
        String equipType = String.valueOf(map.get("EQU_LIST_CODE"));
        List registrationList = new ArrayList();
        switch (equipType) {
            case "4000":
                getGroupList(null, record, EquipTechParamLifting.class, EquipTechParamLiftingModel.class, elevatorService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "3000":
                getGroupList(null, record, EquipTechParamElevator.class, EquipTechParamElevatorModel.class, elevatorService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "5000":
                getGroupList(null, record, EquipTechParamVehicle.class, EquipTechParamVehicleModel.class, vehicleService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "1000":
                getGroupList(null, record, EquipTechParamBoiler.class, EquipTechParamBoilerModel.class, boilerService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "2000":
                getGroupList(null, record, EquipTechParamVessel.class, EquipTechParamVesselModel.class, vesselService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "8000":
                getGroupList(null, record, EquipTechParamPipeline.class, EquipTechParamPipelineModel.class, pipelineService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "6000":
                getGroupList(null, record, EquipTechParamRides.class, EquipTechParamRidesModel.class, ridesService, registrationList, false, dictionaryList, equipmentCategories);
                break;
            case "9000":
                getGroupList(null, record, EquipTechParamRopeway.class, EquipTechParamRopewayModel.class, ropewayService, registrationList, false, dictionaryList, equipmentCategories);
                break;
        }
        getGroupList(null, record, RegistrationInfo.class, RegistrationInfoModel.class, registrationInfoService, registrationList, false, dictionaryList, equipmentCategories);
        getGroupList(null, record, MainParts.class, MainPartsModel.class, mainPartsService, registrationList, false, dictionaryList, equipmentCategories);
        getGroupList(null, record, ProtectionDevices.class, ProtectionDevicesModel.class, protectionDevicesService, registrationList, false, dictionaryList, equipmentCategories);
        registrationJsonObject.put("title", "注册");
        registrationJsonObject.put("tabValue", registrationList);
        jsonArray.add(registrationJsonObject);

        // 使用
        JSONObject useJsonObject = new JSONObject();
        List useList = new ArrayList();
        getGroupList(null, record, UseInfo.class, UseInfoModel.class, unseInfoService, useList, false, dictionaryList, equipmentCategories);
        useJsonObject.put("title", "使用");
        useJsonObject.put("tabValue", useList);
        jsonArray.add(useJsonObject);

        // 维保
        JSONObject maintenanceJsonObject = new JSONObject();
        List maintenanceList = new ArrayList();
        getGroupList(null, record, MaintenanceInfo.class, MaintenanceInfoModel.class, maintenanceInfoService, maintenanceList, true, dictionaryList, equipmentCategories);
        maintenanceJsonObject.put("title", "维保");
        maintenanceJsonObject.put("tabValue", maintenanceList);
        jsonArray.add(maintenanceJsonObject);

        // 检验
        JSONObject inspectionJsonObject = new JSONObject();
        List inspectionList = new ArrayList();
        getGroupList(null, record, InspectionDetectionInfo.class, InspectionDetectionInfoModel.class, inspectionDetectionInfoService, inspectionList, true, dictionaryList, equipmentCategories);
        inspectionJsonObject.put("title", "检验");
        inspectionJsonObject.put("tabValue", inspectionList);
        jsonArray.add(inspectionJsonObject);

        // 其他
        JSONObject otherJsonObject = new JSONObject();
        List otherList = new ArrayList();
        getGroupList(null, record, OtherInfo.class, OtherInfoModel.class, otherInfoService, otherList, false, dictionaryList, equipmentCategories);
        otherJsonObject.put("title", "其他");
        otherJsonObject.put("tabValue", otherList);
        jsonArray.add(otherJsonObject);
        map.put("tab", jsonArray);
        map.put("color", this.getQrCodeColor(record));
        return map;
    }


    public Map<String, Object> getEquipmentInfoWX(String record) {
        List<DataDictionary> dictionaryList = getDictionary();
        List<EquipmentCategory> equipmentCategories = equipmentCategoryMapper.selectList(null);
        Map<String, Object> map = new HashMap();
        map.put("SEQUENCE_NBR", record);
        map.put("tableName", "idx_biz_view_jg_claim");
        ResponseModel<Page<Map<String, Object>>> model = idxFeignService.getPage(map);
        List<Map<String, Object>> detailMapList = model.getResult().getRecords();
        if (!ValidationUtil.isEmpty(detailMapList)) {
            map = detailMapList.iterator().next();
        }
        if (!ObjectUtils.isEmpty(model.getResult().getRecords().get(0).get("SUPERVISORY_CODE"))) {
            map.putAll(getQRCode(model.getResult().getRecords().get(0).get("SUPERVISORY_CODE").toString()));
        }

        JSONArray jsonArray = new JSONArray();
        JSONObject exFactoryJsonObject = new JSONObject();
        List exFactoryList = new ArrayList();
        HashMap putMap = new HashMap();
        Field[] fields = EquBaseInfoForWXModel.class.getDeclaredFields();
        for (Field f : fields) {
            putMap.put(f.getName(), "");
        }
        if (EquipmentClassifityEnum.DT.getCode().equals(map.get("EQU_LIST_CODE"))) {
            // 基本信息
            Field[] fields1 = ElevatorBaseInfoForWXModel.class.getDeclaredFields();
            for (Field f : fields1) {
                putMap.put(f.getName(), "");
            }

            getGroupList(putMap, record, RegistrationInfo.class, ElevatorBaseInfoForWXModel.class, registrationInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, DesignInfo.class, ElevatorBaseInfoForWXModel.class, designInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, OtherInfo.class, ElevatorBaseInfoForWXModel.class, otherInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, UseInfo.class, ElevatorBaseInfoForWXModel.class, unseInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, ProduceInfo.class, ElevatorBaseInfoForWXModel.class, produceInfoService, exFactoryList, false, dictionaryList, equipmentCategories);

            if (exFactoryList.size() > 0) {
                String area = map.get("USE_PLACE").toString();
                JSONObject jsonObject = (JSONObject) exFactoryList.get(0);
                List<HashMap<String, Object>> groupValue = (List<HashMap<String, Object>>) jsonObject.get("groupValue");
                groupValue.forEach(e -> {
                    e.put("fieldValue", putMap.get(e.get("fieldKey")));
                    if (e.get("fieldKey").equals("area")) {
                        e.put("fieldValue", area);
                    }
                });
                Object ob = exFactoryList.get(0);
                exFactoryList.clear();
                exFactoryList.add(ob);
            }

            exFactoryJsonObject.put("title", "基本信息");
            exFactoryJsonObject.put("tabValue", exFactoryList);
            jsonArray.add(exFactoryJsonObject);

            // 最近检验信息
            JSONObject constructionJsonObject = new JSONObject();
            List constructionList = new ArrayList();
            getGroupList(null, record, InspectionDetectionInfo.class, InspectionDetectionInfoModelForWX.class, inspectionDetectionInfoService, constructionList, true, dictionaryList, equipmentCategories);
            constructionJsonObject.put("title", "最近检验信息");
            constructionJsonObject.put("tabValue", constructionList);
            jsonArray.add(constructionJsonObject);

            // 设备维保信息
            JSONObject useJsonObject = new JSONObject();
            List maintenanceList = new ArrayList();
            getGroupList(null, record, MaintenanceInfo.class, MaintenanceInfoModelForWX.class, maintenanceInfoService, maintenanceList, false, dictionaryList, equipmentCategories);
            useJsonObject.put("title", "设备维保信息");
            if (maintenanceList.size() > 1) {
                List maintenanceList1 = new ArrayList();
                maintenanceList1.add(maintenanceList.get(0));
                maintenanceList.clear();
                maintenanceList.add(maintenanceList1.get(0));
            }
            useJsonObject.put("tabValue", maintenanceList);
            jsonArray.add(useJsonObject);
            map.put("tab", jsonArray);
        } else if ("气瓶".equals(map.get("EQU_CATEGORY"))) {
            // 基本信息
            Field[] fields2 = CylinderEquBaseInfoForWXModel.class.getDeclaredFields();
            for (Field f : fields2) {
                putMap.put(f.getName(), "");
            }

            getGroupList(putMap, record, RegistrationInfo.class, OtherEquBaseInfoForWXModel.class, registrationInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, DesignInfo.class, OtherEquBaseInfoForWXModel.class, designInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, OtherInfo.class, OtherEquBaseInfoForWXModel.class, otherInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, UseInfo.class, OtherEquBaseInfoForWXModel.class, unseInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, ProduceInfo.class, OtherEquBaseInfoForWXModel.class, produceInfoService, exFactoryList, false, dictionaryList, equipmentCategories);

            if (exFactoryList.size() > 0) {
                JSONObject jsonObject = (JSONObject) exFactoryList.get(0);
                List<HashMap<String, Object>> groupValue = (List<HashMap<String, Object>>) jsonObject.get("groupValue");
                groupValue.forEach(e -> {
                    e.put("fieldValue", putMap.get(e.get("fieldKey")));
                });
                Object ob = exFactoryList.get(0);
                exFactoryList.clear();
                exFactoryList.add(ob);
            }

            exFactoryJsonObject.put("title", "基本信息");
            exFactoryJsonObject.put("tabValue", exFactoryList);
            jsonArray.add(exFactoryJsonObject);

            // 最近检验信息
            JSONObject constructionJsonObject = new JSONObject();
            List constructionList = new ArrayList();
            getGroupList(null, record, InspectionDetectionInfo.class, InspectionDetectionInfoModelForWX.class, inspectionDetectionInfoService, constructionList, true, dictionaryList, equipmentCategories);
            constructionJsonObject.put("title", "最近检验信息");
            constructionJsonObject.put("tabValue", constructionList);
            jsonArray.add(constructionJsonObject);
            map.put("tab", jsonArray);
        } else {
            // 基本信息
            Field[] fields3 = OtherEquBaseInfoForWXModel.class.getDeclaredFields();
            for (Field f : fields3) {
                putMap.put(f.getName(), "");
            }

            getGroupList(putMap, record, RegistrationInfo.class, OtherEquBaseInfoForWXModel.class, registrationInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, DesignInfo.class, OtherEquBaseInfoForWXModel.class, designInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, OtherInfo.class, OtherEquBaseInfoForWXModel.class, otherInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, UseInfo.class, OtherEquBaseInfoForWXModel.class, unseInfoService, exFactoryList, false, dictionaryList, equipmentCategories);
            getGroupList(putMap, record, ProduceInfo.class, OtherEquBaseInfoForWXModel.class, produceInfoService, exFactoryList, false, dictionaryList, equipmentCategories);

            if (exFactoryList.size() > 0) {
                JSONObject jsonObject = (JSONObject) exFactoryList.get(0);
                List<HashMap<String, Object>> groupValue = (List<HashMap<String, Object>>) jsonObject.get("groupValue");
                groupValue.forEach(e -> {
                    e.put("fieldValue", putMap.get(e.get("fieldKey")));
                });
                Object ob = exFactoryList.get(0);
                exFactoryList.clear();
                exFactoryList.add(ob);
            }

            exFactoryJsonObject.put("title", "基本信息");
            exFactoryJsonObject.put("tabValue", exFactoryList);
            jsonArray.add(exFactoryJsonObject);

            // 最近检验信息
            JSONObject constructionJsonObject = new JSONObject();
            List constructionList = new ArrayList();
            getGroupList(null, record, InspectionDetectionInfo.class, InspectionDetectionInfoModelForWX.class, inspectionDetectionInfoService, constructionList, true, dictionaryList, equipmentCategories);
            constructionJsonObject.put("title", "最近检验信息");
            constructionJsonObject.put("tabValue", constructionList);
            jsonArray.add(constructionJsonObject);
            map.put("tab", jsonArray);
        }
        map.put("color", this.getQrCodeColor(record));
        return map;
    }

    private String getQrCodeColor(String record) {
        // 二维码颜色赋值逻辑
        OtherInfo otherInfo = otherInfoService.getOne(new LambdaQueryWrapper<OtherInfo>().eq(OtherInfo::getRecord, record));
        if (otherInfo != null) {
            return "0".equals(otherInfo.getStatus()) ? "#ff0000" : "#00ff00";
        }
        return "#f2f2f2";
    }

    public void getGroupList(HashMap putMap, String record, Class entity, Class dto, BaseService service, List list, boolean isOne, List<DataDictionary> dictionaryList, List<EquipmentCategory> equipmentCategories) {
        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), entity);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("RECORD", record);
        if (isOne) {
            wrapper.orderByDesc("REC_DATE");
        }

        List entityList = service.list(wrapper);
        Iterator iterator = entityList.iterator();
        JSONObject result;
        if (!isOne) {
            if (!ValidationUtil.isEmpty(entityList)) {
                if (entityList.size() > 0) {
                    while (iterator.hasNext()) {
                        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(iterator.next()));
                        result = getFieldList(putMap, dto, jsonObject, null, dictionaryList, equipmentCategories);
                        list.add(result);
                    }
                }
            }
        } else {
            int count = entityList.size();
            JSONObject jsonObject = null;
            if (count > 0) {
                jsonObject = JSON.parseObject(JSON.toJSONString(iterator.next()));
            } else {
                jsonObject = new JSONObject();
            }
            result = getFieldList(putMap, dto, jsonObject, count, dictionaryList, equipmentCategories);
            list.add(result);
        }
    }

    public JSONObject getFieldList(HashMap putMap, Class clazz, JSONObject jsonObject, Integer count, List<DataDictionary> dictionaryList, List<EquipmentCategory> equipmentCategories) {
        JSONObject result = new JSONObject();
        JSONObject ApiModel = JSON.parseObject(JSON.toJSONString(clazz.getAnnotation(ApiModel.class)));
        List<Field> declaredFields = Lists.newArrayList(clazz.getSuperclass().getDeclaredFields());
        declaredFields.addAll(Arrays.asList(clazz.getDeclaredFields()));

        List<Map<String, Object>> list = new ArrayList<>();
        if (!ValidationUtil.isEmpty(declaredFields)) {
            for (Field field : declaredFields) {
                if ("sequenceNbr".equals(field.getName()) || "recDate".equals(field.getName()) || "recUserId".equals(field.getName())
                        || "recUserName".equals(field.getName()) || "isDelete".equals(field.getName())) {
                    continue;
                }
                if (field.getAnnotation(ApiModelProperty.class) != null && !ValidationUtil.isEmpty(field.getAnnotation(ApiModelProperty.class).value())) {
                    Map<String, Object> map = new HashMap<>();
                    String filedName = field.getAnnotation(ApiModelProperty.class).value();
                    // key和value可根据需求存
                    // 这存的key为注解的值，value为类属性名
                    map.put("fieldName", filedName);
                    map.put("fieldKey", field.getName());
                    if (!ValidationUtil.isEmpty(jsonObject)) {
                        map.put("fieldValue", jsonObject.getString(field.getName()));
                        getCon(field.getName(), jsonObject, map, dictionaryList, equipmentCategories);
                    } else {
                        map.put("fieldValue", "");
                    }

                    if (null != putMap && putMap.containsKey(field.getName())) {
                        if (null != map.get("fieldValue")) {
                            putMap.put(field.getName(), map.get("fieldValue"));
                        }
                    }
                    // 街道信息处理
                    if (String.valueOf(map.get("fieldKey")).equals("factoryUseSiteStreet")) {
                        map.put("fieldValue", getStreet(String.valueOf(map.get("fieldValue"))));
                    }
                    list.add(map);
                }
            }
        }
        // 整理出现多个附件的情况
        Iterator<Map<String, Object>> iterator = list.iterator();
        JSONArray array = new JSONArray();
        Boolean bool = true;
        String name = "";
        while (iterator.hasNext()) {
            Map<String, Object> map = iterator.next();
            String fieldName = map.get("fieldName").toString();
            if (fieldName.contains("附件")) {
                if (bool) {
                    // 第一个出现的附件名称为表单显示的名称
                    name = fieldName;
                    bool = false;
                }
                if (!ValidationUtil.isEmpty(map.get("fieldValue"))) {
                    JSONArray jsonArray = JSON.parseArray(String.valueOf(map.get("fieldValue")));
                    JSONArray json = new JSONArray();
                    if (!ValidationUtil.isEmpty(jsonArray)) {
                        for (Object obj : jsonArray) {
                            JSONObject object = JSON.parseObject(JSON.toJSONString(obj));
                            if (!ValidationUtil.isEmpty(object)) {
                                object.getString("url");
                                object.put("url", object.getString("url"));
                                json.add(object);
                            }
                        }
                        array.addAll(json);
                    }
                }
                // 删除所有附件
                iterator.remove();
            }
        }
        // 如果有附件 整理为一个附件 添加入list里
        if (!bool) {
            Map<String, Object> map = new HashMap<>();
            map.put("fieldKey", "files");
            map.put("fieldValue", array);
            map.put("fieldName", name);
            list.add(map);
        }

        if (!ValidationUtil.isEmpty(count)) {
            result.put("groupCount", count);
        }

        result.put("groupName", ApiModel.getString("description"));
        result.put("groupKey", ApiModel.getString("value"));
        result.put("groupValue", list);
        return result;
    }

    public String getStreet(String code) {
        List<LinkedHashMap<String, Object>> streetList = null;
        if (redisUtil.hasKey(STREET)) {
            streetList = (List<LinkedHashMap<String, Object>>) redisUtil.get(STREET);
        }
        if (!ObjectUtils.isEmpty(code) && !ObjectUtils.isEmpty(streetList)) {
            List<LinkedHashMap<String, Object>> collect = streetList.stream().filter(item -> item.get("regionCode").toString().equals(code)).collect(Collectors.toList());
            if (!org.apache.commons.lang3.ObjectUtils.isEmpty(collect)) {
                return String.valueOf(collect.get(0).get("regionName"));
            }
        }
        return null;
    }

    /**
     * 获取焊口编号
     *
     * @return
     */
    public JSONObject getQRCode(String code) {
        String url = "";
        JSONObject jsonObject = new JSONObject();
        byte[] bytes = QRCodeUtil.generateQRCodeImageByteData(code, 50);
        InputStream inputStream = new ByteArrayInputStream(bytes);
        try {
            MultipartFile file = new MockMultipartFile(code + ".jpg", code + ".jpg", ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
            FeignClientResult<Map<String, String>> date = Systemctl.fileStorageClient.updateCommonFileFree(file, "ugp/qrcode");
            if (date != null) {
                Map<String, String> map = date.getResult();
                Iterator<String> it = map.keySet().iterator();
                String urlString = it.next();
                jsonObject.put("fileUrl", urlString);
                jsonObject.put("fileName", code);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public Object getEquipInfoBySuperviseCode(String supervisoryCode) {
        CategoryOtherInfo categoryOtherInfo = categoryOtherInfoMapper.selectOne(new QueryWrapper<CategoryOtherInfo>().eq("SUPERVISORY_CODE", supervisoryCode));
        return ObjectUtils.isEmpty(categoryOtherInfo) ? null : getEquipmentInfo(categoryOtherInfo.getRecord());
    }

    public Map<String, Object> login(MobileLoginParam param) {
        Map<String, Object> result = new LinkedHashMap<>();
        IdPasswordAuthModel idPasswordAuthModel = new IdPasswordAuthModel();
        idPasswordAuthModel.setLoginId(param.getPhoneNo());
        idPasswordAuthModel.setPassword(param.getVerifyCode());
        FeignClientResult<Map<String, String>> idpassword = new FeignClientResult<>();
        RequestContext.setToken("");
        RequestContext.setProduct(product);
        RequestContext.setAppKey(appKey);
        try {
            idpassword = Privilege.authClient.idpassword(idPasswordAuthModel);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (idpassword.getStatus() != successsCode) {

            log.error("远程调用Privilege服务失败", idpassword.getDevMessage());
            String message = idpassword.getMessage();
            if (StringUtils.isEmpty(message)) {
                message = "账号或密码错误";
            }
            throw new BadRequest(message);
        }
        if (ValidationUtil.isEmpty(idpassword) || ValidationUtil.isEmpty(idpassword.getResult()) ||
                ValidationUtil.isEmpty(idpassword.getResult().get("userId"))) {
            log.error("未修改成功");
            return new HashMap<String, Object>();
        }

        HashMap<Object, Object> authInfo = new HashMap<>();// 设置authInfo信息
        authInfo.put("token", idpassword.getResult().get("token"));
        authInfo.put("personId", idpassword.getResult().get("userId"));
        authInfo.put("appKey", appKey);
        authInfo.put("product", product);
        result.put("authInfo", authInfo);
        //查询用户信息
        RequestContext.setToken(idpassword.getResult().get("token"));
        FeignClientResult<AgencyUserModel> getme = Privilege.agencyUserClient.getme();
        getme.getResult().setPassword("");
        getme.getResult().setAppCodes(new ArrayList());
        result.put("userInfo", getme.getResult());
        return result;
    }


    @SneakyThrows
    public JSONObject wxUserLogin(JSONObject wx) {
        JSONObject obj = getSessionKey(wx);
        String sessionKey = obj.getString("session_key");
        //被加密的数据
        byte[] dataByte = Base64.getDecoder().decode(wx.getString("encryptedData"));
        //加密秘钥
        byte[] keyByte = Base64.getDecoder().decode(sessionKey);
        //偏移量
        byte[] ivByte = Base64.getDecoder().decode(wx.getString("iv"));
        JSONObject res = null;
        // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
        SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
        AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
        parameters.init(new IvParameterSpec(ivByte));
        cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
        byte[] resultByte = cipher.doFinal(dataByte);
        if (null != resultByte && resultByte.length > 0) {
            String result = new String(resultByte, "UTF-8");
            res = JSONObject.parseObject(result);
            return res;
        }

        return res;

    }


    private JSONObject getSessionKey(JSONObject wx) {
        StringBuffer buffer = new StringBuffer("https://api.weixin.qq.com/sns/jscode2session?appid=")
                .append(WxAppAppId).append("&secret=").append(WxAppSecret).append("&js_code=").append(wx.getString("js_code"))
                .append("&grant_type=").append(WxAppGrantType);
        String responseStr = HttpUtils.doGet(buffer.toString());
        JSONObject response = JSONObject.parseObject(responseStr);
        return response;
    }


    public Page equipmentCount(String companyCode) {
        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<>();
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.trackTotalHits(true);
        SearchRequest request = new SearchRequest();
        request.indices("idx_biz_view_jg_all");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();

        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.matchPhraseQuery("USE_UNIT_CREDIT_CODE", companyCode));
        boolMust.must(query);

        TermsAggregationBuilder field1Aggregation = AggregationBuilders
                .terms("group_by_code")
                .field("EQU_LIST_CODE")
                .size(1000);

        TermsAggregationBuilder field2Aggregation = AggregationBuilders
                .terms("group_by_status")
                .field("STATUS")
                .size(1000);
        builder.query(boolMust);
        field1Aggregation.subAggregation(field2Aggregation);
        builder.aggregation(field1Aggregation);
        builder.size(0);
        request.source(builder);
        Map<String, Object> statusCountMap = new HashMap<>();
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            Terms field1Terms = response.getAggregations().get("group_by_code");
            for (Terms.Bucket field1Bucket : field1Terms.getBuckets()) {
                Terms field2Terms = field1Bucket.getAggregations().get("group_by_status");
                for (Terms.Bucket field2Bucket : field2Terms.getBuckets()) {
                    String field1Value = field1Bucket.getKeyAsString();
                    String field2Value = EquipmentCategoryEnum.YRL.getName().equals(field2Bucket.getKeyAsString()) ? "alreadyClaim" :
                            EquipmentCategoryEnum.DRL.getName().equals(field2Bucket.getKeyAsString()) ? "waitClaim" :
                                    EquipmentCategoryEnum.YJL.getName().equals(field2Bucket.getKeyAsString()) ? "refuseClaim" : "caogao";
                    long docCount = field2Bucket.getDocCount();
                    statusCountMap.put(field1Value + "|" + field2Value, docCount);
                }
            }
        } catch (IOException e) {
            throw new BadRequest("es数据查询失败");
        }
        for (Map<String, Object> item : mapList) {
            item.put("waitClaim", getCountNumber(item.get("code").toString(), "waitClaim", statusCountMap));
            item.put("alreadyClaim", getCountNumber(item.get("code").toString(), "alreadyClaim", statusCountMap));
            item.put("refuseClaim", getCountNumber(item.get("code").toString(), "refuseClaim", statusCountMap));
            item.put("sum", Long.parseLong(item.get("waitClaim").toString()) + Long.parseLong(item.get("alreadyClaim").toString()) + Long.parseLong(item.get("refuseClaim").toString()));
            list.add(item);
        }
        page.setCurrent(1);
        page.setTotal(list.size());
        page.setRecords(list);
        return page;
    }

    private Long getCountNumber(String type, String status, Map<String, Object> statusCountMap) {
        String key = type + "|" + status;
        return Long.parseLong(statusCountMap.getOrDefault(key, "0").toString());
    }

    public Page<Map<String, Object>> getTable(Map<String, Object> map) {
        Page<Map<String, Object>> table = null;
        String teqy = (String) map.get("teqy");
        if (ValidationUtil.isEmpty(teqy)) {
            table = equipmentCategoryServiceImpl.getTable(map);
        } else {
            map.remove("teqy");
            table = idxFeignService.getPage(map).getResult();
        }
        return table;
    }


    public JSONArray getRegionName() {
        JSONArray jsonArray = new JSONArray();
        if (redisUtils.hasKey(regionRedis)) {
            jsonArray = JSONArray.parseArray(redisUtils.get(regionRedis).toString());
        } else {
            Collection<RegionModel> regionChild = new ArrayList<>();
            RegionModel regionModel1 = new RegionModel();
            regionChild.add(regionModel1);
            FeignClientResult<Collection<RegionModel>> collectionFeignClientResult = Systemctl.regionClient.queryForTreeParent(610000L);
            Collection<RegionModel> result = collectionFeignClientResult.getResult();
            for (RegionModel regionModel : result) {
                for (RegionModel child : regionModel.getChildren()) {
                    for (RegionModel childChild : child.getChildren()) {
                        jsonArray.add(childChild);
                    }
                    child.setChildren(regionChild);
                    jsonArray.add(child);
                }
                regionModel.setChildren(regionChild);
                jsonArray.add(regionModel);
            }

            redisUtils.set(regionRedis, jsonArray);
        }
        return jsonArray;
    }

    //查询字典值(只针对设备一码通详情字典,其他勿用)
    public List<DataDictionary> getDictionary() {
        LambdaQueryWrapper<DataDictionary> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(DataDictionary::getSequenceNbr, 5951L).le(DataDictionary::getSequenceNbr, 6529L);
        List<DataDictionary> dataDictionaryList = dataDictionaryMapper.selectList(wrapper);
        return dataDictionaryList;
    }

    // 处理字典值
    public void getCon(String fileName, JSONObject jsonObject, Map<String, Object> map,
                       List<DataDictionary> dictionaryList, List<EquipmentCategory> equipmentCategories) {
        if ("city".contains(fileName) || "county".contains(fileName)) {
            JSONArray regionName = getRegionName();
            List<RegionModel> list = JSONArray.parseArray(regionName.toJSONString(), RegionModel.class);
            if (!ValidationUtil.isEmpty(list) && !ValidationUtil.isEmpty(jsonObject.getString(fileName))) {
                String cityName =
                        list.stream().filter(i -> i.getRegionCode().equals(Integer.valueOf(jsonObject.getString("city")))).findFirst().orElse(new RegionModel()).getRegionName();
                String countyName =
                        list.stream().filter(i -> i.getRegionCode().equals(Integer.valueOf(jsonObject.getString(
                                "county")))).findFirst().orElse(new RegionModel()).getRegionName();
                map.put("fieldValue", cityName + "/" + countyName);
            }
        }

        if ("designStandard".indexOf(fileName) != -1) {
            JSONArray jsonArray = JSONArray.parseArray(jsonObject.getString(fileName));
            map.put("fieldValue", jsonArray);
        }

        getIf("imported", fileName, "BOOLEN", dictionaryList, jsonObject, map);
        getIf("changes", fileName, "BGSX", dictionaryList, jsonObject, map);
        getIf("usePlace", fileName, "ADDRESS", dictionaryList, jsonObject, map);
        getIf("equManageDt", fileName, "ZGBM", dictionaryList, jsonObject, map);
        getIf("equState", fileName, "SHZT", dictionaryList, jsonObject, map);
        getIf("denselyPopulatedAreas", fileName, "BOOLEN", dictionaryList, jsonObject, map);
        getIf("importantPlaces", fileName, "BOOLEN", dictionaryList, jsonObject, map);
        getIf("registerState", fileName, "ZC", dictionaryList, jsonObject, map);
        getIf("inspectType", fileName, "JYLX", dictionaryList, jsonObject, map);
        getIf("inspectConclusion", fileName, "JYJL", dictionaryList, jsonObject, map);
        getIf("constructionType", fileName, "SGLX", dictionaryList, jsonObject, map);

        for (EquipmentCategory equipmentCategory : equipmentCategories) {
            if ("equDefine".contains(fileName) && !ValidationUtil.isEmpty(equipmentCategory) && !ValidationUtil.isEmpty(equipmentCategory.getCode()) &&
                    !ValidationUtil.isEmpty(fileName) && !ValidationUtil.isEmpty(jsonObject.getString(fileName)) && equipmentCategory.getCode().contains(jsonObject.getString(fileName))) {
                map.put("fieldValue", equipmentCategory.getName());
            }
            if ("equCategory".contains(fileName) && !ValidationUtil.isEmpty(equipmentCategory) && !ValidationUtil.isEmpty(equipmentCategory.getCode()) &&
                    !ValidationUtil.isEmpty(fileName) && !ValidationUtil.isEmpty(jsonObject.getString(fileName)) && equipmentCategory.getCode().contains(jsonObject.getString(fileName))) {
                map.put("fieldValue", equipmentCategory.getName());
            }
        }
        getIf("carrierLine", fileName, "YZS", dictionaryList, jsonObject, map);
        getIf("deviceLevel", fileName, "GLJB", dictionaryList, jsonObject, map);
        getIf("fuelType", fileName, "GLZL", dictionaryList, jsonObject, map);
        getIf("nameOfPressureParts", fileName, "GLBJMC", dictionaryList, jsonObject, map);
        getIf("nonDestructiveTestingMethodsForPressureParts", fileName, "GLWSJCFF", dictionaryList, jsonObject, map);
        getIf("qpLossless", fileName, "RQJCFF", dictionaryList, jsonObject, map);
        getIf("glLossless", fileName, "RQJCFF", dictionaryList, jsonObject, map);
        getIf("mainStructureType", fileName, "RQJG", dictionaryList, jsonObject, map);
        getIf("checkLossless", fileName, "RQJCFF", dictionaryList, jsonObject, map);
        getIf("pipelineClass", fileName, "GDLB", dictionaryList, jsonObject, map);
        getIf("deviceLevel", fileName, "GBI", dictionaryList, jsonObject, map);
        getIf("workLevel", fileName, "GZJB", dictionaryList, jsonObject, map);
        getIf("mainStructureType", fileName, "JGS", dictionaryList, jsonObject, map);
        getIf("luffingMode", fileName, "BFFS", dictionaryList, jsonObject, map);
        getIf("towerStandardType", fileName, "JXS", dictionaryList, jsonObject, map);
        getIf("baseType", fileName, "JZXS", dictionaryList, jsonObject, map);
        getIf("outriggerType", fileName, "ZT", dictionaryList, jsonObject, map);
        getIf("mainBeamType", fileName, "ZLXS", dictionaryList, jsonObject, map);
        getIf("boomType", fileName, "BJXS", dictionaryList, jsonObject, map);
        getIf("boomStructureType", fileName, "BJJGXS", dictionaryList, jsonObject, map);
        getIf("gantryStructureType", fileName, "MJJG", dictionaryList, jsonObject, map);
        getIf("use", fileName, "YT", dictionaryList, jsonObject, map);
        getIf("controlMode", fileName, "CZFS", dictionaryList, jsonObject, map);
        getIf("hangingCagesNumber", fileName, "DLSL", dictionaryList, jsonObject, map);
        getIf("driveMechanismType", fileName, "QDJG", dictionaryList, jsonObject, map);
        getIf("guideRailFrame", fileName, "DS", dictionaryList, jsonObject, map);
        getIf("liftingDriveMode", fileName, "QD", dictionaryList, jsonObject, map);
        getIf("operationMode", fileName, "JXCZ", dictionaryList, jsonObject, map);
        getIf("liftingMode", fileName, "QSFS", dictionaryList, jsonObject, map);
        getIf("explosionProofGrade", fileName, "FBDJ", dictionaryList, jsonObject, map);
        getIf("hoistWorkingLevel", fileName, "GZJB", dictionaryList, jsonObject, map);
        getIf("bigcarTraveWorkingLevel", fileName, "GZJB", dictionaryList, jsonObject, map);
        getIf("smallcarTraveWorkingLevel", fileName, "GZJB", dictionaryList, jsonObject, map);
        getIf("hoistWorkingLevel", fileName, "GZJB", dictionaryList, jsonObject, map);
        getIf("smallcarSideswayWorkingLevel", fileName, "GZJB", dictionaryList, jsonObject, map);
        getIf("partName", fileName, "ZYLBJ", dictionaryList, jsonObject, map);
        getIf("workType", fileName, "GZLX", dictionaryList, jsonObject, map);
        getIf("controlMode", fileName, "KZFS", dictionaryList, jsonObject, map);
        getIf("jackingType", fileName, "DSXS", dictionaryList, jsonObject, map);
        getIf("explosionproofType", fileName, "FBXS", dictionaryList, jsonObject, map);
        getIf("explosionproofGrade", fileName, "FBDJ", dictionaryList, jsonObject, map);
        getIf("xgxlMediaType", fileName, "XGJZZL", dictionaryList, jsonObject, map);
        getIf("designation", fileName, "KYSDBJMC", dictionaryList, jsonObject, map);
        getIf("designation", fileName, "CCFJDCLLBJMC", dictionaryList, jsonObject, map);
        getIf("isMonitor", fileName, "HAVE", dictionaryList, jsonObject, map);
        if ("equList".indexOf(fileName) != -1) {
            String equList = EquipmentClassifityEnum.getName.get(jsonObject.getString(fileName));
            map.put("fieldValue", equList);
        }
    }

    public void getIf(String name, String fileName, String type, List<DataDictionary> dictionaryList, JSONObject jsonObject, Map<String, Object> map) {
        if (name.indexOf(fileName) != -1) {
            List<DataDictionary> list = dictionaryList.stream().filter(t -> t.getType().equals(type) && t.getCode().equals(jsonObject.getString(fileName))).collect(Collectors.toList());
            if (list.size() > 0) {
                map.put("fieldValue", list.get(0).getName());
            }
        }
    }
}
