master
周文涛 2 years ago
parent 961740757d
commit e90f0ac226

@ -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";
}

@ -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;
}
}

@ -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));

@ -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,9 +35,14 @@ import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api")
@Async
public class ApiController {
@Resource
private IOcrRuleCheckService ocrRuleCheckService;
@Resource
private RedisUtil redisUtil;
////===================================================================伪接口
@ApiOperation(value = "通用识别", notes = "通用识别")
@PostMapping(value = "/identify")
@ -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<TaskModel> jsonObjects = Arrays.asList(task);
task_1 = JSONObject.toJSONString(jsonObjects);
} else {
//有历史任务
JSONArray jsonArray = JSONObject.parseArray(task_1);
if (jsonArray != null) {
List<TaskModel> taskList = jsonArray.toJavaList(TaskModel.class);
List<TaskModel> 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<TaskModel> taskList=getTaskList();
//查看是否有执行中的任务
long executingCount = taskList.stream().filter(t -> t.getTaskStatus().equals("1")).count();
if (executingCount>0) {
//该方法正在执行中
log.error("该方法正在执行中");
}
List<TaskModel> 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<TaskModel> 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<TaskModel> 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<TaskModel> 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;
}
}

@ -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<String> 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<JSONObject> 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<JSONObject> sourceJsonList = sourceJson.toJavaList(JSONObject.class);//校验数据源
String sourceImages = requestBody.getString("sourceImages");//ocr图片集
//获取识别的图片
List<String> 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("请求成功");
}

@ -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<OcrIdentify, IOcrIden
public Result<String> 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<OcrIdentify, IOcrIden
// @RequiresPermissions("org.jeecg.modules.ocr:ocr_identify:delete")
@DeleteMapping(value = "/delete")
public Result<String> 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<OcrIdentify, IOcrIden
// @RequiresPermissions("org.jeecg.modules.ocr:ocr_identify:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
List<OcrIdentify> 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
*/

@ -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;
}
}

@ -14,4 +14,6 @@ import org.jeecg.modules.ocr.entity.OcrApiCallStatistics;
public interface IOcrApiCallStatisticsService extends IService<OcrApiCallStatistics> {
IPage<OcrApiCallStatistics> pageList(Page<OcrApiCallStatistics> page, OcrApiCallStatistics ocrApiCallStatistics);
void saveLogs(String apiName, String apiUrl, int count);
}

@ -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<OcrIdentify> {
public void getSemanticInfo(JSONObject responseBody);
@Async
void postSemantic(String id, String identifyUrl);
void postSemantic(OcrIdentify ocrIdentify, List<String> identifyUrlList);
void updateOcrIdentifyStatus(String id,String status);
/**
*
* @param jsonObject
* @return
*/
Result pushTask(JSONObject jsonObject);
}

@ -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<OcrApiCallStati
IPage<OcrApiCallStatistics> 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);
}
}

