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.CommonException;
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.api.mapper.ViewJgClaimMapper;
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
	EquipTechParamLiftingService liftingService;
	@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("${minio.url.path}")
	String minioPath;
	@Autowired
	ViewJgClaimMapper viewJgClaimMapper;
	@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);

		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);
		}
		return map;
	}

	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();
					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 CommonException(600001, 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 ("province".contains(fileName) || "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());
			}
		}
	}
}
