diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/OcrConstant.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/OcrConstant.java index 30074a1..a8a9d87 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/OcrConstant.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/OcrConstant.java @@ -12,9 +12,14 @@ public class OcrConstant { public static String ruleCheckSplitChar="&"; /** - * OCR任务状态 0 执行中,1执行 + * OCR任务状态 0 识别中,1已识别 */ public static String task_Executing_STATUS="0"; public static String task_OVER_STATUS="1"; + + /** + * Api 通用识别接口 + */ + public static String api_test_identify_url="http://47.103.213.109:8071/aitest/semantic"; } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/OcrStatusEnum.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/OcrStatusEnum.java new file mode 100644 index 0000000..127c7be --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/OcrStatusEnum.java @@ -0,0 +1,74 @@ +package org.jeecg.common.constant.enums; + +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.OcrConstant; + +/** + * @Description + * @Author ZhouWenTao + * @Date 2023/7/25 15:05 + */ +public enum OcrStatusEnum { + /** + * 0 识别中 + */ + EXECUTING(OcrConstant.task_Executing_STATUS, "识别中"), + /** + * 1 已识别 + */ + OVER(OcrConstant.task_OVER_STATUS, "已识别"); + + + /** + * 类型 1列表,2新增,3编辑,4删除,5导入,6导出 + */ + String status; + + /** + * 编码(请求方式) + */ + String name; + + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * 构造器 + * + * @param status 类型 + * @param name 描述 + */ + OcrStatusEnum(String status, String name) { + this.status = status; + this.name = name; + } + + + /** + * 根据状态编码匹配 + * @param status 状态编码 + * @return String 状态名称 + */ + public static String getStatusTypeNameByStatus(String status) { + for (OcrStatusEnum e : OcrStatusEnum.values()) { + if (status.equals(e.getStatus())) { + return e.getName(); + } + } + return null; + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java index ef0d10f..2176357 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java @@ -57,8 +57,8 @@ public class RestUtil { static { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - requestFactory.setConnectTimeout(3000); - requestFactory.setReadTimeout(3000); + requestFactory.setConnectTimeout(300000); + requestFactory.setReadTimeout(300000); RT = new RestTemplate(requestFactory); // 解决乱码问题 RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); 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 0eb96bb..aa02958 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 @@ -6,13 +6,15 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; import org.jeecg.common.api.vo.Result; -import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.util.AssertUtils; +import org.jeecg.common.util.RedisUtil; import org.jeecg.modules.ocr.entity.OcrRuleCheck; -import org.jeecg.modules.ocr.model.OcrMetadataConfigSaveModel; +import org.jeecg.modules.ocr.model.TaskModel; import org.jeecg.modules.ocr.service.IOcrRuleCheckService; import org.jeecg.modules.ocr.vo.OcrRuleCheckVo; +import org.springframework.scheduling.annotation.Async; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -20,9 +22,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; /** * @Description @@ -32,11 +35,16 @@ import java.util.List; @Slf4j @RestController @RequestMapping("/api") +@Async public class ApiController { @Resource private IOcrRuleCheckService ocrRuleCheckService; + @Resource + private RedisUtil redisUtil; + + ////===================================================================伪接口 - @ApiOperation(value="通用识别", notes="通用识别") + @ApiOperation(value = "通用识别", notes = "通用识别") @PostMapping(value = "/identify") @Transactional(rollbackFor = Exception.class) public JSONObject identify(@RequestBody JSONObject jsonObject) { @@ -48,31 +56,31 @@ public class ApiController { JSONArray sourceJson = jsonObject.getJSONArray("sourceJson");//校验数据源 List sourceJsonList = sourceJson.toJavaList(JSONObject.class); - AssertUtils.notEmpty(requestId,"请输入[请求唯一标识]"); - AssertUtils.notEmpty(scenes,"请输入[场景类型]"); - AssertUtils.notEmpty(ruleId,"请输入[规则标识]"); - AssertUtils.notEmpty(sourceImages,"请输入[ocr图片集]"); - AssertUtils.notEmpty(priority,"请输入[任务优先级]"); - AssertUtils.notNull(sourceJson,"请输入[校验数据源]"); + AssertUtils.notEmpty(requestId, "请输入[请求唯一标识]"); + AssertUtils.notEmpty(scenes, "请输入[场景类型]"); + AssertUtils.notEmpty(ruleId, "请输入[规则标识]"); + AssertUtils.notEmpty(sourceImages, "请输入[ocr图片集]"); + AssertUtils.notEmpty(priority, "请输入[任务优先级]"); + AssertUtils.notNull(sourceJson, "请输入[校验数据源]"); return JSONObject.parseObject("{\"error_code\": 1, \"error_msg\": \"请求成功\"}"); } - @ApiOperation(value="获取规则", notes="获取规则") + @ApiOperation(value = "获取规则", notes = "获取规则") @PostMapping(value = "/getRule") @Transactional(rollbackFor = Exception.class) public Result> getRule() { IPage ocrRuleCheckVoIPage = ocrRuleCheckService.pageVo(new Page(1, Integer.MAX_VALUE), new OcrRuleCheck()); List records = new ArrayList<>(); - JSONObject copyEntity=new JSONObject(); + JSONObject copyEntity = new JSONObject(); for (OcrRuleCheckVo record : ocrRuleCheckVoIPage.getRecords()) { copyEntity = new JSONObject(); - copyEntity.put("ruleId",record.getId()); - copyEntity.put("ruleName",record.getConfigName()); - copyEntity.put("ruleInfo",record.getConfigRule()); - copyEntity.put("metadataId",record.getMetadataConfigId()); - copyEntity.put("metadataName",record.getMetadataConfigName()); - copyEntity.put("createTime",record.getCreateTime()); - copyEntity.put("createPeople",record.getCreateBy()); + copyEntity.put("ruleId", record.getId()); + copyEntity.put("ruleName", record.getConfigName()); + copyEntity.put("ruleInfo", record.getConfigRule()); + copyEntity.put("metadataId", record.getMetadataConfigId()); + copyEntity.put("metadataName", record.getMetadataConfigName()); + copyEntity.put("createTime", record.getCreateTime()); + copyEntity.put("createPeople", record.getCreateBy()); records.add(copyEntity); } return Result.OK(records); @@ -84,7 +92,7 @@ public class ApiController { } - @ApiOperation(value="单张图片异步通知", notes="单张图片异步通知") + @ApiOperation(value = "单张图片异步通知", notes = "单张图片异步通知") @PostMapping(value = "/imgNotify") @Transactional(rollbackFor = Exception.class) public JSONObject imgNotify() { @@ -95,7 +103,7 @@ public class ApiController { return JSONObject.parseObject("{\"requestId\":\"10001\",\"result\":{\"tag\":\"hospitalName\",\"inputText\":\"仁和医院\",\"ocrText\":\"仁和医院\",\"ocrPrecisionRate\":0.8,\"ruleValidation\":true,\"sourceImage\":{\"fileName\":\"test1.png\",\"path\":\"/usr/local/ocr/test1.png\"},\"failureReason\":\"图片不清晰\"}}"); } - @ApiOperation(value="任务完结通知", notes="任务完结通知") + @ApiOperation(value = "任务完结通知", notes = "任务完结通知") @PostMapping(value = "/taskNotify") @Transactional(rollbackFor = Exception.class) public JSONObject taskNotify() { @@ -106,4 +114,170 @@ public class ApiController { return JSONObject.parseObject("{\"requestId\":\"10001\",\"result\":{\"retrieveReviewCompliance\":\"80\",\"imageTagRetrievePercentage\":\"66.6\",\"failureReason\":\"图片不清晰\"}}"); } //========================================================================================== + + @ApiOperation(value = "模拟创建任务", notes = "模拟创建任务") + @PostMapping(value = "/pushTask") + @Transactional(rollbackFor = Exception.class) + public Result pushTask(@RequestBody JSONObject jsonObject) { + //获取优先级1的任务 + String taskId = jsonObject.getString("taskId"); + String taskType = jsonObject.getString("taskType"); + int taskLevel= jsonObject.getInteger("taskLevel"); + String task_1 = (String) redisUtil.get("task_"+taskLevel); + if (task_1 == null || task_1.equals("[]")) { + //无历史任务 + TaskModel task = new TaskModel(); + task.setTaskId(taskId); + task.setTaskType(taskType); + task.setTaskStatus("0");//任务 待运行 + task.setTaskLevel(taskLevel); + List jsonObjects = Arrays.asList(task); + task_1 = JSONObject.toJSONString(jsonObjects); + } else { + //有历史任务 + JSONArray jsonArray = JSONObject.parseArray(task_1); + if (jsonArray != null) { + List taskList = jsonArray.toJavaList(TaskModel.class); + List staskList = taskList.stream().filter(t -> t.getTaskId().equals(taskId)).collect(Collectors.toList()); + TaskModel task = null; + if (staskList==null || staskList.size()==0) { + //该任务不存在, 看看 库表里 该任务是否已执行成功了 + String overTask = (String) redisUtil.get("over_task"); + if (StringUtils.isNotBlank(overTask)&&Arrays.asList(overTask.split(",")).contains(taskId)) { + //库表里已执行过 + return Result.OK("该任务已执行结束"); + } else { + //库表中未执行过,追加任务 + taskList.add(new TaskModel(taskId, taskLevel, taskType, "0", "")); + task_1 = JSONObject.toJSONString(taskList); + } + } else if ("0".equals(staskList.get(0).getTaskStatus())) { + //该任务 待运行 + return Result.OK("该任务还处于排队中"); + } else if ("1".equals(staskList.get(0).getTaskStatus())) { + //该任务 运行中 + return Result.OK("该任务还处于运行中"); + } + } + } + //存入redis + redisUtil.set("task_"+taskLevel, task_1); + //执行任务 + executeTask(); + return Result.OK("已追加到任务"); + } + + @Transactional(rollbackFor = Exception.class) + @Async + public void executeTask() { + //获取任务 + List taskList=getTaskList(); + //查看是否有执行中的任务 + long executingCount = taskList.stream().filter(t -> t.getTaskStatus().equals("1")).count(); + if (executingCount>0) { + //该方法正在执行中 + log.error("该方法正在执行中"); + } + List waitingTaskList = taskList.stream().filter(t -> t.getTaskStatus().equals("0")).collect(Collectors.toList()); + if (waitingTaskList!=null) { + while (waitingTaskList.size()>0){ + //取第一个任务 + TaskModel taskModel = waitingTaskList.get(0); + waitingTaskList.get(0).setTaskStatus("1"); + //刷新redis,执行中 + flushTask(taskModel.getTaskId(),1); + //执行 + executeTaskp(taskModel); + //刷新已知任务 + taskList=getTaskList(); + //刷新待运行任务 + waitingTaskList = taskList.stream().filter(t -> t.getTaskStatus().equals("0")).collect(Collectors.toList()); + } + } + log.error("任务已全部执行"); + } + + /** + * 刷新任务状态 + * @param taskId + * @param status 状态 1 运行中,2 已结束 + */ + public void flushTask(String taskId,int status) { + List taskList = getTaskList(); + if (taskList!=null && taskList.size()>0) { + TaskModel taskModel = taskList.stream().filter(t -> t.getTaskId().equals(taskId)).findFirst().get(); + if (taskModel!=null) { + int taskLevel = taskModel.getTaskLevel(); + String task=(String) redisUtil.get("task_"+taskLevel); + JSONArray taskJsonArray = JSONObject.parseArray(task); + taskList=new ArrayList<>(); + if (task!=null) { + taskList.addAll(taskJsonArray.toJavaList(TaskModel.class)); + } + if (status==1) { + //更新任务状态 + taskList.forEach(t->{ + if (t.getTaskId().equals(taskId)) { + t.setTaskStatus("1"); + } + }); + }else if(status==2){ + //删除任务 + taskList=taskList.stream().filter(t->!t.getTaskId().equals(taskId)).collect(Collectors.toList()); + } + String s = JSONObject.toJSONString(taskList); + //存入redis + redisUtil.set("task_"+taskLevel,s); + } + } + } + + //执行任务 + public void executeTaskp(TaskModel taskModel){ + //睡眠 + try { + Thread.sleep(20000l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //模拟执行成功 + String overTaskIds = (String) redisUtil.get("over_task"); + if (StringUtils.isBlank(overTaskIds)) { + overTaskIds=taskModel.getTaskId(); + }else{ + if (!Arrays.asList(overTaskIds.split(",")).contains(taskModel.getTaskId())) { + //该任务未执行过 + overTaskIds+=","+taskModel.getTaskId(); + }else{ + //该任务已结束过 + } + } + //存入已执行 redis里 + redisUtil.set("over_task",overTaskIds); + log.error( taskModel.getTaskLevel()+"-级别,"+ taskModel.getTaskId()+"-已执行"); + //从3中任务集中,删除该任务 + flushTask(taskModel.getTaskId(),2); + } + + //获取全部任务 + public List getTaskList(){ + String task_1 = (String) redisUtil.get("task_1"); + String task_2 = (String) redisUtil.get("task_2"); + String task_3 = (String) redisUtil.get("task_3"); + JSONArray task1JsonArray = JSONObject.parseArray(task_1); + JSONArray task2JsonArray = JSONObject.parseArray(task_2); + JSONArray task3JsonArray = JSONObject.parseArray(task_3); + List taskList=new ArrayList<>(); + if (task1JsonArray!=null) { + taskList.addAll(task1JsonArray.toJavaList(TaskModel.class)); + } + if (task2JsonArray!=null) { + taskList.addAll(task2JsonArray.toJavaList(TaskModel.class)); + } + if (task3JsonArray!=null) { + taskList.addAll(task3JsonArray.toJavaList(TaskModel.class)); + } + return taskList; + } + } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrApiController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrApiController.java index cf725a7..43cdd8c 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrApiController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/controller/OcrApiController.java @@ -2,6 +2,7 @@ package org.jeecg.modules.ocr.controller; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.api.vo.Result; @@ -9,9 +10,11 @@ import org.jeecg.common.util.AssertUtils; import org.jeecg.common.util.RestUtil; import org.jeecg.modules.ocr.entity.OcrApiCallStatistics; import org.jeecg.modules.ocr.entity.OcrIdentify; +import org.jeecg.modules.ocr.entity.OcrTaskType; import org.jeecg.modules.ocr.service.IOcrApiCallStatisticsService; import org.jeecg.modules.ocr.service.IOcrIdentifyService; import org.jeecg.modules.ocr.service.IOcrRuleCheckService; +import org.jeecg.modules.ocr.service.IOcrTaskTypeService; import org.jeecg.modules.ocr.vo.OcrRuleCheckVo; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestBody; @@ -19,6 +22,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.io.File; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; @@ -38,87 +43,60 @@ public class OcrApiController { IOcrRuleCheckService ruleCheckService; @Resource IOcrApiCallStatisticsService ocrApiCallStatisticsService; - + @Resource + IOcrTaskTypeService ocrTaskTypeService; public static final String semanticUrl="http://47.103.213.109:9099/semantic"; -/** - * 1. 收到 任务 入参 任务id,图片路径[] - * POST /semantic - * application/json - * 2. 调用java接口,入参 - * 任务id, - * 图片路径, - * 语义化结果( - * { - * "医院名称":[ - * { - * "ocrText":"从北京到广东医科大学附属医院", - * "text": "广东医科大学附属医院", - * "area": [] - * },{},{} - * ], - * "科室": [{}], - * "时间": [{}] - * "姓名": [{}] - * } - * ) - * message: "成功" - * 任务是否完成 0 未完成,1 完成 - */ - -/** - * task_id: "11", - * img_path: "/usr/ssss/img.jpg", - * semantic_result: -* { -* "医院名称":[ -* { -* "ocrText":"从北京到广东医科大学附属医院", -* "text": "广东医科大学附属医院", -* "area": [] -* }, -* ], -* "科室": [{}], -* "时间": [{}] -* "姓名": [{}] -* } - * message: "成功" - */ - @ApiOperation(value = "通用识别") @RequestMapping("/identify") @Transactional public Result pushSemantic(@RequestBody JSONObject requestBody){ - //String taskId="1681203097437954049";//任务id - //List imagesUrl= Arrays.asList("https://h5.mcnetmart.com/tmp/images/dc_demo1.png");//图片路径 - /*for (String image : imagesUrl) { - JSONObject jsonObject=new JSONObject(); - jsonObject.put("taskId",taskId); - jsonObject.put("images",Arrays.asList(image)); - //请求 ocr识别即可 - JSONObject postResponse = RestUtil.post("", jsonObject); - //获取返回结果 - - }*/ //1.获取请求参数 String requestId = requestBody.getString("requestId");//请求唯一标识 - AssertUtils.notNull(requestId,"[requestId]-不可为空"); String scenes = requestBody.getString("scenes");//场景类型:door=门头照片,cases=病例,bill=票据 - AssertUtils.notTrue(!"door".equals(scenes),String.format("暂不支持该场景类型[%s]",scenes)); String ruleId = requestBody.getString("ruleId");//规则标识 - AssertUtils.notNull(ruleId,"[ruleId]-不可为空"); - OcrRuleCheckVo ruleCheck = ruleCheckService.findById(ruleId); Integer priority = requestBody.getInteger("priority");//任务优先级:1=加急,0=不加急 + String sourceImages = requestBody.getString("sourceImages");//ocr图片集 JSONArray sourceJson = requestBody.getJSONArray("sourceJson"); - + List sourceJsonList = sourceJson.toJavaList(JSONObject.class);//校验数据源 + //============================================================= + //2.参数判断 + AssertUtils.notNull(requestId,"[requestId]-不可为空"); + AssertUtils.notTrue(!"door".equals(scenes),String.format("暂不支持该场景类型[%s]",scenes)); + AssertUtils.notNull(ruleId,"[ruleId]-不可为空"); + OcrRuleCheckVo ruleCheck = ruleCheckService.findById(ruleId); AssertUtils.notNull(ruleCheck,"[ruleId]-不存在"); AssertUtils.notNull(priority,"[priority]-不可为空"); AssertUtils.notNull(sourceJson,"[sourceJson]-不可为空"); - List sourceJsonList = sourceJson.toJavaList(JSONObject.class);//校验数据源 - String sourceImages = requestBody.getString("sourceImages");//ocr图片集 - - + //获取识别的图片 + List fileList=new ArrayList<>(); + if (sourceImages.indexOf("http://")!=-1||sourceImages.indexOf("https://")!=-1) { + //判断附件是否是 图片格式 + AssertUtils.isTrue(sourceImages.lastIndexOf(".png")!=-1 || sourceImages.lastIndexOf(".jpg")!=-1|| + sourceImages.lastIndexOf(".jpeg")!=-1,"当前网络图片格式不支持"); + //网络图片 + fileList.add(sourceImages); + }else{ + //本地附件 + if(false){ + File sourceImagesIile = new File(sourceImages); + AssertUtils.isTrue(sourceImagesIile.exists(),"当前本地目录不存在"); + File[] files = sourceImagesIile.listFiles(); + for (File file : files) { + if (file.getAbsolutePath().lastIndexOf(".png")==-1&&file.getAbsolutePath().lastIndexOf(".jpg")==-1&& + file.getAbsolutePath().lastIndexOf(".jpeg")==-1) { + continue; + } + fileList.add(file.getAbsolutePath()); + } + }else{ + AssertUtils.notTrue(true,"当前仅支持网络图片"); + AssertUtils.isTrue(sourceImages.lastIndexOf(".png")!=-1 || sourceImages.lastIndexOf(".jpg")!=-1|| + sourceImages.lastIndexOf(".jpeg")!=-1,"当前图片格式不支持"); + } + } + AssertUtils.isTrue(fileList.size()!=0,"未获取到图片真实地址"); OcrIdentify ocrIdentify=new OcrIdentify(); //2.创建识别任务 if(true){ @@ -127,27 +105,20 @@ public class OcrApiController { ocrIdentify.setStatus("0");//任务进行中 ocrIdentify.setRuleCheck(ruleId);//配置规则检查id ocrIdentify.setStartTime(new Date());//开始时间 - ocrIdentify.setTaskType("1681508355389231105");//任务类型 + if (scenes.equals("door")) { + ocrIdentify.setTaskType("1683412752926986241");//任务类型 + } ocrIdentify.setMetadataConfigId(ruleCheck.getMetadataConfigId());//规则配置的元数据id ocrIdentify.setTaskSource("API");//任务来源 - ocrIdentify.setIdentifyUrl("https://h5.mcnetmart.com/tmp/images/dc_demo1.png");//识别图片地址 + ocrIdentify.setIdentifyUrl(sourceImages);//识别图片地址 ocrIdentify.setCreateBy("API请求");//创建人 ocrIdentify.setSourceJson(requestBody.getJSONArray("sourceJson").toJSONString());//校验数据源 ocrIdentifyService.save(ocrIdentify); } - //2.1记录 - if(true){ - OcrApiCallStatistics ocrApiCallStatistics=new OcrApiCallStatistics(); - ocrApiCallStatistics.setApiName("通用识别"); - ocrApiCallStatistics.setApiUrl("/ocr/ocrApi/identify"); - ocrApiCallStatistics.setCount(1); - ocrApiCallStatistics.setStartTime(new Date()); - ocrApiCallStatistics.setEndTime(new Date()); - ocrApiCallStatisticsService.save(ocrApiCallStatistics); - } - //3.请求python ocr识别,异步执行 - ocrIdentifyService.postSemantic(ocrIdentify.getId(),"https://h5.mcnetmart.com/tmp/images/dc_demo1.png"); + for (String file : fileList) { + ocrIdentifyService.postSemantic(ocrIdentify,fileList); + } return Result.OK("请求成功"); } 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 3410dea..9701c1e 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 @@ -1,14 +1,18 @@ package org.jeecg.modules.ocr.controller; import java.util.Arrays; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.constant.OcrConstant; +import org.jeecg.common.constant.enums.OcrStatusEnum; import org.jeecg.common.system.query.QueryGenerator; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.util.AssertUtils; import org.jeecg.modules.ocr.entity.OcrIdentify; import org.jeecg.modules.ocr.entity.OcrMetadataConfig; import org.jeecg.modules.ocr.service.IOcrIdentifyService; @@ -73,7 +77,7 @@ public class OcrIdentifyController extends JeecgController add(@RequestBody OcrIdentify ocrIdentify) { ocrIdentifyService.save(ocrIdentify); //请求ocr识别接口 - ocrIdentifyService.postSemantic(ocrIdentify.getId(),ocrIdentify.getIdentifyUrl()); + //ocrIdentifyService.postSemantic(ocrIdentify.getId(),Arrays.asList(ocrIdentify.getIdentifyUrl())); return Result.OK("添加成功!"); } @@ -103,6 +107,8 @@ public class OcrIdentifyController extends JeecgController delete(@RequestParam(name="id",required=true) String id) { + OcrIdentify ocrIdentify = ocrIdentifyService.getById(id); + AssertUtils.isTrue(OcrStatusEnum.OVER.getStatus().equals(ocrIdentify.getStatus()),"当前ocr识别状态不可删除"); ocrIdentifyService.removeById(id); return Result.OK("删除成功!"); } @@ -118,13 +124,16 @@ public class OcrIdentifyController extends JeecgController deleteBatch(@RequestParam(name="ids",required=true) String ids) { + List ocrIdentifies = ocrIdentifyService.listByIds(Arrays.asList(ids.split(","))); + for (OcrIdentify ocrIdentify : ocrIdentifies) { + AssertUtils.isTrue(OcrStatusEnum.OVER.getStatus().equals(ocrIdentify.getStatus()),"当前ocr识别状态不可删除"); + } this.ocrIdentifyService.removeByIds(Arrays.asList(ids.split(","))); return Result.OK("批量删除成功!"); } /** * 通过id查询 - * * @param id * @return */ diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/model/TaskModel.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/model/TaskModel.java new file mode 100644 index 0000000..14eac05 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/model/TaskModel.java @@ -0,0 +1,33 @@ +package org.jeecg.modules.ocr.model; + +import lombok.Data; + +/** + * @Description 存入任务队列 对象 + * @Author ZhouWenTao + * @Date 2023/7/25 16:19 + */ +@Data +public class TaskModel { + //任务id + private String taskId; + //任务等级 1,2,3 + private int taskLevel; + //任务类型 + private String taskType; + //任务状态 0待执行,1执行中 + private String taskStatus; + //任务参数 + private String parameter; + + public TaskModel() { + } + + public TaskModel(String taskId, int taskLevel, String taskType, String taskStatus, String parameter) { + this.taskId = taskId; + this.taskLevel = taskLevel; + this.taskType = taskType; + this.taskStatus = taskStatus; + this.parameter = parameter; + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrApiCallStatisticsService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrApiCallStatisticsService.java index a8cec32..6e6619b 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrApiCallStatisticsService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/IOcrApiCallStatisticsService.java @@ -14,4 +14,6 @@ import org.jeecg.modules.ocr.entity.OcrApiCallStatistics; public interface IOcrApiCallStatisticsService extends IService { IPage pageList(Page page, OcrApiCallStatistics ocrApiCallStatistics); + + void saveLogs(String apiName, String apiUrl, int count); } 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 1a8a806..82ea398 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 @@ -2,10 +2,13 @@ package org.jeecg.modules.ocr.service; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.common.api.vo.Result; import org.jeecg.modules.ocr.entity.OcrIdentify; import org.jeecg.modules.ocr.vo.OcrIdentifyVo; import org.springframework.scheduling.annotation.Async; +import java.util.List; + /** * @Description: ocr识别 * @Author: jeecg-boot @@ -21,5 +24,14 @@ public interface IOcrIdentifyService extends IService { public void getSemanticInfo(JSONObject responseBody); @Async - void postSemantic(String id, String identifyUrl); + void postSemantic(OcrIdentify ocrIdentify, List identifyUrlList); + + void updateOcrIdentifyStatus(String id,String status); + + /** + * 发送执行任务计划 + * @param jsonObject + * @return + */ + Result pushTask(JSONObject jsonObject); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrApiCallStatisticsServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrApiCallStatisticsServiceImpl.java index a72e23b..8609442 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrApiCallStatisticsServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/ocr/service/impl/OcrApiCallStatisticsServiceImpl.java @@ -8,6 +8,7 @@ import org.jeecg.modules.ocr.service.IOcrApiCallStatisticsService; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @@ -30,4 +31,15 @@ public class OcrApiCallStatisticsServiceImpl extends ServiceImpl pageList = this.baseMapper.pageList(page,map); return pageList; } + + @Override + public void saveLogs(String apiName, String apiUrl, int count) { + OcrApiCallStatistics ocrApiCallStatistics = new OcrApiCallStatistics(); + ocrApiCallStatistics.setApiName(apiName); + ocrApiCallStatistics.setApiUrl(apiUrl); + ocrApiCallStatistics.setCount(count); + ocrApiCallStatistics.setStartTime(new Date()); + ocrApiCallStatistics.setEndTime(null); + super.save(ocrApiCallStatistics); + } } 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 7636a30..5d8a0fa 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 @@ -7,6 +7,10 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.units.qual.C; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.constant.OcrConstant; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.common.util.RestUtil; import org.jeecg.modules.ocr.entity.OcrIdentify; import org.jeecg.modules.ocr.entity.OcrIdentifyDetail; import org.jeecg.modules.ocr.entity.OcrRuleCheck; @@ -14,10 +18,8 @@ import org.jeecg.modules.ocr.mapper.OcrIdentifyMapper; import org.jeecg.modules.ocr.model.CheckSemanticModel; import org.jeecg.modules.ocr.model.OcrResult; import org.jeecg.modules.ocr.model.SourceImage; -import org.jeecg.modules.ocr.service.IOcrIdentifyDetailService; -import org.jeecg.modules.ocr.service.IOcrIdentifyService; -import org.jeecg.modules.ocr.service.IOcrRuleCheckDetailService; -import org.jeecg.modules.ocr.service.IOcrRuleCheckService; +import org.jeecg.modules.ocr.model.TaskModel; +import org.jeecg.modules.ocr.service.*; import org.jeecg.modules.ocr.utils.ArrayCUtils; import org.jeecg.modules.ocr.vo.OcrIdentifyVo; import org.jeecg.modules.ocr.vo.OcrRuleCheckVo; @@ -26,6 +28,8 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; import javax.annotation.Resource; import java.util.*; @@ -34,7 +38,7 @@ import java.util.stream.Collectors; /** * @Description: ocr识别 * @Author: jeecg-boot - * @Date: 2023-07-14 + * @Date: 2023-07-14 * @Version: V1.0 */ @Service @@ -46,10 +50,14 @@ public class OcrIdentifyServiceImpl extends ServiceImpl jsonObjects = jsonArray.toJavaList(JSONObject.class); @@ -68,16 +76,17 @@ public class OcrIdentifyServiceImpl extends ServiceImpl checkSemanticModelMap = getCheckSemanticModelMap(ocrRuleCheckVo.getConfigRuleMap(), ocrRuleCheckVo.getFieldMap(),ocrIdentifyVo.getSourceJsonObjects()); + Map checkSemanticModelMap = getCheckSemanticModelMap(ocrRuleCheckVo.getConfigRuleMap(), ocrRuleCheckVo.getFieldMap(), ocrIdentifyVo.getSourceJsonObjects()); //// String text;//ocr 识别的文本, - Double probability=0d; + Double probability = 0d; //用于数据结构化的对象 - List ocrResultList=new ArrayList<>(); + List ocrResultList = new ArrayList<>(); - StringBuffer rMessage=new StringBuffer(); - Map fieldRightMap=new LinkedHashMap<>();//存放 字段判断正确map + StringBuffer rMessage = new StringBuffer(); + Map fieldRightMap = new LinkedHashMap<>();//存放 字段判断正确map //========================== - checkSemanticFor: for (CheckSemanticModel value : checkSemanticModelMap.values()) { + checkSemanticFor: + for (CheckSemanticModel value : checkSemanticModelMap.values()) { String field = value.getField(); String fieldName = value.getFieldName();//校验的字段名称 String ruleInfo = value.getRuleInfo();//是否绝对判断 0-绝对判断,1-不绝对判断 @@ -125,45 +135,46 @@ public class OcrIdentifyServiceImpl extends ServiceImpl ocrArray=new ArrayList<>(); + List ocrArray = new ArrayList<>(); for (String s : fieldNameList) { JSONArray jsonArray = semanticResult.getJSONArray(s); - if (jsonArray!=null&& jsonArray.size()>0) { + if (jsonArray != null && jsonArray.size() > 0) { ocrArray.addAll(jsonArray.toJavaList(JSONObject.class)); } } - ocrArrayFor:for (int i = 0; i < ocrArray.size(); i++) { + ocrArrayFor: + for (int i = 0; i < ocrArray.size(); i++) { JSONObject ocrItem = ocrArray.get(i); text = ocrItem.getString("text");//ocr 识别的文本 probability = ocrItem.getDouble("probability");//置信度 // 1 不需要校验,只需要有返回ocr识别值 if ("1".equals(ruleInfo) && StringUtils.isNotBlank(text)) { - ocrResultAdd(ocrResultList,field,inputText,text,probability,imgPath,"",true); - fieldRightMap.put(field,true); - }else{ - if (StringUtils.isBlank(text) ||!text.contains(inputText)) { + ocrResultAdd(ocrResultList, field, inputText, text, probability, imgPath, "", true); + fieldRightMap.put(field, true); + } else { + if (StringUtils.isBlank(text) || !text.contains(inputText)) { //识别结果为空,识别结果 匹配不上 校验文本 - mapPutIfTrue(fieldRightMap,field,false); - rMessage.append(value.getFieldName()+"不匹配
"); - ocrResultAdd(ocrResultList,field,inputText,text,probability,imgPath,value.getFieldName()+"不匹配",false); - }else{ - ocrResultAdd(ocrResultList,field,inputText,text,probability,imgPath,"",true); - fieldRightMap.put(field,true); + mapPutIfTrue(fieldRightMap, field, false); + rMessage.append(value.getFieldName() + "不匹配
"); + ocrResultAdd(ocrResultList, field, inputText, text, probability, imgPath, value.getFieldName() + "不匹配", false); + } else { + ocrResultAdd(ocrResultList, field, inputText, text, probability, imgPath, "", true); + fieldRightMap.put(field, true); } } } - }else{ - rMessage.append(field+"_未查到ocr结果
"); - ocrResultAdd(ocrResultList,field,inputText,null,0d,imgPath,"ocr结果未获取",false); - fieldRightMap.put(field,false); + } else { + rMessage.append(field + "_未查到ocr结果
"); + ocrResultAdd(ocrResultList, field, inputText, null, 0d, imgPath, "ocr结果未获取", false); + fieldRightMap.put(field, false); } } //其中有一个字段 全部都是 失败,则该图片失败. - if (fieldRightMap!=null&&fieldRightMap.values().size()>0&&!fieldRightMap.containsValue(false)) { + if (fieldRightMap != null && fieldRightMap.values().size() > 0 && !fieldRightMap.containsValue(false)) { ocrIdentifyDetail.setStatus("0");//全部通过 - }else{ + } else { ocrIdentifyDetail.setStatus("1");//有失败的 ocrIdentifyDetail.setMessage(rMessage.toString()); } @@ -174,35 +185,62 @@ public class OcrIdentifyServiceImpl extends ServiceImpl identifyUrlList) { //3.请求python ocr识别 - JSONObject semanticResponseJson = JSONObject.parseObject(semanticResponse); - semanticResponseJson.put("task_id",id); - this.getSemanticInfo(semanticResponseJson); + JSONObject requestBody = new JSONObject(); + String id = ocrIdentify.getId(); + String identifyUrl;//识别图片 + String priority = ocrIdentify.getPriority();//加急状态;//任务优先级 + String taskId; + JSONObject semanticResponseJson = new JSONObject(); + + //将主任务存到redis. + StringBuffer task_master = new StringBuffer(); + for (int i = 0; i < identifyUrlList.size(); i++) { + taskId = String.format(id + "_" + (i + 1)); + task_master.append(taskId).append(","); + } + redisUtil.set("identify_" + id, task_master.toString()); + //执行子任务. + for (int i = 0; i < identifyUrlList.size(); i++) { + identifyUrl = identifyUrlList.get(i); + taskId = String.format(id + "_" + (i + 1)); + requestBody.put("taskId", taskId); + requestBody.put("taskLevel", Integer.valueOf(priority)); + requestBody.put("taskType", "identify"); + requestBody.put("parameter",id+","+taskId+","+identifyUrl); + //发送任务请求 到 redis + pushTask(requestBody); + /*semanticResponseJson = RestUtil.post(OcrConstant.api_test_identify_url, requestBody); + semanticResponseJson.put("task_id", id); + this.getSemanticInfo(semanticResponseJson);*/ + } + } + @Override + public void updateOcrIdentifyStatus(String id,String status) { //4.更新主任务状态 - OcrIdentify ocrIdentify=new OcrIdentify(); LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper(); updateWrapper.eq(OcrIdentify::getId, id); updateWrapper.set(OcrIdentify::getEndTime, new Date()); - updateWrapper.set(OcrIdentify::getStatus,"1"); - this.update(updateWrapper); + updateWrapper.set(OcrIdentify::getStatus, "1"); } - public static void mapPutIfTrue(Map map,String key,Boolean flag){ + public static void mapPutIfTrue(Map map, String key, Boolean flag) { if (map.containsKey(key) && (Boolean) map.get(key).equals(true)) { - }else{ - map.put(key,flag); + } else { + map.put(key, flag); } } /** * 将数据 疯转成 OcrResult,追加到 ocrResultList + * * @param ocrResultList * @param field * @param inputText @@ -211,23 +249,23 @@ public class OcrIdentifyServiceImpl extends ServiceImpl ocrResultList,String field,String inputText,String ocrText,Double ocrPrecisionRate,String imgPath,String failureReason,Boolean ruleValidation){ + public static void ocrResultAdd(List ocrResultList, String field, String inputText, String ocrText, Double ocrPrecisionRate, String imgPath, String failureReason, Boolean ruleValidation) { OcrResult ocrResult = new OcrResult(); ocrResult.setTag(field); ocrResult.setOcrText(ocrText); ocrResult.setInputText(inputText); - ocrResult.setOcrPrecisionRate(ocrPrecisionRate==null?0d:ocrPrecisionRate); + ocrResult.setOcrPrecisionRate(ocrPrecisionRate == null ? 0d : ocrPrecisionRate); if (StringUtils.isNotBlank(imgPath)) { SourceImage sourceImage = new SourceImage(); sourceImage.setPath(imgPath); int i = imgPath.lastIndexOf("/"); - sourceImage.setFileName(imgPath.substring(i+1,imgPath.length())); + sourceImage.setFileName(imgPath.substring(i + 1, imgPath.length())); ocrResult.setSourceImage(sourceImage); } ocrResult.setFailureReason(failureReason); - if (ocrResultList==null) { - ocrResultList=new ArrayList<>(); + if (ocrResultList == null) { + ocrResultList = new ArrayList<>(); } ocrResult.setRuleValidation(ruleValidation); ocrResultList.add(ocrResult); @@ -235,37 +273,38 @@ public class OcrIdentifyServiceImpl extends ServiceImpl getCheckSemanticModelMap(Map configRuleMap,Map fieldMap, List sourceJsonObjects){ - Map checkSemanticModelMap=new LinkedHashMap<>(); + public Map getCheckSemanticModelMap(Map configRuleMap, Map fieldMap, List sourceJsonObjects) { + Map checkSemanticModelMap = new LinkedHashMap<>(); //校验正确的值 - Map inputMap=new LinkedHashMap<>(); - if (sourceJsonObjects!=null&&sourceJsonObjects.size()>0) { - String tag,inputText; + Map inputMap = new LinkedHashMap<>(); + if (sourceJsonObjects != null && sourceJsonObjects.size() > 0) { + String tag, inputText; for (JSONObject sourceJsonObject : sourceJsonObjects) { tag = sourceJsonObject.getString("tag"); if (StringUtils.isBlank(tag)) { continue; } inputText = sourceJsonObject.getString("inputText"); - inputMap.put(tag,inputText); + inputMap.put(tag, inputText); } } - CheckSemanticModel copyEntity=null; - String configRule=null,fieldName=null,inputText; - if (fieldMap!=null) { + CheckSemanticModel copyEntity = null; + String configRule = null, fieldName = null, inputText; + if (fieldMap != null) { for (String field : fieldMap.keySet()) { - copyEntity=new CheckSemanticModel(); + copyEntity = new CheckSemanticModel(); copyEntity.setField(field); //1/0 - if (configRuleMap!=null) { + if (configRuleMap != null) { configRule = configRuleMap.get(field); copyEntity.setRuleInfo(configRule); } @@ -278,27 +317,212 @@ public class OcrIdentifyServiceImpl extends ServiceImpl fieldRightMap = new LinkedHashMap<>(); - fieldRightMap.put("zhangsan",false); - fieldRightMap.put("zhangsan4",true); - mapPutIfTrue(fieldRightMap,"zhangsan",true); - mapPutIfTrue(fieldRightMap,"zhangsan2",false); - mapPutIfTrue(fieldRightMap,"zhangsan3",true); - mapPutIfTrue(fieldRightMap,"zhangsan4",false); - for (String s : fieldRightMap.keySet()) { - System.out.println(s+":"+fieldRightMap.get(s)); + /** + * 发送任务 + * @param jsonObject + * @return + */ + @Override + public Result pushTask(JSONObject jsonObject) { + //获取优先级1的任务 + String taskId = jsonObject.getString("taskId"); + String taskType = jsonObject.getString("taskType"); + int taskLevel= jsonObject.getInteger("taskLevel"); + String parameter = jsonObject.getString("parameter"); + String task_ = (String) redisUtil.get("task_"+taskLevel); + if (task_ == null || task_.equals("[]")) { + //无历史任务 + TaskModel task = new TaskModel(taskId,taskLevel,taskType,"0",parameter); + List jsonObjects = Arrays.asList(task); + task_ = JSONObject.toJSONString(jsonObjects); + } else { + //有历史任务 + JSONArray jsonArray = JSONObject.parseArray(task_); + if (jsonArray != null) { + List taskList = jsonArray.toJavaList(TaskModel.class); + List staskList = taskList.stream().filter(t -> t.getTaskId().equals(taskId)).collect(Collectors.toList()); + TaskModel task = null; + if (staskList==null || staskList.size()==0) { + //该任务不存在, 看看 库表里 该任务是否已执行成功了 + String overTask = (String) redisUtil.get("over_task"); + if (org.apache.commons.lang.StringUtils.isNotBlank(overTask)&&Arrays.asList(overTask.split(",")).contains(taskId)) { + //库表里已执行过 + return Result.OK("该任务已执行结束"); + } else { + //库表中未执行过,追加任务 + taskList.add(new TaskModel(taskId, taskLevel, taskType, "0", parameter)); + task_ = JSONObject.toJSONString(taskList); + } + } else if ("0".equals(staskList.get(0).getTaskStatus())) { + //该任务 待运行 + return Result.OK("该任务还处于排队中"); + } else if ("1".equals(staskList.get(0).getTaskStatus())) { + //该任务 运行中 + return Result.OK("该任务还处于运行中"); + } + } + } + //存入redis + redisUtil.set("task_"+taskLevel, task_); + //执行任务 + executeTask(); + return Result.OK("已追加到任务"); + } + + @Transactional(rollbackFor = Exception.class) + @Async + public void executeTask() { + //获取任务 + List taskList = getTaskList(); + //查看是否有执行中的任务 + long executingCount = taskList.stream().filter(t -> t.getTaskStatus().equals("1")).count(); + if (executingCount > 0) { + //该方法正在执行中 + log.error("该方法正在执行中"); + } + List waitingTaskList = taskList.stream().filter(t -> t.getTaskStatus().equals("0")).collect(Collectors.toList()); + if (waitingTaskList != null) { + while (waitingTaskList.size() > 0) { + //取第一个任务 + TaskModel taskModel = waitingTaskList.get(0); + waitingTaskList.get(0).setTaskStatus("1"); + //刷新redis,执行中 + flushTask(taskModel.getTaskId(), 1); + //执行 + executeTaskp(taskModel); + //刷新已知任务 + taskList = getTaskList(); + //刷新待运行任务 + waitingTaskList = taskList.stream().filter(t -> t.getTaskStatus().equals("0")).collect(Collectors.toList()); + } + } + log.error("任务已全部执行"); + } + + /** + * 刷新任务状态 + * + * @param taskId + * @param status 状态 1 运行中,2 已结束 + */ + public void flushTask(String taskId, int status) { + List taskList = getTaskList(); + if (taskList != null && taskList.size() > 0) { + TaskModel taskModel = taskList.stream().filter(t -> t.getTaskId().equals(taskId)).findFirst().get(); + if (taskModel != null) { + int taskLevel = taskModel.getTaskLevel(); + String task = (String) redisUtil.get("task_" + taskLevel); + JSONArray taskJsonArray = JSONObject.parseArray(task); + taskList = new ArrayList<>(); + if (task != null) { + taskList.addAll(taskJsonArray.toJavaList(TaskModel.class)); + } + if (status == 1) { + //更新任务状态 + taskList.forEach(t -> { + if (t.getTaskId().equals(taskId)) { + t.setTaskStatus("1"); + } + }); + } else if (status == 2) { + //删除任务 + taskList = taskList.stream().filter(t -> !t.getTaskId().equals(taskId)).collect(Collectors.toList()); + } + String s = JSONObject.toJSONString(taskList); + //存入redis + redisUtil.set("task_" + taskLevel, s); + } } + } + //执行任务 + public void executeTaskp(TaskModel taskModel) { + //睡眠 + try { + String parameter = taskModel.getParameter(); + // 任务类型 + if ("identify".equals(taskModel.getTaskType())) { + String[] parameters = parameter.split(","); + //通用识别 + String masterTaskId = parameters[0];//主任务redis + String task_id = parameters[1]; + String image = parameters[2]; + JSONObject requestBody = new JSONObject(); + requestBody.put("task_id", task_id); + requestBody.put("img_path", image); + JSONObject semanticResponseJson = RestUtil.post(OcrConstant.api_test_identify_url, requestBody); + this.getSemanticInfo(semanticResponseJson); + //该子任务已执行,判断主任务是否残留 + String masterTask = (String) redisUtil.get(masterTaskId); + if (StringUtils.isNotBlank(masterTask)) { + //主任务中排除当前任务 + String collect = Arrays.asList(masterTask.split(",")).stream().filter(t -> t.equals(task_id)).collect(Collectors.joining(",")); + if (StringUtils.isBlank(collect)) { + //如果主任务下的子任务已清空,删除key + redisUtil.removeAll(masterTaskId); + //刷新Ocr识别任务状态 + updateOcrIdentifyStatus(masterTaskId,"1"); + }else{ + //主任务还存在,刷新主任务明细 + redisUtil.set(masterTaskId,collect); + } + } + } else { + Thread.sleep(20000l); + } - String ss="[{\"tag\":\"hospitalName\",\"inputText\":\"仁和医院\"},{\"tag\":\"departmentName\",\"inputText\":\"耳鼻喉科\"},{\"tag\":\"doctorName\",\"inputText\":\"张三\"}]"; - JSONArray jsonArray = JSONObject.parseArray(ss); - //System.out.println(jsonArray); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + //模拟执行成功 + String overTaskIds = (String) redisUtil.get("over_task"); + if (org.apache.commons.lang.StringUtils.isBlank(overTaskIds)) { + overTaskIds = taskModel.getTaskId(); + } else { + if (!Arrays.asList(overTaskIds.split(",")).contains(taskModel.getTaskId())) { + //该任务未执行过 + overTaskIds += "," + taskModel.getTaskId(); + } else { + //该任务已结束过 + } + } + //存入已执行 redis里 + redisUtil.set("over_task", overTaskIds); + log.error(taskModel.getTaskLevel() + "-级别," + taskModel.getTaskId() + "-已执行"); + //从3中任务集中,删除该任务 + flushTask(taskModel.getTaskId(), 2); + } + + //获取全部任务 + public List getTaskList() { + String task_0 = (String) redisUtil.get("task_0"); + String task_1 = (String) redisUtil.get("task_1"); + /*String task_2 = (String) redisUtil.get("task_2"); + String task_3 = (String) redisUtil.get("task_3");*/ + JSONArray task0JsonArray = JSONObject.parseArray(task_0); + JSONArray task1JsonArray = JSONObject.parseArray(task_1); + /*JSONArray task2JsonArray = JSONObject.parseArray(task_2); + JSONArray task3JsonArray = JSONObject.parseArray(task_3);*/ + List taskList = new ArrayList<>(); + if (task0JsonArray != null) { + taskList.addAll(task0JsonArray.toJavaList(TaskModel.class)); + } + if (task1JsonArray != null) { + taskList.addAll(task1JsonArray.toJavaList(TaskModel.class)); + } + /*if (task2JsonArray != null) { + taskList.addAll(task2JsonArray.toJavaList(TaskModel.class)); + } + if (task3JsonArray != null) { + taskList.addAll(task3JsonArray.toJavaList(TaskModel.class)); + }*/ + return taskList; } }