temp: 暂存

feature/task-zhanglin
Vincent 1 week ago
parent c3bc2e094d
commit 2eb2149471

@ -59,9 +59,6 @@ public class TaskCompletionRequest {
@JSONField(name = "pictureRepeatList")
private List<PictureRepeat> pictureRepeatList;
@JSONField(name = "hisPictureRepeatList")
private List<HisPictureRepeat> hisPictureRepeatList;
@JSONField(name = "falseImgList")
private List<Long> falseImgList;
@ -82,6 +79,9 @@ public class TaskCompletionRequest {
@JSONField(name = "dynamicFields")
private Map<String, String> dynamicFields;
@JSONField(name = "hisPictureRepeatList")
private List<HisPictureRepeat> hisPictureRepeatList;
}
@Data

@ -4,16 +4,18 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.module.custom.ocr.api.entity.TaskCompletionRequest;
import org.jeecg.module.custom.ocr.common.entity.RequestData;
import org.jeecg.module.custom.ocr.common.entity.ResultData;
import org.jeecg.module.custom.ocr.config.ApiConfig;
import org.jeecg.module.custom.ocr.dataDao.DuplicateTaskMapper;
import org.jeecg.module.custom.ocr.dataDao.OcrPictureInfoMapper;
import org.jeecg.module.custom.ocr.dataDao.PictureCompareMapper;
import org.jeecg.module.custom.ocr.dataobject.DuplicateTask;
import org.jeecg.module.custom.ocr.dataobject.OcrPicture;
import org.jeecg.module.custom.ocr.dataobject.PictureCompare;
import org.jeecg.module.custom.ocr.dataDao.TaskMapper;
import org.jeecg.module.custom.ocr.dataobject.*;
import org.jeecg.module.custom.ocr.service.OcrPictureInfoService;
import org.jeecg.module.custom.ocr.service.OcrPictureService;
import org.jeecg.module.custom.ocr.utils.ApiHelper;
import org.jeecg.module.custom.ocr.utils.ImageClassUtil;
@ -23,6 +25,7 @@ import org.jeecg.module.custom.ocr.utils.httputil.HttpParamers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@ -46,9 +49,15 @@ public class DuplicateTaskRunner {
@Resource
private DuplicateTaskMapper duplicateTaskMapper;
@Resource
private TaskMapper taskMapper;
@Resource
private OcrPictureService ocrPictureService;
@Resource
private OcrPictureInfoMapper ocrPictureInfoMapper;
@Resource
private PictureCompareMapper pictureCompareMapper;
@ -62,6 +71,8 @@ public class DuplicateTaskRunner {
private String classifyBaseUrl;
private ScheduledExecutorService executor;
@Autowired
private OcrPictureInfoService ocrPictureInfoService;
@PostConstruct
public void init() {
@ -76,52 +87,65 @@ public class DuplicateTaskRunner {
private void processDuplicateTasks() {
try {
// 查询所有未完成的 DuplicateTask
List<DuplicateTask> tasks = duplicateTaskMapper.getAllUnCompletedTask();
if (tasks != null && !tasks.isEmpty()) {
for (DuplicateTask task : tasks) {
List<DuplicateTask> duplicateTasks = duplicateTaskMapper.getAllUnCompletedTask();
if (duplicateTasks != null && !duplicateTasks.isEmpty()) {
for (DuplicateTask duplicateTask : duplicateTasks) {
// 解析 queryConfig 为 QueryWrapper
QueryWrapper<OcrPicture> queryWrapper = toQueryWrapper(task);
// 调用 OcrPictureService.listPage 查询图片
List<OcrPicture> pictures = ocrPictureService.listPage(queryWrapper);
// 如果图片数量大于 1进行两两对比
double maxSimilarity = 0.0;
if (pictures != null && pictures.size() > 1) {
for (int i = 0; i < pictures.size(); i++) {
for (int j = i + 1; j < pictures.size(); j++) {
OcrPicture first = pictures.get(i);
OcrPicture second = pictures.get(j);
// 计算相似度
String similarityScore = ImageClassUtil.getSimilarity(first.getImageUrl(), second.getImageUrl(), classifyBaseUrl);
double similarityValue = Double.parseDouble(similarityScore);
maxSimilarity = Math.max(maxSimilarity, similarityValue);
// 保存对比结果到 PictureCompare
PictureCompare compare = new PictureCompare();
compare.setFirstImgNo(first.getId());
compare.setFirstImgUrl(first.getImageUrl());
compare.setFirstLocalImgUrl(first.getLocalImageUrl());
compare.setFirstImgHash(first.getImgHash());
compare.setSecondImgNo(second.getId());
compare.setSecondImgUrl(second.getImageUrl());
compare.setSecondLocalImgUrl(second.getLocalImageUrl());
compare.setSecondImgHash(second.getImgHash());
compare.setSimilarityScore(similarityScore);
pictureCompareMapper.save(compare);
// QueryWrapper<OcrPicture> queryWrapper = toQueryWrapper(duplicateTask);
// // 调用 OcrPictureService.listPage 查询图片
// List<OcrPicture> pictures = ocrPictureService.listPage(queryWrapper);
List<Task> tasks = taskMapper.selectByAccountNoAndQueryConfig(duplicateTask.getAccountNo(), duplicateTask.getQueryConfig());
boolean result = true;
if (!CollectionUtils.isEmpty(tasks)) {
List<Long> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
List<OcrPictureInfo> pictures = ocrPictureInfoMapper.selectByTaskIds(taskIds);
// 如果图片数量大于 1进行两两对比
double maxSimilarity = 0.0;
if (pictures != null && pictures.size() > 1) {
for (int i = 0; i < pictures.size(); i++) {
for (int j = i + 1; j < pictures.size(); j++) {
OcrPictureInfo first = pictures.get(i);
OcrPictureInfo second = pictures.get(j);
// 计算相似度
String similarityScore = ImageClassUtil.getSimilarity(first.getImageUrl(), second.getImageUrl(), classifyBaseUrl);
double similarityValue = Double.parseDouble(similarityScore);
maxSimilarity = Math.max(maxSimilarity, similarityValue);
// 保存对比结果到 PictureCompare
PictureCompare compare = new PictureCompare();
compare.setFirstImgNo(first.getId());
compare.setFirstImgUrl(first.getImageUrl());
compare.setFirstLocalImgUrl(first.getLocalImageUrl());
compare.setFirstImgHash(first.getImgHash());
compare.setSecondImgNo(second.getId());
compare.setSecondImgUrl(second.getImageUrl());
compare.setSecondLocalImgUrl(second.getLocalImageUrl());
compare.setSecondImgHash(second.getImgHash());
compare.setSimilarityScore(similarityScore);
pictureCompareMapper.save(compare);
}
}
// 更新 DuplicateTask 状态和最大相似度
duplicateTaskMapper.updateCompletedAndMaxSimilarity(duplicateTask.getId(), 1, String.valueOf(maxSimilarity));
} else {
// 更新 DuplicateTask 状态和最大相似度
duplicateTaskMapper.updateCompletedAndMaxSimilarity(duplicateTask.getId(), 1, "0");
}
// 更新 DuplicateTask 状态和最大相似度
duplicateTaskMapper.updateCompletedAndMaxSimilarity(task.getId(), true, String.valueOf(maxSimilarity));
String[] taskNos = duplicateTask.getTaskNos().split(",");
for (String taskNo : taskNos) {
notifyTaskCompletion(taskNo, duplicateTask.getTenantNo(), duplicateTask.getAccountNo(), maxSimilarity, pictures);
}
} else {
// 更新 DuplicateTask 状态和最大相似度
duplicateTaskMapper.updateCompletedAndMaxSimilarity(task.getId(), true, "0");
}
String[] taskNos = task.getTaskNos().split(",");
for (String taskNo : taskNos) {
notifyTaskCompletion(taskNo, task.getTenantNo(), task.getAccountNo(), maxSimilarity, pictures);
String[] taskNos = duplicateTask.getTaskNos().split(",");
for (String taskNo : taskNos) {
notifyTaskCompletion(taskNo, duplicateTask.getTenantNo(), duplicateTask.getAccountNo(), 0, Lists.newArrayList());
}
duplicateTaskMapper.updateCompletedAndMaxSimilarity(duplicateTask.getId(), 1, "0");
}
}
}
@ -259,7 +283,7 @@ public class DuplicateTaskRunner {
return queryWrapper;
}
private void notifyTaskCompletion(String taskNo, Long tenantNo, Long accountNo, double maxSimilarity, List<OcrPicture> pictures) {
private boolean notifyTaskCompletion(String taskNo, Long tenantNo, Long accountNo, double maxSimilarity, List<OcrPictureInfo> pictures) {
try {
// 构造任务完成数据
TaskCompletionRequest.TaskCompletionData data = new TaskCompletionRequest.TaskCompletionData();
@ -281,13 +305,13 @@ public class DuplicateTaskRunner {
repeat.setImgNo(p.getId());
repeat.setImgUrl(p.getImageUrl());
repeat.setDynamicFields(new HashMap<>()); // 动态字段待补充
repeat.setHisPictureRepeatList(Arrays.asList());
return repeat;
})
.collect(Collectors.toList());
data.setPictureRepeatList(pictureRepeatList);
// 其他列表暂设为空(需补充逻辑)
data.setHisPictureRepeatList(Arrays.asList());
data.setFalseImgList(Arrays.asList());
data.setBriefRepeatTaskList(Arrays.asList());
data.setApproveDetailList(Arrays.asList());
@ -302,10 +326,14 @@ public class DuplicateTaskRunner {
apiConfig.getAccessCode(),
jsonData
);
// RequestData requestData = ApiHelper.buildResponse(
// apiConfig.getAccessCode(),
// jsonData
// );
// 组装请求
// TODO: 需提供实际路径
String url = apiConfig.getInterfaceDomain() + "/api/task/complete";
String url = apiConfig.getInterfaceDomain();
String requestBodyJson = JSONObject.toJSONString(requestData);
HttpParamers httpParamers = new HttpParamers(HttpMethod.POST);
httpParamers.setJsonParamer(requestBodyJson);
@ -326,11 +354,14 @@ public class DuplicateTaskRunner {
// 处理响应
if (resultData.getStatus() == 100) {
log.info("Task {} completion notified successfully", taskNo);
return true;
} else {
log.error("Failed to notify task completion, taskNo={}, response={}", taskNo, responseJsonStr);
return false;
}
} catch (Exception e) {
log.error("Error notifying task completion, taskNo={}", taskNo, e);
return false;
}
}
}

@ -42,7 +42,7 @@ public class PictureImgToLocalTask implements Runnable {
OcrPictureService ocrPictureService = SpringUtils.getBean("ocrPictureService");
// OcrPicture picture = ocrPictureService.getById(pictureImgToLocal.getId());
TaskService taskService = SpringUtils.getBean("taskServiceImpl");
Task task = taskService.getById(pictureImgToLocal.getId());
Task task = taskService.getById(pictureImgToLocal.getTaskId());
//1.开始转储图片
Boolean result = true;

@ -4,6 +4,7 @@ import lombok.Data;
import org.jeecg.module.custom.ocr.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@ -16,16 +17,19 @@ public class ApiConfig {
/**
*
*/
@Value("${interfaceDomain}")
private String interfaceDomain;
/**
*
*/
@Value("${accessKey}")
private String accessKey;
/**
*
*/
@Value("${accessCode}")
private String accessCode;

@ -12,5 +12,5 @@ public interface DuplicateTaskMapper extends BaseMapper<DuplicateTask> {
void updateCompletedById(Long id);
void updateCompletedAndMaxSimilarity(Long id, boolean completed, String maxSimilarityScore);
void updateCompletedAndMaxSimilarity(Long id, Integer completed, String maxSimilarityScore);
}

@ -1,8 +1,11 @@
package org.jeecg.module.custom.ocr.dataDao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.module.custom.ocr.dataobject.OcrPictureInfo;
import java.util.List;
/**
* ClassName $className$.java
* Description:
@ -10,4 +13,5 @@ import org.jeecg.module.custom.ocr.dataobject.OcrPictureInfo;
* Date 2024/3/22 07:09
*/
public interface OcrPictureInfoMapper extends BaseMapper<OcrPictureInfo> {
List<OcrPictureInfo> selectByTaskIds(@Param("taskIds") List<Long> taskIds);
}

@ -12,4 +12,6 @@ public interface TaskMapper extends BaseMapper<Task> {
void deleteByTaskNo(@Param("taskNo") Long taskNo);
void deleteByTaskNos(@Param("taskNos") List<Long> taskNos);
List<Task> selectByAccountNoAndQueryConfig(@Param("accountNo") Long accountNo, @Param("queryConfig") String queryConfig);
}

@ -88,4 +88,18 @@ public class OcrPictureInfo {
@TableField(value = "`source`")
private String source;
@TableField(value = "image_url")
private String imageUrl;
@TableField(value = "local_image_url")
private String localImageUrl;
@TableField(value = "task_id")
private Long taskId;
@TableField(value = "img_hash")
private String imgHash;
@TableField(value = "history")
private Boolean history;
}

@ -174,6 +174,10 @@ public class OcrPictureServiceImpl extends BaseServiceImpl<OcrPictureMybatisDao,
OcrPictureInfo imageInfo = getImageInfo(url, isConnection);
imageInfo.setPictureId(task.getId());
imageInfo.setImgName(String.valueOf(task.getImageNo()));
imageInfo.setImageUrl(task.getImageUrl());
imageInfo.setLocalImageUrl(task.getLocalImageUrl());
imageInfo.setImgHash(task.getImgHash());
imageInfo.setTaskId(task.getId());
ocrPictureInfoService.save(imageInfo);
}

@ -11,6 +11,7 @@ import org.jeecg.module.custom.ocr.dataobject.Task;
import org.jeecg.module.custom.ocr.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -20,6 +21,7 @@ public class TaskServiceImpl implements TaskService {
@Autowired
private TaskMapper taskMapper;
@Transactional
@Override
public void save(AddTaskRequest request) {
// 处理所有 records 的字段模糊映射
@ -31,6 +33,7 @@ public class TaskServiceImpl implements TaskService {
Task task = toTask(request);
FormRecord formRecord = toFormRecord(request);
// 任务落库
task.setId(null);
taskMapper.save(task);
formRecord.setTaskId(task.getId());
@ -38,6 +41,7 @@ public class TaskServiceImpl implements TaskService {
TaskQueue.pictureImgToLocalPushData(formRecord);
}
@Transactional
@Override
public void deleteTask(Long taskNo) {
taskMapper.deleteByTaskNo(taskNo);
@ -48,6 +52,7 @@ public class TaskServiceImpl implements TaskService {
return this.taskMapper.selectById(id);
}
@Transactional
@Override
public void updateById(Task task) {
this.taskMapper.updateById(task);

@ -70,25 +70,28 @@ public class ImageClassUtil {
JSONObject jsonObjectVi = new JSONObject();
jsonObjectVi.put("taskId", taskId);
JSONArray jsonArrayVi = new JSONArray();
jsonArrayVi.add(imgurl);
// jsonArrayVi.add("/server/ocr/data/images/test01.png");
// jsonArrayVi.add(imgurl);
jsonArrayVi.add("/server/ocr/data/images/test01.png");
jsonObjectVi.put("imgUrls", jsonArrayVi);
HttpParamers paramersVi = HttpParamers.httpPostParamers();
paramersVi.setJsonParamer(jsonObjectVi.toJSONString());
HttpHeader headerVi = null;
String responseDataVi = "";
JSONObject jsonObject = null;
try {
responseDataVi = HttpClient.doService(serverurl, paramersVi, headerVi, 15000, 30000);
JSONObject jsonObjectSimi = JSON.parseObject(responseDataVi);
if (null != jsonObjectSimi && jsonObjectSimi.getString("code").equals("0") && jsonObjectSimi.get("data") != null && jsonObjectSimi.getJSONArray("data").size() > 0) {
} else {
}
jsonObject = JSON.parseObject(responseDataVi);
} catch (Exception e) {
logger.error("classify={}", e);
}
JSONObject jsonObject = JSON.parseObject(responseDataVi);
return jsonObject;
}

@ -269,3 +269,5 @@ image:
serverUrl: http://81.70.154.131/api/image/
classifyBaseUrl: http://47.93.59.251/ai/api/classify/
accessCode: ED6F7B39768AF95E87AEA8ACCCC71A6F
accessKey: 7390F0221A1A73D8E13F8C8BB96F33B0
interfaceDomain: https://saas-dev.rongyucloud.com/api/admin/pangu/jingwei/thirdclient/command/pb/approval/result

@ -14,10 +14,18 @@
<result column="img_space" jdbcType="VARCHAR" property="imgSpace" />
<result column="tag_time" jdbcType="BIGINT" property="tagTime" />
<result column="source" jdbcType="VARCHAR" property="source" />
<result column="task_id" jdbcType="VARCHAR" property="taskId" />
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, picture_id, img_size, img_format, img_measure, upload_time, create_time, img_space,
tag_time, `source`
</sql>
<select id="selectByTaskIds">
SELECT * FROM ocr_picture_info WHERE history = 0 AND task_id IN
<foreach collection="taskIds" item="taskId" open="(" separator="," close=")">
#{taskId}
</foreach>
</select>
</mapper>

@ -74,4 +74,51 @@
#{taskNo}
</foreach>
</delete>
<select id="selectByAccountNoAndQueryConfig" resultType="org.jeecg.module.custom.ocr.dataobject.Task">
SELECT *
FROM task t
WHERE t.account_no = #{accountNo}
<if test="queryConfig != null and queryConfig != ''">
AND (
<choose>
<!-- Parse JSON confidenceLevel and compare with dynamic_fields -->
<when test="queryConfig.contains('confidenceLevel')">
<![CDATA[
JSON_EXTRACT(t.dynamic_fields, '$.confidenceLevel') >= CAST(JSON_EXTRACT(#{queryConfig}, '$.confidenceLevel') AS DECIMAL)
]]>
</when>
<otherwise>
1=1
</otherwise>
</choose>
<!-- Handle startTime and endTime for submit_time range -->
<if test="queryConfig.contains('startTime')">
<![CDATA[
AND t.submit_time >= UNIX_TIMESTAMP(STR_TO_DATE(
JSON_UNQUOTE(JSON_EXTRACT(#{queryConfig}, '$.startTime')),
'%Y-%m-%d %H:%i:%s.%f'
)) * 1000
]]>
</if>
<if test="queryConfig.contains('endTime')">
<![CDATA[
AND t.submit_time <= UNIX_TIMESTAMP(STR_TO_DATE(
JSON_UNQUOTE(JSON_EXTRACT(#{queryConfig}, '$.endTime')),
'%Y-%m-%d %H:%i:%s.%f'
)) * 1000
]]>
</if>
<!-- Handle exCondition boolean -->
<if test="queryConfig.contains('exCondition')">
<![CDATA[
AND JSON_EXTRACT(t.dynamic_fields, '$.exCondition') = JSON_EXTRACT(#{queryConfig}, '$.exCondition')
]]>
</if>
)
</if>
</select>
</mapper>

Loading…
Cancel
Save