package com.persagy.proxy.object.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.RowUtil;
import cn.hutool.poi.excel.WorkbookUtil;
import cn.hutool.poi.excel.cell.CellUtil;
import cn.hutool.poi.excel.editors.TrimEditor;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.dmp.basic.dto.RequestData;
import com.persagy.dmp.basic.model.QueryCriteria;
import com.persagy.dmp.common.constant.CommonConstant;
import com.persagy.dmp.common.constant.ResponseCode;
import com.persagy.dmp.common.context.AppContext;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.dmp.common.model.response.CommonResult;
import com.persagy.dmp.define.client.DigitalObjectInfoFacade;
import com.persagy.dmp.define.entity.ObjectInfoDefine;
import com.persagy.dmp.define.entity.ObjectTypeDefine;
import com.persagy.dmp.digital.client.DigitalObjectFacade;
import com.persagy.dmp.simple.client.DigitalObjectSimpleFacade;
import com.persagy.proxy.adm.constant.AdmCommonConstant;
import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
import com.persagy.proxy.adm.request.*;
import com.persagy.proxy.adm.service.IAdmRelationService;
import com.persagy.proxy.adm.utils.AdmContextUtil;
import com.persagy.proxy.adm.utils.AdmExcelUtil;
import com.persagy.proxy.adm.utils.AdmQueryCriteriaHelper;
import com.persagy.proxy.adm.utils.ObjectNameUtil;
import com.persagy.proxy.common.entity.InstanceUrlParam;
import com.persagy.proxy.common.entity.RelationDTO;
import com.persagy.proxy.dictionary.service.IAdmDictService;
import com.persagy.proxy.object.model.AdmEquipment;
import com.persagy.proxy.object.model.AdmProject;
import com.persagy.proxy.object.model.AdmSystem;
import com.persagy.proxy.object.service.IAdmEquipmentService;
import com.persagy.proxy.object.service.IAdmProjectService;
import com.persagy.proxy.report.model.EquipmentPointExcel;
import com.persagy.proxy.report.service.IRelationReportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.Color;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Adm 楼层 API
 * @author lvxy
 * @date 2021/8/16
 */
