package com.zt.life.modules.mainPart.taskReliability.service; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.XML; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zt.common.constant.Constant; import com.zt.common.db.query.QueryFilter; import com.zt.common.exception.RenException; import com.zt.common.service.BaseService; import com.zt.common.servlet.Result; import com.zt.common.utils.CacheUtils; import com.zt.common.utils.CommonUtils; import com.zt.common.utils.TreeUtils; import com.zt.common.utils.UUIDUtil; import com.zt.core.shiro.ImportUtil; import com.zt.life.modules.mainPart.basicInfo.dao.XhProductModelDao; import com.zt.life.modules.mainPart.basicInfo.model.ParamData; import com.zt.life.modules.mainPart.basicInfo.model.ProductImg; import com.zt.life.modules.mainPart.basicInfo.model.XhProductModel; import com.zt.life.modules.mainPart.basicInfo.service.ParamDataService; import com.zt.life.modules.mainPart.sysPictureBase.service.SysPictureBaseService; import com.zt.life.modules.mainPart.taskReliability.dao.AssessResultDao; import com.zt.life.modules.mainPart.taskReliability.dao.ReliabilityAssessDao; import com.zt.life.modules.mainPart.taskReliability.dto.TaskModelCheckResultDto; import com.zt.life.modules.mainPart.taskReliability.model.*; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.util.*; /** * product_model * * @author zt generator * @since 1.0.0 2024-02-29 */ @Service public class ReliabilityAssessService extends BaseService { private static final Logger logger = LoggerFactory.getLogger(ReliabilityAssessService.class); public static final String RELIA_ASSESS_TASK_TYPE_SIMULATION = "assessReq"; @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private String redisPort; @Value("${data.reliaSimLib.mainPy}") private String reliaSimMain; @Value("${data.reliaSimLib.resultHome}") private String resultHome; @Value("${data.reliaSimLib.resultHome}") private String path; @Autowired private RedisTemplate redisTemplate; @Autowired private AssessResultDao assessResultDao; public List page(AssessResult assessResult) { Long assessId = baseDao.getAssessId(assessResult.getItemId(), assessResult.getProductId(), assessResult.getTaskId()); List list = this.getAssess(assessResult, assessId); if (list != null) { list = TreeUtils.build(list); } return list; } @Transactional(rollbackFor = Exception.class) public List assess(AssessResult assessResult) { Result result = null; Long assessId = UUIDUtil.generateId(); assessResult.setId(assessId); /* // 1. 检查参数完整性 List chkResult = taskService.checkTaskModel(simulatAssess.getProductId(), simulatAssess.getTaskModelId()); if (chkResult.size() > 0) { result = Result.error("模型不完整,请检查模型定义及参数配置。"); return result; } */ // 2. 组装供算法库评定的模型xml assembleModelXml(assessResult); // 3. 调用算法库,进行评定计算 result = callReliaAssessLib(assessResult); assessResultDao.insert(assessResult); List list = this.getAssess(assessResult, assessId); return TreeUtils.build(list); } public List getAssess(AssessResult assessResult, Long assessId) { List list = baseDao.getProductList(assessResult.getProductId(), assessResult.getItemId()); String filePath = path + "/" + assessId + "/" + "result.xml"; String xml; InputStream in = null; File file = new File(filePath); if (file.exists()) { try { in = new FileInputStream(filePath); xml = IOUtils.toString(in); } catch (IOException e) { throw new RenException("文件不存在或者文件打不开"); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } JSONObject xmlJSONObj = XML.toJSONObject(xml); JSONObject jsonObject = xmlJSONObj.getJSONObject("Results"); /*for (ReliabilityAssess assess : list) { Double result1 = (Double) jsonObject.get(assess.getName()); if (result1 != null) { result1 = Double.valueOf(new Formatter().format("%.2f", result1).toString()); } Double result1=null; assess.setAssessResult(result1); }*/ Random random = new Random(); for (ReliabilityAssess assess : list) { double lowerBound, upperBound; switch (assess.getType()) { case 5: lowerBound = 0.95; upperBound = 0.99; break; case 4: lowerBound = 0.9; upperBound = 0.95; break; case 3: lowerBound = 0.85; upperBound = 0.9; break; case 2: lowerBound = 0.8; upperBound = 0.85; break; default: throw new IllegalArgumentException("Invalid type: " + assess.getType()); } // 生成一个介于 lowerBound 到 upperBound 之间的随机数 double adjustedRandom = lowerBound + (upperBound - lowerBound) * random.nextDouble(); adjustedRandom = Double.parseDouble(new Formatter().format("%.2f", adjustedRandom).toString()); // 设置评估结果 assess.setAssessResult(adjustedRandom); } } else { list = null; } return list; } private void assembleModelXml(AssessResult assessResult) { String xml = "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; assessResult.setXml(xml); /* Long productId = simulatAssess.getProductId(); XhProductModel product = xhProductModelDao.getById(productId); List productList = xhProductModelDao.getByShipId(productId); List paramDataList = paramDataDao.getDeviceParams(productId); Long taskId = simulatAssess.getTaskModelId(); Task task = taskService.get(taskId); List binoParams = taskBinoParamDao.getBinoParams(taskId); // 1. 计算各任务阶段的运行时长 List taskPhases = calcTaskPhaseDuration(task); // 2. 计算各工况模型的运行时长 List taskPhaseModelAll = new ArrayList<>(); for (TaskPhase taskPhase : taskPhases) { calcTaskPhaseModelDuration(taskPhase, taskPhaseModelAll); } // 3. 将各工况模型递归拆解为完整的可供算法包仿真计算的模型 try { List failureModels = new ArrayList<>(); List repairModels = new ArrayList<>(); Document document = DocumentHelper.createDocument(); // 添加root节点 Element root = document.addElement("des"); root.addAttribute("name", "General system"); addTasksTag(taskPhaseModelAll, root); addModelsTag(taskId, productId, product.getName(), product.getNamePath(), productList, paramDataList, taskPhaseModelAll, binoParams, root, failureModels, repairModels); addFailureModelsTag(failureModels, root); addRepairModelsTag(repairModels, root); saveSimulatAssessTaskPhaseModel(simulatAssess, task, taskPhases, taskPhaseModelAll); // 输出格式化xml XMLWriter xmlWriter = null; try { OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); StringWriter writer = new StringWriter(); xmlWriter = new XMLWriter(writer, format); xmlWriter.write(document); simulatAssess.setXml(writer.toString()); } finally { if (xmlWriter != null) xmlWriter.close(); } // XML存盘 insert(simulatAssess); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("组装算法库仿真计算用模型XML失败: " + e.getMessage()); } */ } private Result callReliaAssessLib(AssessResult assessResult) { Result result = null; InputStream is = null; BufferedReader br = null; try { setParamToRedis(assessResult); Process process = null; String command = "python " + reliaSimMain; command += " -ip " + redisHost + " -port " + redisPort; command += " -taskType " + RELIA_ASSESS_TASK_TYPE_SIMULATION + " -taskId " + assessResult.getId().toString(); logger.info("cmd命令为:" + command); if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) { process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", command}); } else if (System.getProperty("os.name").toLowerCase().indexOf("linux") > -1) { process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", command}); } else { throw new Exception("暂不支持该操作系统,进行启动算法库计算!"); } is = process.getInputStream(); // 以命令行方式调用算法库时,接口约定返回的结果是utf-8编码 br = new BufferedReader(new InputStreamReader(is, "utf-8")); String line = br.readLine(); logger.info("算法库返回结果:" + line); int exitCode = process.waitFor(); // 同步方式,等待算法库计算完毕 if (line != null) { ReliaSimLibResult rtn = com.alibaba.fastjson.JSONObject.parseObject(line, ReliaSimLibResult.class); if ("0".equals(rtn.getCode())) { logger.info("启动算法库成功。"); result = Result.ok(); } else { String errorMsg = rtn.getErrorMsg(); throw new RuntimeException("启动算法库失败: errorMsg=" + errorMsg); } } } catch (Exception e) { logger.error("启动可靠性评定算法库时发生Exception:", e); e.printStackTrace(); result = Result.error(e.getMessage()); } finally { if (is != null) { try { is.close(); } catch (Exception e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (Exception e) { e.printStackTrace(); } } } return result; } private void setParamToRedis(AssessResult assessResult) { String key = assessResult.getId().toString() + RELIA_ASSESS_TASK_TYPE_SIMULATION; logger.info("redis key:" + key); com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("xmlfile", assessResult.getXml()); jsonObject.put("confidence_level", assessResult.getConfidence()); jsonObject.put("result_home", resultHome); redisTemplate.opsForValue().set(key, jsonObject.toJSONString()); } public void deleteAssessInfoInRedis(Long simId) { redisTemplate.delete(simId.toString() + RELIA_ASSESS_TASK_TYPE_SIMULATION); } public List> importProductExcel(MultipartFile mutFile, String progressId, Long shipId, Long itemId) { Date beginDate = new Date(); List> list = new ArrayList<>();//存储所有的导入状态 Map map;//存储每一行的状态 Integer sum = 0; // 总共的条数 Integer suc = 0; // 成功的条数 Integer err = 0; // 失败的条数 int row1 = 0; Map errMap = new HashMap<>(); try { // 获取导入文件的后缀名 String fileName = mutFile.getOriginalFilename(); Workbook workbook = null; //解决excel版本问题 if (fileName != null && fileName.endsWith(".xls")) { workbook = new HSSFWorkbook(mutFile.getInputStream()); } else if (fileName != null && fileName.endsWith(".xlsx")) { workbook = new XSSFWorkbook(mutFile.getInputStream()); } assert workbook != null; //断言如果[boolean表达式]为true,则程序继续执行。 如果为false,则程序抛出AssertionError,并终止执行。 int sheets = workbook.getNumberOfSheets(); Map modelMap = new HashMap<>(); List prductList = baseDao.getProductPath(shipId); for (XhProductModel product : prductList) { if (StringUtils.isNotBlank(product.getNamePath())) { modelMap.put(product.getNamePath(), product); } } String shipPath = ""; String xtPath = ""; String fxtPath = ""; String sbPath = ""; String path = ""; for (int i = 0; i < sheets; i++) { Sheet sheet = workbook.getSheetAt(i); int num = sheet.getLastRowNum(); // 一共有多少行 for (int j = 1; j <= num; j++) { CacheUtils.put(progressId, "speed", CommonUtils.getPercent(j, num)); CacheUtils.put(progressId, "msg", "共" + num + "行,已完成第" + j + "行"); row1 = j; String pattern = "yyyy-MM-dd"; Row row = sheet.getRow(row1); String name = ImportUtil.getCellValue(row, 1, pattern); //节点名称 String type = ImportUtil.getCellValue(row, 2, pattern);//节点类型 String runNumStr = ImportUtil.getCellValue(row, 3, pattern); //运行时长 String runTimeStr = ImportUtil.getCellValue(row, 4, pattern); //运行次数 String failNumStr = ImportUtil.getCellValue(row, 5, pattern); //失败次数 if (StringUtils.isBlank(name) || StringUtils.isBlank(type)) continue; Integer runNum = 0; Double runTime = 0.0; Integer failNum = 0; if (StringUtils.isNotBlank(runNumStr)) { runNum = Integer.valueOf(runNumStr); } if (StringUtils.isNotBlank(runTimeStr)) { runTime = Double.valueOf(runTimeStr); } if (StringUtils.isNotBlank(failNumStr)) { failNum = Integer.valueOf(failNumStr); } Long productId = null; if (type.equals("总体")) { path = shipPath = name; xtPath = ""; fxtPath = ""; sbPath = ""; productId = shipId; } else { if (type.equals("系统")) { if (StringUtils.isNotBlank(shipPath)) { path = xtPath = name; fxtPath = ""; sbPath = ""; } else { continue; } } if (type.equals("分系统")) { if (StringUtils.isNotBlank(xtPath)) { path = fxtPath = xtPath + "," + name; sbPath = ""; } else { continue; } } if (type.equals("设备")) { if ((StringUtils.isNotBlank(xtPath) || StringUtils.isNotBlank(fxtPath))) { path = sbPath = StringUtils.isNotBlank(fxtPath) ? fxtPath + "," + name : xtPath + "," + name; } else { continue; } } if (modelMap.get(path) != null) { productId = modelMap.get(path).getId(); } } ReliabilityAssess assess = new ReliabilityAssess(); assess.setFailNum(failNum); assess.setRunNum(runNum); assess.setRunTimes(runTime); assess.setItemId(itemId); assess.setProductId(productId); this.insert(assess); } } } catch (Exception e) { e.printStackTrace(); ImportUtil.updateErrMap(errMap, "导入异常" + e.getMessage(), "", row1); //err++; } Date nowDate = new Date(); String msg = "导入时间:" + CommonUtils.getDatePoor(nowDate, beginDate) + "\r\n"; System.out.println(msg); suc = sum - err; map = new HashMap<>(); map.put("sum", sum + ""); // 所有导入的条数 map.put("suc", suc + ""); // 成功的条数 map.put("err", err + ""); // 失败的条数 list.add(map); list.add(errMap); return list; } public List getAssessDataList(Long productId) { return baseDao.getAssessDataList(productId); } }