From 6cfced5860b69513c5a84318b0514d4eb0e2c7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E5=90=91=E6=96=8C?= <574110378@qq.com> Date: Fri, 22 Sep 2023 15:50:37 +0800 Subject: [PATCH] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/api/controller/ApiController.java | 6 +- .../ocr/controller/OcrIdentifyController.java | 6 +- .../controller/OcrSimulatorController.java | 17 +- .../modules/ocr/dto/OcrRuleCheckDTO.java | 2 +- .../modules/ocr/init/HandleCallbacklnit.java | 4 + .../ocr/service/IOcrIdentifyService.java | 2 + .../ocr/service/IOcrRuleCheckService.java | 1 + .../service/impl/OcrIdentifyServiceImpl.java | 400 ++++++++++++++++++ .../service/impl/OcrRuleCheckServiceImpl.java | 197 ++++++++- .../modules/ocr/utils/CallBackWlyUtils.java | 2 + .../modules/system/util/RandImageUtil.java | 6 + 11 files changed, 618 insertions(+), 25 deletions(-) diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/ApiController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/ApiController.java index 208e7ab..fb26250 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/ApiController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/ApiController.java @@ -65,9 +65,9 @@ public class ApiController { @Transactional @ResponseBody public Result pushSemantic(@RequestBody JSONObject requestBody) throws InterruptedException { - if (!"test".equals(profiles)) { - return Result.error("当前环境不支持该功能,请访问测试环境"); - } +// if (!"test".equals(profiles)) { +// return Result.error("当前环境不支持该功能,请访问测试环境"); +// } if (requestBody == null) { return Result.error("请输入请求参数"); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrIdentifyController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrIdentifyController.java index c14aeaf..1ca4b29 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrIdentifyController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrIdentifyController.java @@ -149,9 +149,9 @@ public class OcrIdentifyController extends JeecgController add(@RequestBody OcrIdentify ocrIdentify) { - if (!"test".equals(profiles)) { - return Result.error("当前环境不支持该功能,请访问测试环境"); - } +// if (!"test".equals(profiles)) { +// return Result.error("当前环境不支持该功能,请访问测试环境"); +// } AssertUtils.notEmpty(ocrIdentify.getTaskName(), "[任务名称]-不可为空"); AssertUtils.notTrue(ocrIdentifyService.calculateTimeDifference(ocrIdentify.getTaskName())<=10,"[任务名称]-"+ocrIdentify.getTaskName()+" 短时间内已存在,不可再次请求"); AssertUtils.notEmpty(ocrIdentify.getIdentifyUrl(), "[识别路径]不可为空"); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrSimulatorController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrSimulatorController.java index 895b0b9..727a0f4 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrSimulatorController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrSimulatorController.java @@ -51,9 +51,9 @@ public class OcrSimulatorController{ @ApiOperation(value = "场景识别") @PostMapping(value = "/identify") public Result identify(@RequestBody JSONObject requestBody) { - if (!"test".equals(profiles)) { - return Result.error("当前环境不支持该功能,请访问测试环境"); - } +// if (!"test".equals(profiles)) { +// return Result.error("当前环境不支持该功能,请访问测试环境"); +// } JSONObject responseBody = new JSONObject(); JSONArray images = requestBody.getJSONArray("images"); AssertUtils.hasSize(images,"请先上传图片"); @@ -115,5 +115,14 @@ public class OcrSimulatorController{ AssertUtils.hasSize(identifyDetailIdList,"请先上传图片"); return Result.OK(ocrIdentifyService.simulateChecks(simulateChecksVO)); } - + @ApiOperation(value = "模拟检查G") + @PostMapping(value = "/simulateChecksV01") + public Result simulateChecksV01(@RequestBody SimulateChecksVO simulateChecksVO) { + //规则检查配置id + String ruleCheckId = simulateChecksVO.getRuleCheckId(); + List identifyDetailIdList = simulateChecksVO.getIdentifyDetailIdList(); + AssertUtils.notEmpty(ruleCheckId, "请选择[规则扫描器]"); + AssertUtils.hasSize(identifyDetailIdList,"请先上传图片"); + return Result.OK(ocrIdentifyService.simulateChecksV01(simulateChecksVO)); + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/dto/OcrRuleCheckDTO.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/dto/OcrRuleCheckDTO.java index d030bd5..66ee45b 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/dto/OcrRuleCheckDTO.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/dto/OcrRuleCheckDTO.java @@ -22,7 +22,7 @@ public class OcrRuleCheckDTO extends OcrRuleCheck { @ApiModelProperty(value = "元数据配置名称") @Excel(name = "元数据配置名称", width = 15) private String metadataConfigName; - + private String configRuleAdapter; private Map configRuleMap=new LinkedHashMap<>(); private Map fieldMap=new LinkedHashMap<>(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/init/HandleCallbacklnit.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/init/HandleCallbacklnit.java index 6b3ef7d..c4cba36 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/init/HandleCallbacklnit.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/init/HandleCallbacklnit.java @@ -70,9 +70,13 @@ public class HandleCallbacklnit implements ApplicationRunner { e.printStackTrace(); } List ocrIdentifyList = ocrIdentifyService.findNeNoticeList(autoPushNoticeMaxNum); + log.info("待回调任务:{}",ocrIdentifyList.size()); + log.info("待回调任务:{}",ocrIdentifyList); for (OcrIdentify ocrIdentify : ocrIdentifyList) { try { + log.info("回调:{}",ocrIdentify); ocrIdentifyService.callbackWly(ocrIdentify.getId()); + log.info("回调结束:{}",ocrIdentify); Thread.sleep(pushTimeInterval*1000); } catch (InterruptedException e) { log.error(e.getMessage()); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrIdentifyService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrIdentifyService.java index 9c5abab..3f4a948 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrIdentifyService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrIdentifyService.java @@ -81,4 +81,6 @@ public interface IOcrIdentifyService extends IService { * @return */ long calculateTimeDifference(String taskName); + + JSONObject simulateChecksV01(SimulateChecksVO simulateChecksVO); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrRuleCheckService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrRuleCheckService.java index 28a82c2..e340c86 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrRuleCheckService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrRuleCheckService.java @@ -78,4 +78,5 @@ public interface IOcrRuleCheckService extends IService { boolean copy(OcrRuleCheck ocrRuleCheck); + OcrRuleCheckDTO findByIdV01(String ruleCheckId); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrIdentifyServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrIdentifyServiceImpl.java index 5c999bd..db68725 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrIdentifyServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrIdentifyServiceImpl.java @@ -428,7 +428,9 @@ public class OcrIdentifyServiceImpl extends ServiceImpl identifyDetailList = ocrIdentifyDetailService.listByIdentifyId(ocrIdentifyId); ocrIdentifyCallbackLog.setStartTime(date); + log.info("执行CallBackWlyUtils.callbackWly({}, {})",ocrIdentify,identifyDetailList); boolean b = CallBackWlyUtils.callbackWly(ocrIdentify, identifyDetailList); + log.info("执行CallBackWlyUtils.callbackWly 结束",ocrIdentify,identifyDetailList); ocrIdentifyCallbackLog.setStatus(b?1:0);//0-失败,1-成功 ocrIdentifyCallbackLog.setEndTime(new Date()); ocrIdentifyCallbackLogService.save(ocrIdentifyCallbackLog); @@ -510,6 +512,38 @@ public class OcrIdentifyServiceImpl extends ServiceImpl ocrResultDTOList, String fieldName, String field, String inputText, String ocrText, Double ocrPrecisionRate, String imgPath, String failureReason, Boolean ruleValidation, Double d) { + OcrResultDTO ocrResultDTO = new OcrResultDTO(); + ocrResultDTO.setTag(field); + ocrResultDTO.setTagName(fieldName); + ocrResultDTO.setOcrText(ocrText); + ocrResultDTO.setInputText(inputText); + ocrResultDTO.setOcrPrecisionRate(ocrPrecisionRate == null ? 0d : ocrPrecisionRate); + if (d == null) { + ocrResultDTO.setTextRate(0d); + } else { + ocrResultDTO.setTextRate(new BigDecimal(d).setScale(2, RoundingMode.HALF_UP).doubleValue()); + } + /*System.out.println("-----------------"); + System.out.println(failureReason); + System.out.println("-----------------");*/ + if (StringUtils.isNotBlank(imgPath)) { + SourceImage sourceImage = new SourceImage(); + sourceImage.setPath(imgPath); + int i = imgPath.lastIndexOf("/"); + sourceImage.setFileName(imgPath.substring(i + 1, imgPath.length())); + sourceImage.setPreviewUrl(OcrConstant.FILE_REVIEW_URL_PREFIX+imgPath); + ocrResultDTO.setSourceImage(sourceImage); + } + ocrResultDTO.setFailureReason(failureReason); + if (ocrResultDTOList == null) { + ocrResultDTOList = new ArrayList<>(); + } + ocrResultDTOList.add(ocrResultDTO); + } /** * 组装 checkSemanticModelMap @@ -1042,6 +1076,372 @@ public class OcrIdentifyServiceImpl extends ServiceImpl identifyDetailList = ocrIdentifyDetailService.listByIds(simulateChecksVO.getIdentifyDetailIdList()); + System.out.println("1111111111111111111111111111111"); + //遍历任务,做匹配 + int i1=1; + //用于数据结构化的对象 + List ocrResultDTOList = new ArrayList<>(); + Date startDataCheckTime = new Date(); + Map fieldRightMap = new LinkedHashMap<>();//存放 字段判断正确map + for (OcrIdentifyDetail ocrIdentifyDetail : identifyDetailList) { + i1++; + String semanticResultJson = ocrIdentifyDetail.getSemanticResult(); + String imgPath = ocrIdentifyDetail.getImageUrl(); + if (StringUtils.isBlank(semanticResultJson)) {continue;} + String doctorName = simulateChecksVO.getDoctorName(); + String hospitalName = simulateChecksVO.getHospitalName(); + String departmentName = simulateChecksVO.getDepartmentName(); + String time = simulateChecksVO.getTime(); + List sourceJson = new ArrayList<>(); + if (StringUtils.isNotBlank(doctorName)) { + sourceJson.add(JSONObject.parseObject(String.format("{\"tag\":\"doctorName\", \"inputText\":\"%s\"}", doctorName))); + } + if (StringUtils.isNotBlank(hospitalName)) { + sourceJson.add(JSONObject.parseObject(String.format("{\"tag\":\"hospitalName\", \"inputText\":\"%s\"}", hospitalName))); + } + if (StringUtils.isNotBlank(departmentName)) { + sourceJson.add(JSONObject.parseObject(String.format("{\"tag\":\"departmentName\", \"inputText\":\"%s\"}", departmentName))); + } + if (StringUtils.isNotBlank(time)) { + sourceJson.add(JSONObject.parseObject(String.format("{\"tag\":\"time\", \"inputText\":\"%s\"}", time))); + } + JSONObject semanticResult = JSONObject.parseObject(ocrIdentifyDetail.getSemanticResult()); + + //判断是不是网络图片 + Boolean onlineFile = FileOUtils.isOnlineFile(imgPath); + if (onlineFile) { + //如果是网络图片,则将图片下载 + imgPath = FileOUtils.downLoadFromUrl(imgPath, FileOUtils.getFileName(imgPath), OcrConstant.FILE_DOWNLOAD_URL_PREFIX); + } + + File file = new File(imgPath); + //当原图片存在时. + if (file.exists()) { + int i = imgPath.lastIndexOf("/"); + //压缩图片 + /*if (true) { + String fileUrl = "/data/ocrImage/thumbnail" + imgPath.substring(0, i); + //判断新目录是否存在,不存在则新建 + FileOUtils.folderCreate(fileUrl); + String outputImagePath = fileUrl + imgPath.substring(i + 1, imgPath.length()); + File thumbnailFile = new File(outputImagePath); + //如果上次生成过缩率图,就不生成了 + if (!thumbnailFile.exists()) { + ImageUtils.compressImage(file.getAbsolutePath(), outputImagePath, 0.3f, 0.3f); + } + ocrIdentifyDetail.setThumbnailImageUrl(outputImagePath); + }*/ + //============================绘制虚线 + JSONObject semanticResult2 = semanticResult.getJSONObject("semantic_result"); + String fileUrl = "/data/ocrImage/drawDashed" + imgPath.substring(0, i); + //判断新目录是否存在,不存在则新建 + FileOUtils.folderCreate(fileUrl); + String outputImagePath = fileUrl + imgPath.substring(i + 1, imgPath.length()); + if (semanticResult2!=null) { + List> resultToPoints = ImageUtils.semanticResultToPoints(semanticResult2); + boolean hasPoints=true; + if (CollectionUtils.isNotEmpty(resultToPoints)) { + for (List resultToPoint : resultToPoints) { + if (CollectionUtils.isEmpty(resultToPoint)) { + hasPoints=false; + } + } + if (hasPoints){ + ImageUtils.drawDashedRectangleOnImages(file.getAbsolutePath(), resultToPoints, outputImagePath,"green"); + imgPath = outputImagePath; + } + } + } + //============================ + } + + OcrRuleCheckDTO ocrRuleCheckVo = ocrRuleCheckService.findByIdV01(simulateChecksVO.getRuleCheckId()); +// Map checkSemanticModelMap = getCheckSemanticModelMapV0(ocrRuleCheckVo.getConfigRule(), ocrRuleCheckVo.getFieldMap(), sourceJson); + String text = null;//ocr 识别的文本 + Double probability = 0d; + StringBuilder rMessage = new StringBuilder(); + //========================== + for (String key : ocrRuleCheckVo.getFieldMap().keySet()) { + CheckSemanticModel checkSemanticModel=new CheckSemanticModel(); + for(JSONObject jsonObject:sourceJson){ + Object tag = jsonObject.get("tag"); + if(tag.equals(key)){ + checkSemanticModel.setField(key); + checkSemanticModel.setFieldName(ocrRuleCheckVo.getFieldMap().get(key)); + checkSemanticModel.setInputText(jsonObject.getString("inputText")); + } + } + String field = key;//字段 name. + String fieldName = checkSemanticModel.getFieldName();//校验的字段名称 +// String ruleInfo = value.getRuleInfo();//是否绝对判断 0-绝对判断,1-不绝对判断 + String inputText = checkSemanticModel.getInputText();//校验文本 ,ocr识别的文本如果不包含该内容,则算作失败 + if (StringUtils.isBlank(fieldName)) { + continue; + } + List fieldNameList = Arrays.asList(fieldName.split(",")); + text = null; + //boolean b = ArrayOUtils.containsStringList(fieldNameList, new ArrayList<>(semanticResult.getJSONObject("semantic_result").keySet())); + //查看ocr识别返回的字段名称中是否有当前这个字段名称 + //TODO 注意,ocr 识别返回的 字段是多个结果(数组),有一个值匹配上即为正确 + List ocrArray = new ArrayList<>(); + for (String s : fieldNameList) { + JSONArray jsonArray = new JSONArray(); + if (Arrays.asList("医生名称","姓名","医生").contains(s)) { + for (String s1 : Arrays.asList("医生名称", "姓名", "医生")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("科室名称","科室").contains(s)) { + for (String s1 : Arrays.asList("科室名称","科室")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("医院名称","医院").contains(s)) { + for (String s1 : Arrays.asList("医院名称", "医院")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("日期", "时间").contains(s)) { + for (String s1 : Arrays.asList("日期", "时间")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("患者姓名","患者").contains(s)) { + for (String s1 : Arrays.asList("患者姓名","患者")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("病历号").contains(s)) { + for (String s1 : Arrays.asList("病历号")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("入院日期").contains(s)) { + for (String s1 : Arrays.asList("入院日期")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("出生日期").contains(s)) { + for (String s1 : Arrays.asList("出生日期")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else if (Arrays.asList("年龄").contains(s)) { + for (String s1 : Arrays.asList("年龄")) { + JSONArray semantic_result = semanticResult.getJSONObject("semantic_result").getJSONArray(s1); + if (CollectionUtils.isNotEmpty(semantic_result)) { + jsonArray.addAll(semantic_result); + break; + } + } + }else{ + jsonArray = semanticResult.getJSONObject("semantic_result").getJSONArray(s); + } + + if (jsonArray != null && jsonArray.size() > 0) { + ocrArray.addAll(jsonArray.toJavaList(JSONObject.class)); + } + } + if (ocrArray.size() > 0) { + for (JSONObject ocrItem : ocrArray) { + text = ocrItem.getString("text");//ocr 识别的文本 + probability = ocrItem.getDouble("probability");//置信度 + double v = StrCharUtil.similarityRatio(inputText, text); + this.ocrResultAddV01(ocrResultDTOList, checkSemanticModel.getFieldName(), field, inputText, text, probability, imgPath, checkSemanticModel.getFieldName() + "参数未获取到结果", false,v); + } + } + + } + } + Date overDataCheckTime = new Date(); + + JSONObject responseBody=new JSONObject(); + + //OCR和NlU执行时间总和(秒) + double ocrAndNluTimeSum = identifyDetailList.stream().mapToDouble(i -> (i.getOcrTime() == null ? 0 : i.getOcrTime()) + (i.getNluTime() == null ? 0 : i.getNluTime())).sum(); + //执行时间(毫秒) + double dataStructuredTime = new BigDecimal(overDataCheckTime.getTime() - startDataCheckTime.getTime()).setScale(2, RoundingMode.HALF_UP).doubleValue(); + double executionTime = new BigDecimal(ocrAndNluTimeSum+(dataStructuredTime/1000)).setScale(2, RoundingMode.HALF_UP).doubleValue(); + responseBody.put("dataStructuredTime",dataStructuredTime); + responseBody.put("allExecutionTime",executionTime); + + //=========排序 + if (CollectionUtils.isNotEmpty(ocrResultDTOList)) { + ocrResultDTOList.sort((h1, h2) -> h1.getTag().compareTo(h2.getTag())); + } + //============ + if (CollectionUtils.isEmpty(ocrResultDTOList)) { + //没有匹配结果 + responseBody.put("taskResult",1); + }else{ + long count = fieldRightMap.values().stream().filter(o->!o).count(); + //long count = ocrResultDTOList.stream().filter(o -> !o.getRuleValidation()).count(); + responseBody.put("taskResult",count>0?0:1);//匹配成功或失败 + Set haveRateTagList = ocrResultDTOList.stream().filter(o -> o.getTextRate() > 0).map(OcrResultDTO::getTag).collect(Collectors.toSet()); + List newResultDTOList=new ArrayList<>(); + //过滤掉0的值 + + for (OcrResultDTO o : ocrResultDTOList) { + if (haveRateTagList.contains(o.getTag())) { + if (o.getTextRate()>0) { + newResultDTOList.add(o); + } + }else{ + newResultDTOList.add(o); + } + //脱敏处理 + String tagName = o.getTagName(); + String ocrText = o.getOcrText(); + StringBuilder sb = new StringBuilder(); + if ("患者姓名".equals(tagName)) { + // 保留第一个字,其余用 "*" 替代 + int length = Math.max(0, ocrText.length() - 1); + for (int i = 0; i < length; i++) { + sb.append("*"); + } + String desensitizedText = ocrText.substring(0, 1) + sb.toString(); + o.setOcrText(desensitizedText); + } + if ("联系方式".equals(tagName) || "身份证号".equals(tagName)){ + String desensitizedText = desensitizeText(ocrText); // 自定义的脱敏方法 + // 更新脱敏后的值 + o.setOcrText(desensitizedText); + } + if ("家庭住址".equals(tagName) || "工作地址".equals(tagName) || "病情陈述人".equals(tagName) + || "户籍地".equals(tagName)){ + + sb.append(ocrText.charAt(0)); + for (int i = 1; i < ocrText.length() - 1; i++) { + sb.append("*"); + } + sb.append(ocrText.charAt(ocrText.length() - 1)); + String desensitizedText= sb.toString(); + o.setOcrText(desensitizedText); + } + } + ocrResultDTOList = newResultDTOList; + } + //获取最小 + double min = 0d; + //获取最大 + double max = 0d; + if (CollectionUtils.isNotEmpty(ocrResultDTOList)) { + min = ocrResultDTOList.stream().mapToDouble(OcrResultDTO::getTextRate).min().getAsDouble(); + max = ocrResultDTOList.stream().mapToDouble(OcrResultDTO::getTextRate).max().getAsDouble(); + } + responseBody.put("min",min); + responseBody.put("max",max); + responseBody.put("detailList", ocrResultDTOList); + return responseBody; + } + + private Map getCheckSemanticModelMapV0(String configRule, Map fieldMap, List sourceJson) { + if (configRule!=null) { + String[] split = configRule.split("&"); + //将 configRuleMap的 key 创建一个Set +// Set keySet = new HashSet<>(configRuleMap.keySet()); +// //循环keySet,判断字段是否是缩写,如果是缩写就把缩写的全称put一下 +// for (String s : keySet) { +// String value = configRuleMap.get(s); +// if ("hn".equals(s)) { +// configRuleMap.put("hospitalName",value); +// }else if("dn".equals(s)) { +// configRuleMap.put("doctorName", value); +// }else if("dmn".equals(s)) { +// configRuleMap.put("departmentName", value); +// }else if("tm".equals(s) || ("time".equals(s))) { +// configRuleMap.put("time", value); +// }else{ +// configRuleMap.put(s,value); +// } +// } + } + + Map checkSemanticModelMap = new LinkedHashMap<>(); + //校验正确的值 + Map inputMap = new LinkedHashMap<>(); + if (sourceJson != null && sourceJson.size() > 0) { + String tag, inputText; + for (JSONObject sourceJsonObject : sourceJson) { + tag = sourceJsonObject.getString("tag"); + if (StringUtils.isBlank(tag)) { + continue; + } + inputText = sourceJsonObject.getString("inputText"); + inputMap.put(tag, inputText); + } + } + + CheckSemanticModel copyEntity = null; + String fieldName = null, inputText; + + + //判断 规则检查配置 是不是 isrule=1 + if (configRule.contains("isrule==1")) { + //isrule=1 + for (String field : inputMap.keySet()) { + fieldName = fieldMap.get(field); + copyEntity = new CheckSemanticModel(); + inputText = inputMap.get(field); + copyEntity.setField(field); + copyEntity.setInputText(inputText); + copyEntity.setRuleInfo("1"); + copyEntity.setFieldName(fieldName); + checkSemanticModelMap.put(field, copyEntity); + } + } else { + if (fieldMap != null) { + for (String field : fieldMap.keySet()) { + copyEntity = new CheckSemanticModel(); + copyEntity.setField(field); + //1/0 +// if (configRuleMap != null && configRuleMap.containsKey(field)) { +// configRule = configRuleMap.get(field); +// copyEntity.setRuleInfo(configRule); +// //端字段含义 +// fieldName = fieldMap.get(field); +// //检查数据 +// inputText = inputMap.get(field); +// +// copyEntity.setFieldName(fieldName); +// +// copyEntity.setInputText(inputText); +// +// checkSemanticModelMap.put(field, copyEntity); +// } + } + } + } + return checkSemanticModelMap; + } + // 自定义的脱敏方法,对字段进行半脱敏 private String desensitizeText(String text) { StringBuilder sb = new StringBuilder(text); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrRuleCheckServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrRuleCheckServiceImpl.java index 98cd3e7..b7825db 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrRuleCheckServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrRuleCheckServiceImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.ocr.service.impl; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -18,13 +19,16 @@ import org.jeecg.modules.ocr.mapper.OcrRuleCheckMapper; import org.jeecg.modules.ocr.service.IOcrRuleCheckDetailService; import org.jeecg.modules.ocr.service.IOcrRuleCheckService; import org.jeecg.modules.ocr.vo.SaveOcrRuleCheckVO; +import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -96,6 +100,88 @@ public class OcrRuleCheckServiceImpl extends ServiceImpl list=new ArrayList<>(); + for(int i=0;i keySet = new HashSet<>(configRuleMap.keySet()); +// //循环keySet,判断字段是否是缩写,如果是缩写就把缩写的全称put一下 +// for (String s : keySet) { +// String value = configRuleMap.get(s); +// if ("hn".equals(s)) { +// configRuleMap.put("hospitalName",value); +// }else if("dn".equals(s)) { +// configRuleMap.put("doctorName", value); +// }else if("dmn".equals(s)) { +// configRuleMap.put("departmentName", value); +// }else if("tm".equals(s) || ("time".equals(s))) { +// configRuleMap.put("time", value); +// }else{ +// configRuleMap.put(s,value); +// } +// } + } + //hn=40&&(dmn=0||dn=0) + } + if (StringUtils.isNotBlank(ocrRuleCheckVo.getMetadataConfigId())) { + String metadataConfigId = ocrRuleCheckVo.getMetadataConfigId(); + List ocrMetadataConfigDetails = ocrMetadataConfigDetailMapper.selectList(new LambdaQueryWrapper().eq(OcrMetadataConfigDetail::getMetadataConfigId, metadataConfigId)); + Map fieldMap=new LinkedHashMap<>(); + for (OcrMetadataConfigDetail ocrMetadataConfigDetail : ocrMetadataConfigDetails) { + fieldMap.put(ocrMetadataConfigDetail.getFieldName(),ocrMetadataConfigDetail.getGetField()); + } + ocrRuleCheckVo.setFieldMap(fieldMap); + } + return ocrRuleCheckVo; + } @Override public OcrRuleCheck updateModel(SaveOcrRuleCheckVO saveOcrRuleCheckVO) { @@ -148,6 +234,99 @@ public class OcrRuleCheckServiceImpl extends ServiceImpl=","") + .replaceAll(">","") + .replaceAll("<","") + .replaceAll("=",""); + } + public static boolean compare(char cur, char peek) {// 如果是peek优先级高于cur,返回true,默认都是peek优先级要低 + int[] operatPriority = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 }; + boolean result = false; + System.out.println(peek+cur); + if (operatPriority[(peek) - 40] >= operatPriority[(cur) - 40]) { + result = true; + } + return result; + } + public static void main(String[] args) throws ScriptException { + String str="((hn=40)&((dmn=0&tm=2)|dn=0))"; + StringBuffer sb=new StringBuffer(); + System.out.println(str); + configRuleAdapter(new StringBuffer(str),"&",sb); + System.out.println(sb); + } + static boolean isMatch(String s){ + //定义左右括号的对应关系 + Map bracket = new HashMap<>(); + bracket.put(')','('); + bracket.put(']','['); + bracket.put('}','{'); + Stack stack = new Stack(); + for(int i = 0; i < s.length(); i++){ + Character temp = s.charAt(i);//先转换成字符 + //是否为左括号 + if(bracket.containsValue(temp)){ + stack.push(temp); + //是否为右括号 + }else if(bracket.containsKey(temp)){ + if(stack.isEmpty()){ + return false; + } + //若左右括号匹配 + if(stack.peek() == bracket.get(temp)){ + stack.pop(); + } + else{ + return false; + } + } + } + return stack.isEmpty()? true: false; + } + public static String replaceFunctionStr(String text){ + return text.replaceAll("hn","H").replaceAll("dmn","D").replaceAll("dn","N").replaceAll("&","K").replaceAll("\\|","L"); + } + public static String zkh="(",ykh=")",hz="||",bq="&",dy="=",th="!"; + + public static int strNumber(String zf,String str){ + int oldCount=str.length(); + int newCount=str.replace(zf,"").length(); + return oldCount-newCount/zf.length(); + } + public static boolean isOperator(char c){ + return c == '(' || c == ')'; + } + public static boolean isExpression(String op){ + return op.contains("&")||op.contains("|"); + } + public static boolean isFlagOp(String op){ + return op.contains(">")||op.contains("<")||op.contains("!="); + } + public static boolean isExpressOp(String op){ + return op.equals("H")||op.equals("D")||op.equals("N")||op.equals("O"); + } + public static boolean isOtherOp(String op){ + return op.equals(","); + } + public static boolean isNumber(String op){ + return op.matches("\\d+(\\.\\d+)?"); + } + public static boolean isString(String op){ + return op.matches("[\\u4e00-\\u9fa50-9a-zA-Z-]{1,}$"); + } + public static int priority(String op){ + if(op.equals("*")||op.equals("/")||isFlagOp(op)||isExpressOp(op)){ + return 1; + }else if(op.equals("+")||op.equals("-")){ + return 0; + } + return -1; + } + @Override public OcrRuleCheckDTO findById(String id) { @@ -200,14 +379,4 @@ public class OcrRuleCheckServiceImpl extends ServiceImpl identifyDetails) { String requestId = ocrIdentify.getRequestId(); + log.info("数据准备:{}",ocrIdentify); //请求对象 CallBackWlyResult result = new CallBackWlyResult(); @@ -76,6 +77,7 @@ public class CallBackWlyUtils { result.setRetrieveReviewCompliance(imageTagRetrievePercentage+""); result.setFailureReason(ocrIdentify.getErrorMsg()); if (CollectionUtils.isEmpty(jsonObjects)) { + log.info("结果为空不给无量云推送:{}",jsonObjects); return false; } result.setOcrResult(jsonObjects); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java index 3311d68..c96fc5e 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java @@ -84,10 +84,13 @@ public class RandImageUtil { } private static BufferedImage getImageBuffer(String resultCode){ + System.out.println("验证码:"+resultCode); // 在内存中创建图象 final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); + System.out.println("image:"+image); // 获取图形上下文 final Graphics2D graphics = (Graphics2D) image.getGraphics(); + System.out.println("image11111111111 :"+graphics); // 设定背景颜色 // ---1 graphics.setColor(Color.WHITE); @@ -119,6 +122,9 @@ public class RandImageUtil { // 设置字体样式 // graphics.setFont(new Font("Arial Black", Font.ITALIC, 18)); graphics.setFont(new Font("Times New Roman", Font.BOLD, 24)); + System.out.println("resultCode:"+resultCode); + System.out.println("resultCode i:"+i); + System.out.println("resultCode:"+String.valueOf(resultCode.charAt(i))); // 设置字符,字符间距,上边距 graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26); }