@Slf4j
@RestController
@RequestMapping("/object/equip")
public class AdmEquipmentController {
	@Autowired
	private IAdmEquipmentService service;
	@Autowired
	private IAdmRelationService relationService;
	@Autowired
	private IRelationReportService relationReportService;
	@Autowired
	private IAdmDictService dictService;
	@Autowired
	private IAdmProjectService projectService;
	/**
	 * 统计
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/count")
	public AdmResponse count(@RequestBody AdmQueryCriteria request) throws Exception {
		request.setName(AdmEquipment.OBJ_TYPE);
		request.setOnlyCount(true);
		return service.query(request);
	}

	/**
	 * 创建
	 * @param createRequest
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/create")
	public AdmCreateResponse create(@RequestBody AdmCreateRequest<AdmEquipment> createRequest) throws Exception {
		List<AdmEquipment> vos = CollUtil.newArrayList(createRequest.getContent());
		if(CollUtil.isEmpty(vos)){
			return AdmCreateResponse.success();
		}
		vos = service.doInsert(AdmContextUtil.toDmpContext(), AdmEquipment.class, vos);
		return AdmCreateResponse.success(vos);
	}

	/**
	 * 根据ID删除
	 * @param vos
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/delete")
	public AdmResponse delete( @RequestBody List<AdmEquipment> vos) throws Exception {
		// 组装上下文条件
		service.doDelete(AdmContextUtil.toDmpContext(), vos);
		return AdmResponse.success();
	}

	/**
	 * 更新
	 * @param createRequest
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/update")
	public AdmResponse update(@RequestBody AdmCreateRequest<AdmEquipment> createRequest) throws Exception {
		List<AdmEquipment> vos = createRequest.getContent();
		if(CollUtil.isEmpty(vos)) {
			return AdmResponse.success(vos);
		}
		vos = service.doUpdate(AdmContextUtil.toDmpContext(), AdmEquipment.class, vos);
		return AdmResponse.success(vos);
	}

	/**
	 * 查询
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/query")
	public AdmResponse query(@RequestBody AdmQueryCriteria request) throws Exception {
		// 组装上下文条件
		request.setName(AdmEquipment.OBJ_TYPE);
		if(CollUtil.isEmpty(request.getCascade()) && CollUtil.isNotEmpty(request.getProjection()) && request.getDistinct() != null && request.getDistinct() && request.getProjection().size() == 1 && request.getProjection().get(0).equals("classCode")) {
			/** 特殊处理
			 * distinct: true
			 * pageNumber: 1
			 * pageSize: 1000
			 * projection: ["classCode"]
			 * 0: "classCode"
			 */
			RequestData requestData = new RequestData();
			requestData.setProjection(request.getProjection());
			requestData.setObjType(AdmEquipment.OBJ_TYPE);
			requestData.setPage(request.getPageNumber().longValue());
			requestData.setSize(request.getPageSize().longValue());
			CommonResult<List<ObjectNode>> result = DigitalObjectSimpleFacade.queryObjListByConditions(AdmContextUtil.toDmpContext().getGroupCode(), AdmContextUtil.toDmpContext().getProjectId(), AdmContextUtil.toDmpContext().getAppId(), null, requestData);
			if (result == null || CollUtil.isEmpty(result.getData())) {
				return AdmResponse.success();
			}else{
				List<AdmEquipment> admEquipments = JSONUtil.toList(result.getData().toString(), AdmEquipment.class);
				service.ensureSpecialValues(AdmContextUtil.toDmpContext(), admEquipments);
				return AdmResponse.success(admEquipments, request);
			}
		}else{
			return service.query(request);
		}

	}

	/**
	 * 设备绑定的动态信息点或静态信息点
	 * @param type 数据类型 static (静态)、iot (动态)
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/export")
	public void exportInfos(@RequestParam("type") String type, @RequestParam("projectId") String projectId, HttpServletResponse response) throws Exception {
		try {
			response.setContentType("application/vnd.ms-excel");
			String encode = StandardCharsets.UTF_8.name();
			response.setCharacterEncoding(encode);
			AdmQueryCriteria projectRequest = new AdmQueryCriteria();
			projectRequest.setName(AdmProject.OBJ_TYPE);
			projectRequest.setFilters("id = '" + projectId + "';");
			AdmResponse responsePro = projectService.doQuery(AdmContextUtil.toDmpContext(), projectRequest, AdmProject.class);

			if (CollUtil.isEmpty(responsePro.getContent())) {
				throw new BusinessException(ResponseCode.A0402.getCode(), ResponseCode.A0402.getDesc());
			} else {
				AdmProject admProject = (AdmProject) responsePro.getContent().get(0);
				// 防止中文乱码
				String fileName = admProject.getLocalName() + "设备已交付信息点";
				fileName = URLEncoder.encode(fileName, encode);

				response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
				List<EquipmentPointExcel> equipmentPointExcels = dealEquipmentPoint(admProject.getGroupCode(),admProject.getId(),type, false, null);
				int count = equipmentPointExcels.size();
				if(count > 100000){
					ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), EquipmentPointExcel.class).build();
					try {
						WriteSheet writeSheet = EasyExcel.writerSheet(0, "sheet1").build();
						excelWriter.write(equipmentPointExcels.subList(0,100000), writeSheet);

						WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "sheet2").build();
						excelWriter.write(equipmentPointExcels.subList(100000,count), writeSheet2);
					} finally {
						if (excelWriter != null) {
							excelWriter.finish();
						}
					}
				}else{
					EasyExcel.write(response.getOutputStream(), EquipmentPointExcel.class).sheet("sheet1").doWrite(equipmentPointExcels);
				}
			}
		}catch (Exception e){
			log.error("设备数据导出异常,获取项目失败",e);
		}
	}
	/**
	 * 根据建筑 查询设备绑定的动态信息点或静态信息点
	 * @param type 数据类型 static (静态)、iot (动态)
	 */
	@GetMapping("/export/bulidng")
	public void equipInfosTwo(@RequestParam("type") String type, @RequestParam("projectId") String projectId, HttpServletResponse response,@RequestParam("buildingId") String buildingId) {
		try {
			response.setContentType("application/vnd.ms-excel");
			String encode = StandardCharsets.UTF_8.name();
			response.setCharacterEncoding(encode);
			AdmQueryCriteria projectRequest = new AdmQueryCriteria();
			projectRequest.setName(AdmProject.OBJ_TYPE);
			projectRequest.setFilters("id = '" + projectId + "';");
			AdmResponse responsePro = projectService.doQuery(AdmContextUtil.toDmpContext(), projectRequest, AdmProject.class);

			if (CollUtil.isEmpty(responsePro.getContent())) {
				throw new BusinessException(ResponseCode.A0402.getCode(), ResponseCode.A0402.getDesc());
			} else {
				AdmProject admProject = (AdmProject) responsePro.getContent().get(0);
				// 防止中文乱码
				String fileName = admProject.getLocalName() + "设备已交付信息点";
				fileName = URLEncoder.encode(fileName, encode);

				response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
				List<EquipmentPointExcel> equipmentPointExcels = dealEquipmentPoint(admProject.getGroupCode(),admProject.getId(),type, true, buildingId);
				EasyExcel.write(response.getOutputStream(), EquipmentPointExcel.class).sheet("sheet1").doWrite(equipmentPointExcels);
			}
		}catch (Exception e){
			log.error("设备数据导出异常,获取项目失败",e);
		}
	}
	/**
	 * 根据项目id查询所有的设备和部件
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/query-equip")
	public AdmResponse queryEquip(@RequestBody AdmQueryCriteria request) throws Exception {
		//request.setName("equipment");
		if(StrUtil.isNotEmpty(request.getFilters())){
			request.setFilters(String.join(";",request.getFilters(),"objType in ['equipment','component']"));
		}else{
			request.setFilters("objType in ['equipment','component']");
		}
		return service.query(request);
	}

	/**
	 * 批量创建设备同时创建资产、创建设备和系统的关系
	 * @param admEquipment
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/creat-equip-pro")
	public AdmCreateResponse createExt(@RequestBody AdmCreateRequest<AdmEquipment> admEquipment) throws Exception {
		List<AdmEquipment> vos = admEquipment.getContent();
		if(CollUtil.isEmpty(vos)){
			return AdmCreateResponse.success();
		}
		// 这里应该要移到实现类里
		List<RelationDTO> relationDTOS = new ArrayList<>(16);
		for(AdmEquipment vo:vos) {
			if (StrUtil.isBlank(vo.getId())){
				vo.setId(AdmContextUtil.generateIdStr("Eq",true));
			}
			if (StrUtil.isEmpty(vo.getName())){
				vo.setName(ObjectNameUtil.objectName("设备-"));
			}
			List<AdmSystem> systems = vo.getLinkSystem();
			if(CollUtil.isNotEmpty(systems)){
				for(AdmSystem system:systems) {
					relationDTOS.add(new RelationDTO(StrUtil.format(CommonConstant.DEFAULT_GRAPH_ID_FORMAT,
							AdmRelationTypeEnum.EQ2SY.getGraphCode()), AdmRelationTypeEnum.EQ2SY.getGraphCode(),
							AdmRelationTypeEnum.EQ2SY.getRelCode(), null , system.getId(), vo.getId()));
				}
			}
		}
		if (CollUtil.isNotEmpty(relationDTOS)){
			relationService.doSave(AdmContextUtil.toDmpContext(),relationDTOS);
		}
		vos = service.doInsert(AdmContextUtil.toDmpContext(), AdmEquipment.class, vos);
		return AdmCreateResponse.success(vos);
	}

	/**
	 * 设备上传excel识别静态信息点
	 *
	 * @param file
	 * @param request
	 * @param response
	 */
	@RequestMapping("/import")
	public AdmResponse importFile(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
		if (file == null) {
			return AdmResponse.failure("未选择文件");
		}
		String path = AdmCommonConstant.SERVER_ROOT_PATH + AdmExcelUtil.TEMP_UPLOAD_PAHT;

		int failurNum = 0;
		int successCount = 0;
		String failure = null;
		String primaryKey = null;
		String classCodeCloumn = null;
		Workbook workbook = null;
		FileOutputStream fileOutputStream = null;
		String groupCode = AppContext.getContext().getGroupCode();
		String projectId = AppContext.getContext().getProjectId();
		try {
			byte[] bytes = IoUtil.readBytes(file.getInputStream());
			workbook = WorkbookUtil.createBook(IoUtil.toStream(bytes));
			Sheet sheet = WorkbookUtil.getOrCreateSheet(workbook, 0);
			Row row1 = RowUtil.getOrCreateRow(sheet, 1);
			/** 获取识别码 */
			Cell markCell = CellUtil.getCell(row1, 0);
			if (markCell == null) {
				AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
				return AdmExcelUtil.getImportFailResult("未填写识别码", "2", 0, ++failurNum);
			}
			primaryKey = StrUtil.toString(CellUtil.getCellValue(markCell,true)); 	// 识别码
			if (!AdmCommonConstant.codeColMap.containsKey(primaryKey)) {
				AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
				return AdmExcelUtil.getImportFailResult("未找到识别码", "2", 0, ++failurNum);
			}
			primaryKey = AdmCommonConstant.codeColMap.get(primaryKey);
			/** 获取类型 */
			Cell cell = CellUtil.getCell(row1,1);
			if (cell == null) {
				AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
				return AdmExcelUtil.getImportFailResult("未填写设备类型", "2", 0, ++failurNum);
			}
			classCodeCloumn = cell.getStringCellValue().trim();
			if (!"ClassCode".equals(classCodeCloumn)) {
				AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
				return AdmExcelUtil.getImportFailResult("缺少设备类型（ClassCode）", "2", 0, ++failurNum);
			}
			// 写入错误报告对比值颜色
			this.wirteReport(workbook, sheet);
			// 存取所有的信息点
			Map<Integer, String> infoMap = new HashMap<>();
			List<Object> row1List = RowUtil.readRow(row1, new TrimEditor());
			for (int i = 1; i < row1List.size(); i++) {
				infoMap.put(i,StrUtil.toString(row1List.get(i)));
			}
			boolean isClassCode = "classCode".equals(primaryKey);
			ExcelReader excelReader = ExcelUtil.getReader(IoUtil.toStream(bytes), 0);
			List<List<Object>> listList = excelReader.read();
			// 1.存储设备类型code
			Set<String> classCodes = CollUtil.newHashSet();
			// 2.存储primaryKey对应的值
			Set<String> primaryMess = CollUtil.newHashSet();
			for (int i = 2; i < listList.size(); i++) {
				List<Object> objects = listList.get(i);
				if (CollUtil.isEmpty(objects)){
					continue;
				}
				if (null==objects.get(0) || StrUtil.isBlank(StrUtil.toString(objects.get(0)))){
					this.setColor(workbook, 252, 255, 77,
							CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(sheet,i),0));
					continue;
				}
				if (!isClassCode && (null==objects.get(1) || StrUtil.isBlank(StrUtil.toString(objects.get(1))))){
					// 第一个cell为空或者非classCode上传并且第二个cell为空
					this.setColor(workbook, 252, 255, 77,
							CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(sheet,i),0));
					continue;
				}
				if (isClassCode){
					classCodes.add(StrUtil.toString(objects.get(0)));
					continue;
				}
				classCodes.add(StrUtil.toString(objects.get(1)));
				primaryMess.add(StrUtil.toString(objects.get(0)));
			}
			if (isClassCode && CollUtil.isEmpty(classCodes)){
				// 设备类型code集合为空
				String fileName = AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
				return AdmExcelUtil.getImportSuccessResult(fileName, successCount, listList.size());
			}
			if (!isClassCode && (CollUtil.isEmpty(primaryMess) || CollUtil.isEmpty(classCodes))){
				// 设备类型code集合或唯一标识为空
				String fileName = AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
				return AdmExcelUtil.getImportSuccessResult(fileName, successCount, listList.size());
			}
			// 1.根据设备类型code集合查询定义
			Map<String,ObjectTypeDefine> defineMap = relationReportService.queryDefineTypeMapByClassCodes(classCodes);
			// 2.根据设备类型code集合查询设备类的信息点
			Map<String,List<ObjectInfoDefine>> defineInfoMap = relationReportService.queryDefineInfoMapByClassCodes(classCodes);
			// 3.根据是否根据设备类型code上传来区分处理
			Map<String,List<ObjectNode>> objectDigitalMap = CollUtil.newHashMap();
			if (isClassCode){
				objectDigitalMap=relationReportService.queryEquipsByClassCodes(classCodes);
			}else {
				objectDigitalMap=relationReportService.queryEquipsByConditions(primaryKey,primaryMess,classCodes);
			}
			List<ObjectNode> updateObjs = new ArrayList<>();
			ObjectNode equipment = null;
			List<ObjectNode> equipmentList = null;
			for (int i = 2; i < listList.size(); i++) {
				List<Object> objects = listList.get(i);
				if (CollUtil.isEmpty(objects)){
					continue;
				}
				if ((null==objects.get(0) || StrUtil.isBlank(StrUtil.toString(objects.get(0))))
						|| (!isClassCode && (null==objects.get(1) || StrUtil.isBlank(StrUtil.toString(objects.get(1)))))){
					failurNum++;
					continue;
				}
				String classCode = isClassCode?StrUtil.toString(objects.get(0)):StrUtil.toString(objects.get(1));
				if (!defineMap.containsKey(classCode)){
					failurNum++;
					this.setColor(workbook, 56, 94, 15, CellUtil.getCell(RowUtil.getOrCreateRow(sheet, i), isClassCode?0:1));
					continue;
				}
				classCode = defineMap.get(classCode).getCode();
				equipmentList = isClassCode ? objectDigitalMap.get(classCode)
						: objectDigitalMap.get(StrUtil.toString(objects.get(0)) + StrUtil.UNDERLINE + classCode);
				if (CollectionUtil.isEmpty(equipmentList)) {
					failurNum++;
					this.setColor(workbook, 153, 225, 77, CellUtil.getCell(RowUtil.getOrCreateRow(sheet, i), 0));
					continue;
				}
				if (isClassCode) {
					equipment = equipmentList.get(0);
				} else {
					if (equipmentList.size() > 1) {
						failurNum++;
						this.setColor(workbook, 249, 203, 77, CellUtil.getCell(RowUtil.getOrCreateRow(sheet, i), 1));
						continue;
					} else {
						equipment = equipmentList.get(0);
					}
				}
				boolean changeFlag = true;
				for (int j = 2; j < objects.size(); j++) {
					// 剩余列数据处理
					if (!infoMap.containsKey(j)) {
						continue;
					}
					Cell tempCell = CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(sheet, i), j);
					// 如果值为空直接跳过
					if (StrUtil.isBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))){
						continue;
					}
					// 获取设备类的信息点
					String code = infoMap.get(j);
					List<ObjectInfoDefine> funidList = defineInfoMap.getOrDefault(classCode,new ArrayList<>())
							.stream().filter(func->code.equals(func.getAliasCode()) && "STATIC".equals(func.getCategory()))
							.collect(Collectors.toList());
					if (CollectionUtil.isEmpty(funidList)) {
						failurNum++;
						this.setColor(workbook, 77, 178, 255, tempCell);
						changeFlag=false;
						continue;
					}
					ObjectInfoDefine define = funidList.get(0);
					if ("STRING".equalsIgnoreCase(define.getDataType())) {
						tempCell.setCellType(CellType.STRING);
						equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
					} else if ("INTEGER".equalsIgnoreCase(define.getDataType())) {
						try {
							if (!CellType.NUMERIC.equals(tempCell.getCellTypeEnum())
									|| StrUtil.isBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))) {
								failurNum++;
								this.setColor(workbook, 155, 227, 255, tempCell);
								changeFlag=false;
								continue;
							}
							tempCell.setCellType(CellType.STRING);
							equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
						} catch (Exception e) {
							failurNum++;
							this.setColor(workbook, 155, 227, 255, tempCell);
							changeFlag=false;
							continue;
						}
					} else if ("ENUM".equalsIgnoreCase(define.getDataType())) {
						if (CellType.NUMERIC.equals(tempCell.getCellTypeEnum())
								&& StrUtil.isNotBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))) {
							tempCell.setCellType(CellType.STRING);
							equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
						} else if (CellType.STRING.equals(tempCell.getCellTypeEnum())
								&& StrUtil.isNotBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))) {
							equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
						} else {
							failurNum++;
							this.setColor(workbook, 155, 227, 255, tempCell);
							changeFlag=false;
							continue;
						}
					} else if ("DATETIME".equalsIgnoreCase(define.getDataType())) {
						try {
							tempCell.setCellType(CellType.STRING);
							String trim = tempCell.getStringCellValue().trim();
							DateUtil.parseByPatterns(trim, "yyyyMMdd");
							equipment.put(define.getCode(), trim);
						} catch (Exception e) {
							failurNum++;
							this.setColor(workbook, 155, 227, 255, tempCell);
							changeFlag=false;
							continue;
						}
					} else if ("DOUBLE".equalsIgnoreCase(define.getDataType())) {
						try {
							tempCell.setCellType(CellType.STRING);
							String trim = tempCell.getStringCellValue().trim();
							equipment.put(define.getCode(), Double.parseDouble(trim));
						} catch (Exception e) {
							failurNum++;
							this.setColor(workbook, 155, 227, 255, tempCell);
							changeFlag=false;
							continue;
						}
					} else if ("BOOLEAN".equalsIgnoreCase(define.getDataType())) {
						tempCell.setCellType(CellType.STRING);
						String trim = tempCell.getStringCellValue() == null ? null : tempCell.getStringCellValue().trim();
						if ("1".equals(trim) || "0".equals(trim)) {
							equipment.put(define.getCode(), Double.parseDouble(trim));
						} else {
							failurNum++;
							this.setColor(workbook, 155, 227, 255, tempCell);
							changeFlag=false;
							continue;
						}
					} else {
						failurNum++;
						this.setColor(workbook, 204, 99, 233, tempCell);
						changeFlag=false;
						continue;
					}
				}
				if (changeFlag){
					updateObjs.add(equipment);
				}
			}
			// 5.更新对象数据
			if (CollUtil.isNotEmpty(updateObjs)){
				successCount=updateObjs.size();
				DigitalObjectFacade.update(AppContext.getContext().getGroupCode(),
						AppContext.getContext().getProjectId(),
						AppContext.getContext().getAppId(),
						AppContext.getContext().getAccountId(),
						updateObjs);
			}
			// 设备类型code集合或唯一标识为空
			String fileName = AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
			return AdmExcelUtil.getImportSuccessResult(fileName, successCount, failurNum);
		} catch (Exception e) {
			log.error("台账信息导入失败", e);
			failure = e.getMessage();
		} finally {
			if (fileOutputStream != null) {
				try {
					fileOutputStream.flush();
					fileOutputStream.close();
				} catch (IOException e) {}
			}
			if (workbook != null) {
				try {
					workbook.close();
				} catch (IOException e) {}
			}
		}
		return AdmResponse.failure(failure);
	}

	/**
	 * 设置填充色
	 *
	 * @param workbook
	 * @param r
	 * @param g
	 * @param b
	 * @param cell
	 */
	private void setColor(Workbook workbook, int r, int g, int b, Cell cell) {
		XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
		cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		cellStyle.setFillForegroundColor(new XSSFColor(new Color(r, g, b)));
		cell.setCellStyle(cellStyle);
	}

	/**
	 * 写入错误报告对比值颜色
	 *
	 * @param workbook
	 * @param sheet
	 */
	private void wirteReport(Workbook workbook, Sheet sheet) {
		Row row = sheet.getRow(1);
		short column = (short) (row.getLastCellNum() + 2);
		Row row4 = sheet.getRow(4);
		if (row4 == null) {
			row4 = sheet.createRow(4);
		}
		Cell createCell = row4.createCell(column);
		createCell.setCellValue("导入失败,识别码超出范围(本地编码，设备类型)");
		createCell = row4.createCell(column + 1);
		this.setColor(workbook,233,99,99,createCell);

		Row row5 = sheet.getRow(5);
		if (row5 == null) {
			row5 = sheet.createRow(5);
		}
		createCell = row5.createCell(column);
		createCell.setCellValue("导入失败,识别码为空");
		createCell = row5.createCell(column + 1);
		this.setColor(workbook,252,147,77,createCell);

		Row row6 = sheet.getRow(6);
		if (row6 == null) {
			row6 = sheet.createRow(6);
		}
		createCell = row6.createCell(column);
		createCell.setCellValue("导入失败,多个实例");
		createCell = row6.createCell(column + 1);
		this.setColor(workbook,249,203,77,createCell);

		Row row7 = sheet.getRow(7);
		if (row7 == null) {
			row7 = sheet.createRow(7);
		}
		createCell = row7.createCell(column);
		createCell.setCellValue("导入失败,设备不存在");
		createCell = row7.createCell(column + 1);
		this.setColor(workbook,153,225,77,createCell);

		Row row8 = sheet.getRow(8);
		if (row8 == null) {
			row8 = sheet.createRow(8);
		}
		createCell = row8.createCell(column);
		createCell.setCellValue("导入失败,识别码值为空");
		createCell = row8.createCell(column + 1);
		this.setColor(workbook,252,255,77,createCell);

		Row row9 = sheet.getRow(9);
		if (row9 == null) {
			row9 = sheet.createRow(9);
		}
		createCell = row9.createCell(column);
		createCell.setCellValue("导入失败,输入类型与字典定义不一致");
		createCell = row9.createCell(column + 1);
		this.setColor(workbook,155,227,255,createCell);

		Row row10 = sheet.getRow(10);
		if (row10 == null) {
			row10 = sheet.createRow(10);
		}
		createCell = row10.createCell(column);
		createCell.setCellValue("导入失败,未支持的输入类型");
		createCell = row10.createCell(column + 1);
		this.setColor(workbook,204,99,233,createCell);

		Row row11 = sheet.getRow(11);
		if (row11 == null) {
			row11 = sheet.createRow(11);
		}
		createCell = row11.createCell(column);
		createCell.setCellValue("导入失败,信息点不存在");
		createCell = row11.createCell(column + 1);
		this.setColor(workbook,77,178,255,createCell);

		Row row12 = sheet.getRow(12);
		if (row12 == null) {
			row12 = sheet.createRow(12);
		}
		createCell = row12.createCell(column);
		createCell.setCellValue("导入失败,设备类型不在字典定义中");
		createCell = row12.createCell(column + 1);
		this.setColor(workbook,56,94,15,createCell);
	}

	/**
	 * 组装需要导出的设备信息点
	 * @param groupCode
	 * @param projectId
	 * @return
	 */
    private List<EquipmentPointExcel> dealEquipmentPoint(String groupCode,String projectId, String type, Boolean withBuilding, String buildingId){
		InstanceUrlParam context = AdmContextUtil.toDmpContext();
    	if(StrUtil.isAllNotEmpty(groupCode,projectId)){
			// 结果封装
			List<EquipmentPointExcel> excelList = new ArrayList<EquipmentPointExcel>();
			/** 统计项目设备类型 */
			RequestData requestData = new RequestData();
			requestData.setProjectId(projectId);
			requestData.setGroupCode(groupCode);
			requestData.setObjType(AdmEquipment.OBJ_TYPE);
			requestData.setObjTypes(CollUtil.newHashSet(AdmEquipment.OBJ_TYPE));
			List<Map<String, Object>> equipTypeList = DigitalObjectSimpleFacade.queryDefineInfoByObjType(groupCode,projectId,null,null,requestData);
			/** 统计信息不为空继续 */
			if (equipTypeList.size() > 0 ) {
				for(int i = 0; i < equipTypeList.size(); i++){
					AdmDictQueryCriteria admQueryCriteriaInfo = new AdmDictQueryCriteria();
					/** 是否查询静态信息点 */
					if (type.equals("static")){
						admQueryCriteriaInfo.addFilters("category = 'STATIC'");
					} else {
						admQueryCriteriaInfo.addFilters("category != 'STATIC'");
					}
					admQueryCriteriaInfo.addFilters("valid = 1 ");
					admQueryCriteriaInfo.addFilters("classCode = '" + equipTypeList.get(i).get("code").toString() + "'");

					AdmQueryCriteria admQueryCriteriaEquip = new AdmQueryCriteria();
					admQueryCriteriaEquip.addFilters("classCode = '" + equipTypeList.get(i).get("code").toString() + "'");
					admQueryCriteriaEquip.addFilters("not infos isnull");
					admQueryCriteriaEquip.setName(AdmEquipment.OBJ_TYPE);
					if(withBuilding){
						if(StrUtil.isNotEmpty(buildingId)){
							admQueryCriteriaEquip.addFilters("buildingId = '"+buildingId+"'");
						}else{
							admQueryCriteriaEquip.addFilters("buildingId isnull");
						}
					}
					AdmResponse eqResponse = service.query(admQueryCriteriaEquip);
					List<AdmEquipment> equipmentList = (List<AdmEquipment>) eqResponse.getContent();
					if (equipmentList.size() > 0) {
						/** 字典信息点 */
						//AdmResponse responseDic = dictService.query(context, admQueryCriteriaInfo, AdmDictConstant.CLASS_CODE, AdmObjectInfo.class);
						//List<AdmObjectInfo> defFuncIdList = (List<AdmObjectInfo>) responseDic.getContent();
						QueryCriteria queryCriteria = AdmQueryCriteriaHelper.toDmpCriteria(admQueryCriteriaInfo);
						queryCriteria.setOnlyCount(false);
						List<ObjectInfoDefine> defFuncIdList = DigitalObjectInfoFacade.query(AdmContextUtil.toDmpContext().getGroupCode(), AdmContextUtil.toDmpContext().getProjectId(), AdmCommonConstant.APP_ID,null,queryCriteria);

						if (defFuncIdList.size() > 0) {
							Map mapInfo = new HashMap<String,String>();
							Map mapInputType = new HashMap<String,String>();
							Map mapInputFirstName = new HashMap<String,String>();
							for (ObjectInfoDefine defFuncId : defFuncIdList) {
								if(StrUtil.isEmpty(defFuncId.getCode())){
									continue;
								}
								mapInfo.put(defFuncId.getCode(),defFuncId.getName());
								if(StrUtil.isNotEmpty(defFuncId.getDataType())){
									mapInputType.put(defFuncId.getCode(), defFuncId.getDataType());
								}
								if(StrUtil.isNotEmpty(defFuncId.getFirstTag())){
									mapInputFirstName.put(defFuncId.getCode(),defFuncId.getFirstTag());
								}
							}
							for (AdmEquipment equipment : equipmentList) {
								if(CollUtil.isEmpty(equipment.getInfos())){
									continue;
								}
								Map<String, Object> info = equipment.getInfos();
								for(String key : info.keySet()){
									if(info.get(key) != null && StrUtil.isNotEmpty(info.get(key).toString())){
										boolean containsKey = mapInfo.containsKey(key);
										if(!containsKey){
											continue;
										}
										/** 处理数据写入文件 */
										EquipmentPointExcel excel = new EquipmentPointExcel();
										/** id */
										excel.setId(equipment.getId());
										/** 本地编码 */
										excel.setLocalId(equipment.getLocalId());
										/** 本地名称 */
										excel.setLocalName(equipment.getLocalName());
										/** 类型 */
										excel.setClassCode(equipment.getClassCode());
										/** 类型 */
										excel.setClassCodeName(equipTypeList.get(i).get("name").toString());
										/** 一级标签 */
										boolean containsFirstName = mapInputFirstName.containsKey(key);
										if (containsFirstName) {
											/** 一级标签 */
											excel.setMapInputFirstName(mapInputFirstName.get(key).toString());
										}
										/** 信息点名 */
										excel.setInfoName(mapInfo.get(key).toString());
										/** 信息点 */
										excel.setInfoCode(key);
										boolean containsInputType = mapInputType.containsKey(key);
										if (containsInputType) {
											/** 输入类型 */
											excel.setInputType(mapInputType.get(key).toString());
										}
										/** 值 */
										excel.setInputValue(info.get(key).toString());
										excelList.add(excel);
									}
								}
							}
						}
					}
				}
			}
			return excelList;
		}else{
    		return null;
		}
	}
}
