AdmEquipmentController.java 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. package com.persagy.proxy.object.controller;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.io.IoUtil;
  6. import cn.hutool.core.map.MapUtil;
  7. import cn.hutool.core.util.IdUtil;
  8. import cn.hutool.core.util.StrUtil;
  9. import cn.hutool.json.JSONUtil;
  10. import cn.hutool.poi.excel.ExcelReader;
  11. import cn.hutool.poi.excel.ExcelUtil;
  12. import cn.hutool.poi.excel.RowUtil;
  13. import cn.hutool.poi.excel.WorkbookUtil;
  14. import cn.hutool.poi.excel.cell.CellUtil;
  15. import cn.hutool.poi.excel.editors.TrimEditor;
  16. import com.alibaba.excel.EasyExcel;
  17. import com.alibaba.excel.ExcelWriter;
  18. import com.alibaba.excel.write.metadata.WriteSheet;
  19. import com.fasterxml.jackson.databind.node.ObjectNode;
  20. import com.persagy.dmp.basic.dto.RequestData;
  21. import com.persagy.dmp.basic.model.QueryCriteria;
  22. import com.persagy.dmp.common.constant.CommonConstant;
  23. import com.persagy.dmp.common.constant.ResponseCode;
  24. import com.persagy.dmp.common.context.AppContext;
  25. import com.persagy.dmp.common.exception.BusinessException;
  26. import com.persagy.dmp.common.model.response.CommonResult;
  27. import com.persagy.dmp.define.client.DigitalObjectInfoFacade;
  28. import com.persagy.dmp.define.entity.ObjectInfoDefine;
  29. import com.persagy.dmp.define.entity.ObjectTypeDefine;
  30. import com.persagy.dmp.digital.client.DigitalObjectFacade;
  31. import com.persagy.dmp.simple.client.DigitalObjectSimpleFacade;
  32. import com.persagy.proxy.adm.constant.AdmCommonConstant;
  33. import com.persagy.proxy.adm.constant.AdmDictCategoryEnum;
  34. import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
  35. import com.persagy.proxy.adm.request.*;
  36. import com.persagy.proxy.adm.service.IAdmRelationService;
  37. import com.persagy.proxy.adm.utils.AdmContextUtil;
  38. import com.persagy.proxy.adm.utils.AdmExcelUtil;
  39. import com.persagy.proxy.adm.utils.AdmQueryCriteriaHelper;
  40. import com.persagy.proxy.adm.utils.ObjectNameUtil;
  41. import com.persagy.proxy.common.entity.InstanceUrlParam;
  42. import com.persagy.proxy.common.entity.RelationDTO;
  43. import com.persagy.proxy.dictionary.model.AdmDict;
  44. import com.persagy.proxy.dictionary.model.AdmObjectType;
  45. import com.persagy.proxy.dictionary.service.IAdmDictService;
  46. import com.persagy.proxy.object.model.AdmEquipment;
  47. import com.persagy.proxy.object.model.AdmProject;
  48. import com.persagy.proxy.object.model.AdmSystem;
  49. import com.persagy.proxy.object.service.IAdmEquipmentService;
  50. import com.persagy.proxy.object.service.IAdmProjectService;
  51. import com.persagy.proxy.report.model.EquipmentPointExcel;
  52. import com.persagy.proxy.report.service.IRelationReportService;
  53. import lombok.extern.slf4j.Slf4j;
  54. import org.apache.poi.ss.usermodel.*;
  55. import org.apache.poi.xssf.usermodel.XSSFCellStyle;
  56. import org.apache.poi.xssf.usermodel.XSSFColor;
  57. import org.springframework.beans.factory.annotation.Autowired;
  58. import org.springframework.web.bind.annotation.*;
  59. import org.springframework.web.multipart.MultipartFile;
  60. import javax.servlet.http.HttpServletRequest;
  61. import javax.servlet.http.HttpServletResponse;
  62. import java.awt.Color;
  63. import java.io.FileOutputStream;
  64. import java.io.IOException;
  65. import java.net.URLEncoder;
  66. import java.nio.charset.StandardCharsets;
  67. import java.util.List;
  68. import java.util.*;
  69. import java.util.stream.Collectors;
  70. /**
  71. * Adm 楼层 API
  72. * @author lvxy
  73. * @date 2021/8/16
  74. */
  75. @Slf4j
  76. @RestController
  77. @RequestMapping("/object/equip")
  78. public class AdmEquipmentController {
  79. @Autowired
  80. private IAdmEquipmentService service;
  81. @Autowired
  82. private IAdmRelationService relationService;
  83. @Autowired
  84. private IRelationReportService relationReportService;
  85. @Autowired
  86. private IAdmDictService dictService;
  87. @Autowired
  88. private IAdmProjectService projectService;
  89. /**
  90. * 统计
  91. *
  92. * @param request
  93. * @return
  94. * @throws Exception
  95. */
  96. @PostMapping("/count")
  97. public AdmResponse count(@RequestBody AdmQueryCriteria request) throws Exception {
  98. request.setName(AdmEquipment.OBJ_TYPE);
  99. request.setOnlyCount(true);
  100. return service.query(request);
  101. }
  102. /**
  103. * 创建
  104. * @param createRequest
  105. * @return
  106. * @throws Exception
  107. */
  108. @PostMapping("/create")
  109. public AdmCreateResponse create(@RequestBody AdmCreateRequest<AdmEquipment> createRequest) throws Exception {
  110. List<AdmEquipment> vos = CollUtil.newArrayList(createRequest.getContent());
  111. if(CollUtil.isEmpty(vos)){
  112. return AdmCreateResponse.success();
  113. }
  114. // 查询所有设备类型
  115. AdmDict dictCond = AdmDict.builder().type(AdmDictCategoryEnum.EQUIPMENT.getValue()).build();
  116. AdmResponse dictResponse = dictService.queryCategory(AdmContextUtil.toDmpContext(), dictCond, AdmObjectType.class);
  117. List<AdmObjectType> dicts = (List<AdmObjectType>) dictResponse.getContent();
  118. // 转换为Map,key为编码后4位。用于适配旧类型编码
  119. Map<String, AdmObjectType> shortDictMap = new HashMap<>();
  120. Map<String, AdmObjectType> fullDictMap = new HashMap<>();
  121. for(int i = 0,j = CollUtil.size(dicts);i < j;i++) {
  122. AdmObjectType dict = dicts.get(i);
  123. shortDictMap.put(StrUtil.subSufByLength(dict.getCode(), 4), dict);
  124. fullDictMap.put(dict.getCode(), dict);
  125. }
  126. // 设备属性调整
  127. List<AdmEquipment> filterVOs = new ArrayList<>();
  128. for(AdmEquipment equipment:vos) {
  129. // 如果不是Eq开头,则重新生成ID
  130. if(StrUtil.startWith(equipment.getId(), "Eq")) {
  131. equipment.setId("Eq"+ IdUtil.simpleUUID());
  132. }
  133. // 类型编码适配
  134. String classCode = equipment.getClassCode();
  135. // 如果编码为空,或在4位、6位里都不存在,则报错
  136. if(StrUtil.isBlank(classCode) ||
  137. (shortDictMap.get(classCode) == null && fullDictMap.get(classCode) == null)) {
  138. log.error(StrUtil.format("没有找到对象类型【{}】!", equipment.getClassCode()));
  139. continue;
  140. }
  141. filterVOs.add(equipment);
  142. // 如果少于6位,则需要适配新编码
  143. if(classCode.length() < 6) {
  144. AdmObjectType dict = MapUtil.get(shortDictMap, classCode, AdmObjectType.class);
  145. equipment.setClassCode(dict.getCode());
  146. }
  147. // 如果名称为空,则提供默认名称
  148. if (StrUtil.isEmpty(equipment.getName())){
  149. AdmObjectType dict = MapUtil.get(fullDictMap, equipment.getClassCode(), AdmObjectType.class);
  150. String preName = dict == null ? "设备" : dict.getName();
  151. equipment.setName(ObjectNameUtil.objectName(preName + "-"));
  152. }
  153. }
  154. if(CollUtil.isEmpty(filterVOs)){
  155. return AdmCreateResponse.success();
  156. }
  157. filterVOs = service.doInsert(AdmContextUtil.toDmpContext(), AdmEquipment.class, filterVOs);
  158. return AdmCreateResponse.success(filterVOs);
  159. }
  160. /**
  161. * 根据ID删除
  162. * @param vos
  163. * @return
  164. * @throws Exception
  165. */
  166. @PostMapping("/delete")
  167. public AdmResponse delete( @RequestBody List<AdmEquipment> vos) throws Exception {
  168. // 组装上下文条件
  169. service.doDelete(AdmContextUtil.toDmpContext(), vos);
  170. return AdmResponse.success();
  171. }
  172. /**
  173. * 更新
  174. * @param createRequest
  175. * @return
  176. * @throws Exception
  177. */
  178. @PostMapping("/update")
  179. public AdmResponse update(@RequestBody AdmCreateRequest<AdmEquipment> createRequest) throws Exception {
  180. List<AdmEquipment> vos = createRequest.getContent();
  181. if(CollUtil.isEmpty(vos)) {
  182. return AdmResponse.success(vos);
  183. }
  184. for(AdmEquipment vo:vos) {
  185. if(StrUtil.isNotBlank(vo.getFlowBuild())) {
  186. // 处理建筑-楼层信息点
  187. List<String> flows = StrUtil.splitTrim(vo.getFlowBuild(), "-");
  188. for(String flow:flows) {
  189. if(StrUtil.startWith(flow, "Bd")) {
  190. vo.setBuildingId(flow);
  191. } else if(StrUtil.startWith(flow, "fl")) {
  192. vo.setFloorId(flow);
  193. }
  194. }
  195. vo.setFlowBuild(null);
  196. }
  197. }
  198. vos = service.doUpdate(AdmContextUtil.toDmpContext(), AdmEquipment.class, vos);
  199. return AdmResponse.success(vos);
  200. }
  201. /**
  202. * 查询
  203. *
  204. * @param request
  205. * @return
  206. * @throws Exception
  207. */
  208. @PostMapping("/query")
  209. public AdmResponse query(@RequestBody AdmQueryCriteria request) throws Exception {
  210. // 组装上下文条件
  211. request.setName(AdmEquipment.OBJ_TYPE);
  212. if(CollUtil.isEmpty(request.getCascade()) && CollUtil.isNotEmpty(request.getProjection()) && request.getDistinct() != null && request.getDistinct() && request.getProjection().size() == 1 && request.getProjection().get(0).equals("classCode")) {
  213. /** 特殊处理
  214. * distinct: true
  215. * pageNumber: 1
  216. * pageSize: 1000
  217. * projection: ["classCode"]
  218. * 0: "classCode"
  219. */
  220. RequestData requestData = new RequestData();
  221. requestData.setProjection(request.getProjection());
  222. requestData.setObjType(AdmEquipment.OBJ_TYPE);
  223. requestData.setPage(request.getPageNumber().longValue());
  224. requestData.setSize(request.getPageSize().longValue());
  225. CommonResult<List<ObjectNode>> result = DigitalObjectSimpleFacade.queryObjListByConditions(AdmContextUtil.toDmpContext().getGroupCode(), AdmContextUtil.toDmpContext().getProjectId(), AdmContextUtil.toDmpContext().getAppId(), null, requestData);
  226. if (result == null || CollUtil.isEmpty(result.getData())) {
  227. return AdmResponse.success();
  228. }else{
  229. List<AdmEquipment> admEquipments = JSONUtil.toList(result.getData().toString(), AdmEquipment.class);
  230. service.ensureSpecialValues(AdmContextUtil.toDmpContext(), admEquipments);
  231. return AdmResponse.success(admEquipments, request);
  232. }
  233. }else{
  234. return service.query(request);
  235. }
  236. }
  237. /**
  238. * 设备绑定的动态信息点或静态信息点
  239. * @param type 数据类型 static (静态)、iot (动态)
  240. * @return
  241. * @throws Exception
  242. */
  243. @GetMapping("/export")
  244. public void exportInfos(@RequestParam("type") String type, @RequestParam("projectId") String projectId, HttpServletResponse response) throws Exception {
  245. try {
  246. response.setContentType("application/vnd.ms-excel");
  247. String encode = StandardCharsets.UTF_8.name();
  248. response.setCharacterEncoding(encode);
  249. AdmQueryCriteria projectRequest = new AdmQueryCriteria();
  250. projectRequest.setName(AdmProject.OBJ_TYPE);
  251. projectRequest.setFilters("id = '" + projectId + "';");
  252. AdmResponse responsePro = projectService.doQuery(AdmContextUtil.toDmpContext(), projectRequest, AdmProject.class);
  253. if (CollUtil.isEmpty(responsePro.getContent())) {
  254. throw new BusinessException(ResponseCode.A0402.getCode(), ResponseCode.A0402.getDesc());
  255. } else {
  256. AdmProject admProject = (AdmProject) responsePro.getContent().get(0);
  257. // 防止中文乱码
  258. String fileName = admProject.getLocalName() + "设备已交付信息点";
  259. fileName = URLEncoder.encode(fileName, encode);
  260. response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
  261. List<EquipmentPointExcel> equipmentPointExcels = dealEquipmentPoint(admProject.getGroupCode(),admProject.getId(),type, false, null);
  262. int count = equipmentPointExcels.size();
  263. if(count > 100000){
  264. ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), EquipmentPointExcel.class).build();
  265. try {
  266. WriteSheet writeSheet = EasyExcel.writerSheet(0, "sheet1").build();
  267. excelWriter.write(equipmentPointExcels.subList(0,100000), writeSheet);
  268. WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "sheet2").build();
  269. excelWriter.write(equipmentPointExcels.subList(100000,count), writeSheet2);
  270. } finally {
  271. if (excelWriter != null) {
  272. excelWriter.finish();
  273. }
  274. }
  275. }else{
  276. EasyExcel.write(response.getOutputStream(), EquipmentPointExcel.class).sheet("sheet1").doWrite(equipmentPointExcels);
  277. }
  278. }
  279. }catch (Exception e){
  280. log.error("设备数据导出异常,获取项目失败",e);
  281. }
  282. }
  283. /**
  284. * 根据建筑 查询设备绑定的动态信息点或静态信息点
  285. * @param type 数据类型 static (静态)、iot (动态)
  286. */
  287. @GetMapping("/export/bulidng")
  288. public void equipInfosTwo(@RequestParam("type") String type, @RequestParam("projectId") String projectId, HttpServletResponse response,@RequestParam("buildingId") String buildingId) {
  289. try {
  290. response.setContentType("application/vnd.ms-excel");
  291. String encode = StandardCharsets.UTF_8.name();
  292. response.setCharacterEncoding(encode);
  293. AdmQueryCriteria projectRequest = new AdmQueryCriteria();
  294. projectRequest.setName(AdmProject.OBJ_TYPE);
  295. projectRequest.setFilters("id = '" + projectId + "';");
  296. AdmResponse responsePro = projectService.doQuery(AdmContextUtil.toDmpContext(), projectRequest, AdmProject.class);
  297. if (CollUtil.isEmpty(responsePro.getContent())) {
  298. throw new BusinessException(ResponseCode.A0402.getCode(), ResponseCode.A0402.getDesc());
  299. } else {
  300. AdmProject admProject = (AdmProject) responsePro.getContent().get(0);
  301. // 防止中文乱码
  302. String fileName = admProject.getLocalName() + "设备已交付信息点";
  303. fileName = URLEncoder.encode(fileName, encode);
  304. response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
  305. List<EquipmentPointExcel> equipmentPointExcels = dealEquipmentPoint(admProject.getGroupCode(),admProject.getId(),type, true, buildingId);
  306. EasyExcel.write(response.getOutputStream(), EquipmentPointExcel.class).sheet("sheet1").doWrite(equipmentPointExcels);
  307. }
  308. }catch (Exception e){
  309. log.error("设备数据导出异常,获取项目失败",e);
  310. }
  311. }
  312. /**
  313. * 根据项目id查询所有的设备和部件
  314. *
  315. * @param request
  316. * @return
  317. * @throws Exception
  318. */
  319. @GetMapping("/query-equip")
  320. public AdmResponse queryEquip(@RequestBody AdmQueryCriteria request) throws Exception {
  321. //request.setName("equipment");
  322. if(StrUtil.isNotEmpty(request.getFilters())){
  323. request.setFilters(String.join(";",request.getFilters(),"objType in ['equipment','component']"));
  324. }else{
  325. request.setFilters("objType in ['equipment','component']");
  326. }
  327. return service.query(request);
  328. }
  329. /**
  330. * 批量创建设备同时创建资产、创建设备和系统的关系
  331. * @param admEquipment
  332. * @return
  333. * @throws Exception
  334. */
  335. @PostMapping("/creat-equip-pro")
  336. public AdmCreateResponse createExt(@RequestBody AdmCreateRequest<AdmEquipment> admEquipment) throws Exception {
  337. List<AdmEquipment> vos = admEquipment.getContent();
  338. if(CollUtil.isEmpty(vos)){
  339. return AdmCreateResponse.success();
  340. }
  341. // 这里应该要移到实现类里
  342. List<RelationDTO> relationDTOS = new ArrayList<>(16);
  343. for(AdmEquipment vo:vos) {
  344. if (StrUtil.isBlank(vo.getId())){
  345. vo.setId(AdmContextUtil.generateIdStr("Eq",true));
  346. }
  347. if (StrUtil.isEmpty(vo.getName())){
  348. vo.setName(ObjectNameUtil.objectName("设备-"));
  349. }
  350. List<AdmSystem> systems = vo.getLinkSystem();
  351. if(CollUtil.isNotEmpty(systems)){
  352. for(AdmSystem system:systems) {
  353. relationDTOS.add(new RelationDTO(StrUtil.format(CommonConstant.DEFAULT_GRAPH_ID_FORMAT,
  354. AdmRelationTypeEnum.EQ2SY.getGraphCode()), AdmRelationTypeEnum.EQ2SY.getGraphCode(),
  355. AdmRelationTypeEnum.EQ2SY.getRelCode(), null , system.getId(), vo.getId()));
  356. }
  357. }
  358. }
  359. if (CollUtil.isNotEmpty(relationDTOS)){
  360. relationService.doSave(AdmContextUtil.toDmpContext(),relationDTOS);
  361. }
  362. vos = service.doInsert(AdmContextUtil.toDmpContext(), AdmEquipment.class, vos);
  363. return AdmCreateResponse.success(vos);
  364. }
  365. /**
  366. * 设备上传excel识别静态信息点
  367. *
  368. * @param file
  369. * @param request
  370. * @param response
  371. */
  372. @RequestMapping("/import")
  373. public AdmResponse importFile(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
  374. if (file == null) {
  375. return AdmResponse.failure("未选择文件");
  376. }
  377. String path = AdmCommonConstant.SERVER_ROOT_PATH + AdmExcelUtil.TEMP_UPLOAD_PAHT;
  378. int failurNum = 0;
  379. int successCount = 0;
  380. String failure = null;
  381. String primaryKey = null;
  382. String classCodeCloumn = null;
  383. Workbook workbook = null;
  384. FileOutputStream fileOutputStream = null;
  385. String groupCode = AppContext.getContext().getGroupCode();
  386. String projectId = AppContext.getContext().getProjectId();
  387. try {
  388. byte[] bytes = IoUtil.readBytes(file.getInputStream());
  389. workbook = WorkbookUtil.createBook(IoUtil.toStream(bytes));
  390. Sheet sheet = WorkbookUtil.getOrCreateSheet(workbook, 0);
  391. Row row1 = RowUtil.getOrCreateRow(sheet, 1);
  392. /** 获取识别码 */
  393. Cell markCell = CellUtil.getCell(row1, 0);
  394. if (markCell == null) {
  395. AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  396. return AdmExcelUtil.getImportFailResult("未填写识别码", "2", 0, ++failurNum);
  397. }
  398. primaryKey = StrUtil.toString(CellUtil.getCellValue(markCell,true)); // 识别码
  399. if (!AdmCommonConstant.codeColMap.containsKey(primaryKey)) {
  400. AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  401. return AdmExcelUtil.getImportFailResult("未找到识别码", "2", 0, ++failurNum);
  402. }
  403. primaryKey = AdmCommonConstant.codeColMap.get(primaryKey);
  404. /** 获取类型 */
  405. Cell cell = CellUtil.getCell(row1,1);
  406. if (cell == null) {
  407. AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  408. return AdmExcelUtil.getImportFailResult("未填写设备类型", "2", 0, ++failurNum);
  409. }
  410. classCodeCloumn = cell.getStringCellValue().trim();
  411. if (!"ClassCode".equals(classCodeCloumn)) {
  412. AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  413. return AdmExcelUtil.getImportFailResult("缺少设备类型(ClassCode)", "2", 0, ++failurNum);
  414. }
  415. // 写入错误报告对比值颜色
  416. this.wirteReport(workbook, sheet);
  417. // 存取所有的信息点
  418. Map<Integer, String> infoMap = new HashMap<>();
  419. List<Object> row1List = RowUtil.readRow(row1, new TrimEditor());
  420. for (int i = 1; i < row1List.size(); i++) {
  421. infoMap.put(i,StrUtil.toString(row1List.get(i)));
  422. }
  423. boolean isClassCode = "classCode".equals(primaryKey);
  424. ExcelReader excelReader = ExcelUtil.getReader(IoUtil.toStream(bytes), 0);
  425. List<List<Object>> listList = excelReader.read();
  426. // 1.存储设备类型code
  427. Set<String> classCodes = CollUtil.newHashSet();
  428. // 2.存储primaryKey对应的值
  429. Set<String> primaryMess = CollUtil.newHashSet();
  430. for (int i = 2; i < listList.size(); i++) {
  431. List<Object> objects = listList.get(i);
  432. if (CollUtil.isEmpty(objects)){
  433. continue;
  434. }
  435. if (null==objects.get(0) || StrUtil.isBlank(StrUtil.toString(objects.get(0)))){
  436. this.setColor(workbook, 252, 255, 77,
  437. CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(sheet,i),0));
  438. continue;
  439. }
  440. if (!isClassCode && (null==objects.get(1) || StrUtil.isBlank(StrUtil.toString(objects.get(1))))){
  441. // 第一个cell为空或者非classCode上传并且第二个cell为空
  442. this.setColor(workbook, 252, 255, 77,
  443. CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(sheet,i),0));
  444. continue;
  445. }
  446. if (isClassCode){
  447. classCodes.add(StrUtil.toString(objects.get(0)));
  448. continue;
  449. }
  450. classCodes.add(StrUtil.toString(objects.get(1)));
  451. primaryMess.add(StrUtil.toString(objects.get(0)));
  452. }
  453. if (isClassCode && CollUtil.isEmpty(classCodes)){
  454. // 设备类型code集合为空
  455. String fileName = AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  456. return AdmExcelUtil.getImportSuccessResult(fileName, successCount, listList.size());
  457. }
  458. if (!isClassCode && (CollUtil.isEmpty(primaryMess) || CollUtil.isEmpty(classCodes))){
  459. // 设备类型code集合或唯一标识为空
  460. String fileName = AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  461. return AdmExcelUtil.getImportSuccessResult(fileName, successCount, listList.size());
  462. }
  463. // 1.根据设备类型code集合查询定义
  464. Map<String,ObjectTypeDefine> defineMap = relationReportService.queryDefineTypeMapByClassCodes(classCodes);
  465. // 2.根据设备类型code集合查询设备类的信息点
  466. Map<String,List<ObjectInfoDefine>> defineInfoMap = relationReportService.queryDefineInfoMapByClassCodes(classCodes);
  467. // 3.根据是否根据设备类型code上传来区分处理
  468. Map<String,List<ObjectNode>> objectDigitalMap = CollUtil.newHashMap();
  469. if (isClassCode){
  470. objectDigitalMap=relationReportService.queryEquipsByClassCodes(classCodes);
  471. }else {
  472. objectDigitalMap=relationReportService.queryEquipsByConditions(primaryKey,primaryMess,classCodes);
  473. }
  474. List<ObjectNode> updateObjs = new ArrayList<>();
  475. ObjectNode equipment = null;
  476. List<ObjectNode> equipmentList = null;
  477. for (int i = 2; i < listList.size(); i++) {
  478. List<Object> objects = listList.get(i);
  479. if (CollUtil.isEmpty(objects)){
  480. continue;
  481. }
  482. if ((null==objects.get(0) || StrUtil.isBlank(StrUtil.toString(objects.get(0))))
  483. || (!isClassCode && (null==objects.get(1) || StrUtil.isBlank(StrUtil.toString(objects.get(1)))))){
  484. failurNum++;
  485. continue;
  486. }
  487. String classCode = isClassCode?StrUtil.toString(objects.get(0)):StrUtil.toString(objects.get(1));
  488. if (!defineMap.containsKey(classCode)){
  489. failurNum++;
  490. this.setColor(workbook, 56, 94, 15, CellUtil.getCell(RowUtil.getOrCreateRow(sheet, i), isClassCode?0:1));
  491. continue;
  492. }
  493. classCode = defineMap.get(classCode).getCode();
  494. equipmentList = isClassCode ? objectDigitalMap.get(classCode)
  495. : objectDigitalMap.get(StrUtil.toString(objects.get(0)) + StrUtil.UNDERLINE + classCode);
  496. if (CollectionUtil.isEmpty(equipmentList)) {
  497. failurNum++;
  498. this.setColor(workbook, 153, 225, 77, CellUtil.getCell(RowUtil.getOrCreateRow(sheet, i), 0));
  499. continue;
  500. }
  501. if (isClassCode) {
  502. equipment = equipmentList.get(0);
  503. } else {
  504. if (equipmentList.size() > 1) {
  505. failurNum++;
  506. this.setColor(workbook, 249, 203, 77, CellUtil.getCell(RowUtil.getOrCreateRow(sheet, i), 1));
  507. continue;
  508. } else {
  509. equipment = equipmentList.get(0);
  510. }
  511. }
  512. boolean changeFlag = true;
  513. for (int j = 2; j < objects.size(); j++) {
  514. // 剩余列数据处理
  515. if (!infoMap.containsKey(j)) {
  516. continue;
  517. }
  518. Cell tempCell = CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(sheet, i), j);
  519. // 如果值为空直接跳过
  520. if (StrUtil.isBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))){
  521. continue;
  522. }
  523. // 获取设备类的信息点
  524. String code = infoMap.get(j);
  525. List<ObjectInfoDefine> funidList = defineInfoMap.getOrDefault(classCode,new ArrayList<>())
  526. .stream().filter(func->code.equals(func.getAliasCode()) && "STATIC".equals(func.getCategory()))
  527. .collect(Collectors.toList());
  528. if (CollectionUtil.isEmpty(funidList)) {
  529. failurNum++;
  530. this.setColor(workbook, 77, 178, 255, tempCell);
  531. changeFlag=false;
  532. continue;
  533. }
  534. ObjectInfoDefine define = funidList.get(0);
  535. if ("STRING".equalsIgnoreCase(define.getDataType())) {
  536. tempCell.setCellType(CellType.STRING);
  537. equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
  538. } else if ("INTEGER".equalsIgnoreCase(define.getDataType())) {
  539. try {
  540. if (!CellType.NUMERIC.equals(tempCell.getCellTypeEnum())
  541. || StrUtil.isBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))) {
  542. failurNum++;
  543. this.setColor(workbook, 155, 227, 255, tempCell);
  544. changeFlag=false;
  545. continue;
  546. }
  547. tempCell.setCellType(CellType.STRING);
  548. equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
  549. } catch (Exception e) {
  550. failurNum++;
  551. this.setColor(workbook, 155, 227, 255, tempCell);
  552. changeFlag=false;
  553. continue;
  554. }
  555. } else if ("ENUM".equalsIgnoreCase(define.getDataType())) {
  556. if (CellType.NUMERIC.equals(tempCell.getCellTypeEnum())
  557. && StrUtil.isNotBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))) {
  558. tempCell.setCellType(CellType.STRING);
  559. equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
  560. } else if (CellType.STRING.equals(tempCell.getCellTypeEnum())
  561. && StrUtil.isNotBlank(StrUtil.toString(CellUtil.getCellValue(tempCell,true)))) {
  562. equipment.put(define.getCode(), tempCell.getStringCellValue().trim());
  563. } else {
  564. failurNum++;
  565. this.setColor(workbook, 155, 227, 255, tempCell);
  566. changeFlag=false;
  567. continue;
  568. }
  569. } else if ("DATETIME".equalsIgnoreCase(define.getDataType())) {
  570. try {
  571. tempCell.setCellType(CellType.STRING);
  572. String trim = tempCell.getStringCellValue().trim();
  573. DateUtil.parseByPatterns(trim, "yyyyMMdd");
  574. equipment.put(define.getCode(), trim);
  575. } catch (Exception e) {
  576. failurNum++;
  577. this.setColor(workbook, 155, 227, 255, tempCell);
  578. changeFlag=false;
  579. continue;
  580. }
  581. } else if ("DOUBLE".equalsIgnoreCase(define.getDataType())) {
  582. try {
  583. tempCell.setCellType(CellType.STRING);
  584. String trim = tempCell.getStringCellValue().trim();
  585. equipment.put(define.getCode(), Double.parseDouble(trim));
  586. } catch (Exception e) {
  587. failurNum++;
  588. this.setColor(workbook, 155, 227, 255, tempCell);
  589. changeFlag=false;
  590. continue;
  591. }
  592. } else if ("BOOLEAN".equalsIgnoreCase(define.getDataType())) {
  593. tempCell.setCellType(CellType.STRING);
  594. String trim = tempCell.getStringCellValue() == null ? null : tempCell.getStringCellValue().trim();
  595. if ("1".equals(trim) || "0".equals(trim)) {
  596. equipment.put(define.getCode(), Double.parseDouble(trim));
  597. } else {
  598. failurNum++;
  599. this.setColor(workbook, 155, 227, 255, tempCell);
  600. changeFlag=false;
  601. continue;
  602. }
  603. } else {
  604. failurNum++;
  605. this.setColor(workbook, 204, 99, 233, tempCell);
  606. changeFlag=false;
  607. continue;
  608. }
  609. }
  610. if (changeFlag){
  611. updateObjs.add(equipment);
  612. }
  613. }
  614. // 5.更新对象数据
  615. if (CollUtil.isNotEmpty(updateObjs)){
  616. successCount=updateObjs.size();
  617. DigitalObjectFacade.update(AppContext.getContext().getGroupCode(),
  618. AppContext.getContext().getProjectId(),
  619. AppContext.getContext().getAppId(),
  620. AppContext.getContext().getAccountId(),
  621. updateObjs);
  622. }
  623. // 设备类型code集合或唯一标识为空
  624. String fileName = AdmExcelUtil.writeFile2Local(workbook, projectId, path, file.getOriginalFilename());
  625. return AdmExcelUtil.getImportSuccessResult(fileName, successCount, failurNum);
  626. } catch (Exception e) {
  627. log.error("台账信息导入失败", e);
  628. failure = e.getMessage();
  629. } finally {
  630. if (fileOutputStream != null) {
  631. try {
  632. fileOutputStream.flush();
  633. fileOutputStream.close();
  634. } catch (IOException e) {}
  635. }
  636. if (workbook != null) {
  637. try {
  638. workbook.close();
  639. } catch (IOException e) {}
  640. }
  641. }
  642. return AdmResponse.failure(failure);
  643. }
  644. /**
  645. * 设置填充色
  646. *
  647. * @param workbook
  648. * @param r
  649. * @param g
  650. * @param b
  651. * @param cell
  652. */
  653. private void setColor(Workbook workbook, int r, int g, int b, Cell cell) {
  654. XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
  655. cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  656. cellStyle.setFillForegroundColor(new XSSFColor(new Color(r, g, b)));
  657. cell.setCellStyle(cellStyle);
  658. }
  659. /**
  660. * 写入错误报告对比值颜色
  661. *
  662. * @param workbook
  663. * @param sheet
  664. */
  665. private void wirteReport(Workbook workbook, Sheet sheet) {
  666. Row row = sheet.getRow(1);
  667. short column = (short) (row.getLastCellNum() + 2);
  668. Row row4 = sheet.getRow(4);
  669. if (row4 == null) {
  670. row4 = sheet.createRow(4);
  671. }
  672. Cell createCell = row4.createCell(column);
  673. createCell.setCellValue("导入失败,识别码超出范围(本地编码,设备类型)");
  674. createCell = row4.createCell(column + 1);
  675. this.setColor(workbook,233,99,99,createCell);
  676. Row row5 = sheet.getRow(5);
  677. if (row5 == null) {
  678. row5 = sheet.createRow(5);
  679. }
  680. createCell = row5.createCell(column);
  681. createCell.setCellValue("导入失败,识别码为空");
  682. createCell = row5.createCell(column + 1);
  683. this.setColor(workbook,252,147,77,createCell);
  684. Row row6 = sheet.getRow(6);
  685. if (row6 == null) {
  686. row6 = sheet.createRow(6);
  687. }
  688. createCell = row6.createCell(column);
  689. createCell.setCellValue("导入失败,多个实例");
  690. createCell = row6.createCell(column + 1);
  691. this.setColor(workbook,249,203,77,createCell);
  692. Row row7 = sheet.getRow(7);
  693. if (row7 == null) {
  694. row7 = sheet.createRow(7);
  695. }
  696. createCell = row7.createCell(column);
  697. createCell.setCellValue("导入失败,设备不存在");
  698. createCell = row7.createCell(column + 1);
  699. this.setColor(workbook,153,225,77,createCell);
  700. Row row8 = sheet.getRow(8);
  701. if (row8 == null) {
  702. row8 = sheet.createRow(8);
  703. }
  704. createCell = row8.createCell(column);
  705. createCell.setCellValue("导入失败,识别码值为空");
  706. createCell = row8.createCell(column + 1);
  707. this.setColor(workbook,252,255,77,createCell);
  708. Row row9 = sheet.getRow(9);
  709. if (row9 == null) {
  710. row9 = sheet.createRow(9);
  711. }
  712. createCell = row9.createCell(column);
  713. createCell.setCellValue("导入失败,输入类型与字典定义不一致");
  714. createCell = row9.createCell(column + 1);
  715. this.setColor(workbook,155,227,255,createCell);
  716. Row row10 = sheet.getRow(10);
  717. if (row10 == null) {
  718. row10 = sheet.createRow(10);
  719. }
  720. createCell = row10.createCell(column);
  721. createCell.setCellValue("导入失败,未支持的输入类型");
  722. createCell = row10.createCell(column + 1);
  723. this.setColor(workbook,204,99,233,createCell);
  724. Row row11 = sheet.getRow(11);
  725. if (row11 == null) {
  726. row11 = sheet.createRow(11);
  727. }
  728. createCell = row11.createCell(column);
  729. createCell.setCellValue("导入失败,信息点不存在");
  730. createCell = row11.createCell(column + 1);
  731. this.setColor(workbook,77,178,255,createCell);
  732. Row row12 = sheet.getRow(12);
  733. if (row12 == null) {
  734. row12 = sheet.createRow(12);
  735. }
  736. createCell = row12.createCell(column);
  737. createCell.setCellValue("导入失败,设备类型不在字典定义中");
  738. createCell = row12.createCell(column + 1);
  739. this.setColor(workbook,56,94,15,createCell);
  740. }
  741. /**
  742. * 组装需要导出的设备信息点
  743. * @param groupCode
  744. * @param projectId
  745. * @return
  746. */
  747. private List<EquipmentPointExcel> dealEquipmentPoint(String groupCode,String projectId, String type, Boolean withBuilding, String buildingId){
  748. InstanceUrlParam context = AdmContextUtil.toDmpContext();
  749. if(StrUtil.isAllNotEmpty(groupCode,projectId)){
  750. // 结果封装
  751. List<EquipmentPointExcel> excelList = new ArrayList<EquipmentPointExcel>();
  752. /** 统计项目设备类型 */
  753. RequestData requestData = new RequestData();
  754. requestData.setProjectId(projectId);
  755. requestData.setGroupCode(groupCode);
  756. requestData.setObjType(AdmEquipment.OBJ_TYPE);
  757. requestData.setObjTypes(CollUtil.newHashSet(AdmEquipment.OBJ_TYPE));
  758. List<Map<String, Object>> equipTypeList = DigitalObjectSimpleFacade.queryDefineInfoByObjType(groupCode,projectId,null,null,requestData);
  759. /** 统计信息不为空继续 */
  760. if (equipTypeList.size() > 0 ) {
  761. for(int i = 0; i < equipTypeList.size(); i++){
  762. AdmDictQueryCriteria admQueryCriteriaInfo = new AdmDictQueryCriteria();
  763. /** 是否查询静态信息点 */
  764. if (type.equals("static")){
  765. admQueryCriteriaInfo.addFilters("category = 'STATIC'");
  766. } else {
  767. admQueryCriteriaInfo.addFilters("category != 'STATIC'");
  768. }
  769. admQueryCriteriaInfo.addFilters("valid = 1 ");
  770. admQueryCriteriaInfo.addFilters("classCode = '" + equipTypeList.get(i).get("code").toString() + "'");
  771. AdmQueryCriteria admQueryCriteriaEquip = new AdmQueryCriteria();
  772. admQueryCriteriaEquip.addFilters("classCode = '" + equipTypeList.get(i).get("code").toString() + "'");
  773. admQueryCriteriaEquip.addFilters("not infos isnull");
  774. admQueryCriteriaEquip.setName(AdmEquipment.OBJ_TYPE);
  775. if(withBuilding){
  776. if(StrUtil.isNotEmpty(buildingId)){
  777. admQueryCriteriaEquip.addFilters("buildingId = '"+buildingId+"'");
  778. }else{
  779. admQueryCriteriaEquip.addFilters("buildingId isnull");
  780. }
  781. }
  782. AdmResponse eqResponse = service.query(admQueryCriteriaEquip);
  783. List<AdmEquipment> equipmentList = (List<AdmEquipment>) eqResponse.getContent();
  784. if (equipmentList.size() > 0) {
  785. /** 字典信息点 */
  786. //AdmResponse responseDic = dictService.query(context, admQueryCriteriaInfo, AdmDictConstant.CLASS_CODE, AdmObjectInfo.class);
  787. //List<AdmObjectInfo> defFuncIdList = (List<AdmObjectInfo>) responseDic.getContent();
  788. QueryCriteria queryCriteria = AdmQueryCriteriaHelper.toDmpCriteria(admQueryCriteriaInfo);
  789. queryCriteria.setOnlyCount(false);
  790. List<ObjectInfoDefine> defFuncIdList = DigitalObjectInfoFacade.query(AdmContextUtil.toDmpContext().getGroupCode(), AdmContextUtil.toDmpContext().getProjectId(), AdmCommonConstant.APP_ID,null,queryCriteria);
  791. if (defFuncIdList.size() > 0) {
  792. Map mapInfo = new HashMap<String,String>();
  793. Map mapInputType = new HashMap<String,String>();
  794. Map mapInputFirstName = new HashMap<String,String>();
  795. for (ObjectInfoDefine defFuncId : defFuncIdList) {
  796. if(StrUtil.isEmpty(defFuncId.getCode())){
  797. continue;
  798. }
  799. mapInfo.put(defFuncId.getCode(),defFuncId.getName());
  800. if(StrUtil.isNotEmpty(defFuncId.getDataType())){
  801. mapInputType.put(defFuncId.getCode(), defFuncId.getDataType());
  802. }
  803. if(StrUtil.isNotEmpty(defFuncId.getFirstTag())){
  804. mapInputFirstName.put(defFuncId.getCode(),defFuncId.getFirstTag());
  805. }
  806. }
  807. for (AdmEquipment equipment : equipmentList) {
  808. if(CollUtil.isEmpty(equipment.getInfos())){
  809. continue;
  810. }
  811. Map<String, Object> info = equipment.getInfos();
  812. for(String key : info.keySet()){
  813. if(info.get(key) != null && StrUtil.isNotEmpty(info.get(key).toString())){
  814. boolean containsKey = mapInfo.containsKey(key);
  815. if(!containsKey){
  816. continue;
  817. }
  818. /** 处理数据写入文件 */
  819. EquipmentPointExcel excel = new EquipmentPointExcel();
  820. /** id */
  821. excel.setId(equipment.getId());
  822. /** 本地编码 */
  823. excel.setLocalId(equipment.getLocalId());
  824. /** 本地名称 */
  825. excel.setLocalName(equipment.getLocalName());
  826. /** 类型 */
  827. excel.setClassCode(equipment.getClassCode());
  828. /** 类型 */
  829. excel.setClassCodeName(equipTypeList.get(i).get("name").toString());
  830. /** 一级标签 */
  831. boolean containsFirstName = mapInputFirstName.containsKey(key);
  832. if (containsFirstName) {
  833. /** 一级标签 */
  834. excel.setMapInputFirstName(mapInputFirstName.get(key).toString());
  835. }
  836. /** 信息点名 */
  837. excel.setInfoName(mapInfo.get(key).toString());
  838. /** 信息点 */
  839. excel.setInfoCode(key);
  840. boolean containsInputType = mapInputType.containsKey(key);
  841. if (containsInputType) {
  842. /** 输入类型 */
  843. excel.setInputType(mapInputType.get(key).toString());
  844. }
  845. /** 值 */
  846. excel.setInputValue(info.get(key).toString());
  847. excelList.add(excel);
  848. }
  849. }
  850. }
  851. }
  852. }
  853. }
  854. }
  855. return excelList;
  856. }else{
  857. return null;
  858. }
  859. }
  860. }