@ -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.*;
@ -46,6 +50,10 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
IOcrIdentifyDetailService ocrIdentifyDetailService;
@Resource
IOcrRuleCheckDetailService ocrRuleCheckDetailService;
@Resource
IOcrApiCallStatisticsService ocrApiCallStatisticsService;
@Resource
RedisUtil redisUtil;
@Override
public OcrIdentifyVo findById(String id) {
@ -68,6 +76,7 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
@Override
public void getSemanticInfo(JSONObject responseBody) {
try {
ocrApiCallStatisticsService.saveLogs("通用识别", "/ocr/ocrApi/identify", 1);
Thread.sleep(10000l);
} catch (InterruptedException e) {
e.printStackTrace();
@ -112,7 +121,8 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
StringBuffer rMessage = new StringBuffer();
Map<String, Boolean> 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-不绝对判断
@ -132,7 +142,8 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
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");//置信度
@ -175,23 +186,49 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
}
public static String semanticResponse = "{\"execution_time\":69.1751720905304,\"img_path\":\"./static/ocrData/custom_2_44.jpg\",\"message\":\"成功\",\"semantic_result\":{\"医院名称\":[{\"area\":[[227,382],[441,388],[440,422],[226,416]],\"end\":7,\"ocrText\":\"开封市眼病医院\",\"probability\":0.9677108957485778,\"start\":0,\"text\":\"开封市眼病医院\"}],\"姓名\":[{\"area\":[[566,668],[691,668],[691,712],[566,712]],\"end\":3,\"ocrText\":\"闫利霞\",\"probability\":0.884488371938783,\"start\":0,\"text\":\"闫利霞\"}],\"时间\":[{\"area\":[[701,400],[874,400],[874,456],[701,456]],\"end\":5,\"ocrText\":\"10:40\",\"probability\":0.9626484940814066,\"start\":0,\"text\":\"10:40\"},{\"area\":[[502,422],[667,424],[667,452],[502,450]],\"end\":11,\"ocrText\":\"2023年05月17日\",\"probability\":0.815085233546764,\"start\":0,\"text\":\"2023年05月17日\"}],\"科室\":[]},\"task_id\":1}";
public static String semanticUrl = "http://111.202.228.113:7003/semantic";
@Override
@Async
public void postSemantic(String id, String identifyUrl) {
public void postSemantic(OcrIdentify ocrIdentify, List<String> identifyUrlList) {
//3.请求python ocr识别
JSONObject semanticResponseJson = JSONObject.parseObject(semanticResponse);
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);
this.getSemanticInfo(semanticResponseJson);*/
}
}
@Override
public void updateOcrIdentifyStatus(String id,String status) {
//4.更新主任务状态
OcrIdentify ocrIdentify=new OcrIdentify();
LambdaUpdateWrapper<OcrIdentify> updateWrapper = new LambdaUpdateWrapper<OcrIdentify>();
updateWrapper.eq(OcrIdentify::getId, id);
updateWrapper.set(OcrIdentify::getEndTime, new Date());
updateWrapper.set(OcrIdentify::getStatus, "1");
this.update(updateWrapper);
}
public static void mapPutIfTrue(Map map, String key, Boolean flag) {
@ -203,6 +240,7 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
/**
* OcrResult, ocrResultList
*
* @param ocrResultList
* @param field
* @param inputText
@ -235,6 +273,7 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
/**
* checkSemanticModelMap
*
* @param configRuleMap 1/0 map
* @param fieldMap map
* @return
@ -284,21 +323,206 @@ public class OcrIdentifyServiceImpl extends ServiceImpl<OcrIdentifyMapper, OcrId
return checkSemanticModelMap;
}
public static void main(String[] args) {
Map<String,Boolean> 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<TaskModel> jsonObjects = Arrays.asList(task);
task_ = JSONObject.toJSONString(jsonObjects);
} else {
//有历史任务
JSONArray jsonArray = JSONObject.parseArray(task_);
if (jsonArray != null) {
List<TaskModel> taskList = jsonArray.toJavaList(TaskModel.class);
List<TaskModel> 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<TaskModel> taskList = getTaskList();
//查看是否有执行中的任务
long executingCount = taskList.stream().filter(t -> t.getTaskStatus().equals("1")).count();
if (executingCount > 0) {
//该方法正在执行中
log.error("该方法正在执行中");
}
List<TaskModel> 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<TaskModel> 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);
}
} 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);
}
String ss="[{\"tag\":\"hospitalName\",\"inputText\":\"仁和医院\"},{\"tag\":\"departmentName\",\"inputText\":\"耳鼻喉科\"},{\"tag\":\"doctorName\",\"inputText\":\"张三\"}]";
JSONArray jsonArray = JSONObject.parseArray(ss);
//System.out.println(jsonArray);
//获取全部任务
public List<TaskModel> 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<TaskModel> 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;
}
}

Loading…
Cancel
Save