add:AI一键查重功能改造方法实现

pull/1/head
707464720@qq.com 1 year ago
parent 1afb543613
commit 7f10dfc1ea

@ -6,18 +6,41 @@ import cn.jyjz.xiaoyao.admin.service.UserService;
import cn.jyjz.xiaoyao.common.base.config.XiaoyaoConfig;
import cn.jyjz.xiaoyao.common.base.controller.BaseController;
import cn.jyjz.xiaoyao.common.base.service.UserTokenService;
import cn.jyjz.xiaoyao.common.base.util.RequestBaseUtil;
import cn.jyjz.xiaoyao.common.base.vo.ResultVo;
import cn.jyjz.xiaoyao.common.base.vo.ResultVoUtil;
import cn.jyjz.xiaoyao.common.base.vo.UserToken;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrCheckDuplicate;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrPicture;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrPlan;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrTaskPackage;
import cn.jyjz.xiaoyao.ocr.service.IOcrCheckDuplicateResultService;
import cn.jyjz.xiaoyao.ocr.service.IOcrCheckDuplicateService;
import cn.jyjz.xiaoyao.ocr.service.IOcrTaskPackageService;
import cn.jyjz.xiaoyao.ocr.service.OcrPictureService;
import cn.jyjz.xiaoyao.ocr.util.DataUtil;
import cn.jyjz.xiaoyao.ocr.util.SearchConfigEnum;
import cn.jyjz.xiaoyao.ocr.util.SearchParaFormatting;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* (20240323)
*
* </p>
*
* @author author
@ -38,7 +61,149 @@ public class OcrTaskPackageController extends BaseController {
private XiaoyaoConfig xiaoyaoConfig;
@Resource
private FtperrorService ftperrorService;
@Resource
private IOcrCheckDuplicateResultService ocrCheckDuplicateResultService;
@Resource
private IOcrCheckDuplicateService ocrCheckDuplicateService;
@Resource
private OcrPictureService ocrPictureService;
@ApiOperation(value = "一键查重", notes = "一键查重")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "header", name = "X-Tenant-Id", value = "租户主键,用户登录时的信息“tenantList”中获得。", dataType = "String", required = true)
})
@GetMapping(value = "/checkDuplicate")
public ResultVo checkDuplicate(OcrPicture ocrPicture, HttpServletRequest req) {
//获取当前登录人
UserToken userToken = this.userTokenService.getUserToken(RequestBaseUtil.getToken(req));
//租户主键,由前端页面传送
String tenantId = req.getHeader("X-Tenant-Id");
if (StringUtils.isBlank(tenantId)) {
return ResultVoUtil.error("租户主键不能为空");
}
QueryWrapper<OcrPicture> queryWrapper = new QueryWrapper<>();
//根据参数枚举获取检索参数并映射为数据库的字段的key-v map
Map<String, Object> paraMap = new HashMap<>();
for (SearchConfigEnum config : SearchConfigEnum.values()) {
String searchvalue = req.getParameter(config.getId());
if (StringUtils.isNotBlank(searchvalue)) {
paraMap.put(config.getMeaning(), searchvalue);
}
}
//调用查询参数解析方法解析为queryWrapper
queryWrapper = SearchParaFormatting.searchParaParse(queryWrapper, paraMap);
queryWrapper.eq("tenant_id", tenantId);
List<OcrPicture> pageList = ocrPictureService.listPage(queryWrapper);
if (null != pageList && !pageList.isEmpty()) {
if (pageList.size() == 1) {
return ResultVoUtil.error("查重数据至少要有两条。");
} else {
return ocrTaskPackageService.duplicateCheck(pageList, tenantId, userToken, req);
}
} else {
return ResultVoUtil.error("没有查重数据。");
}
}
//取消查重任务接口
@ApiOperation(value = "获取查重任务接口异步状态", notes = "获取查重任务接口异步状态")
@GetMapping("/getCheckDuplicateStatus")
@ResponseBody
public ResultVo getCheckDuplicateStatus(HttpServletResponse response, HttpServletRequest request,
@RequestParam(name="checkDuplicateNo",required = true) String checkDuplicateNo) throws IOException {
String tenantId = request.getHeader("X-Tenant-Id");
if(StringUtils.isBlank(tenantId)){
return ResultVoUtil.error("租户主键不能为空");
}
if(StringUtils.isBlank(checkDuplicateNo)){
return ResultVoUtil.error("查重编号不能为空");
}
OcrCheckDuplicate dto = this.ocrCheckDuplicateService.getCheckDuplicateStatus(checkDuplicateNo);
if(null != dto){
return ResultVoUtil.success(dto);
}else{
return ResultVoUtil.error();
}
}
/**
*
* @param request
* @return
*/
@GetMapping(value = "/getLastCheckNo")
public ResultVo getLastCheckNo(HttpServletRequest request) {
String tenantId = request.getHeader("X-Tenant-Id");
if(StringUtils.isBlank(tenantId)){
return ResultVoUtil.error("租户主键不能为空");
}
String lastCheckNo = this.ocrCheckDuplicateService.getLastCheckNo(tenantId);
if(StringUtils.isBlank(lastCheckNo)){
return ResultVoUtil.success(lastCheckNo);
}else{
return ResultVoUtil.error();
}
}
/**
*
* @param ocrTaskPackage
* @param req
* @return
*/
@GetMapping(value = "/createPackage")
public ResultVo createPackage(OcrTaskPackage ocrTaskPackage, HttpServletRequest req) {
//校验参数包名称
if(ocrTaskPackage == null){
return ResultVoUtil.error("参数对象为空");
}
//校验参数包名称
if(StringUtils.isBlank(ocrTaskPackage.getName())){
return ResultVoUtil.error("任务包名称不能为空");
}
boolean isSuccess = ocrTaskPackageService.save(ocrTaskPackage);
if(isSuccess){
return ResultVoUtil.success(ocrTaskPackage);
}else{
return ResultVoUtil.error();
}
}
/**
*
* @param id
* @param req
* @return
*/
@GetMapping(value = "/deletePackage")
public ResultVo deletePackage(Long id, HttpServletRequest req) {
boolean b = ocrTaskPackageService.removeById(id);
if(b){
return ResultVoUtil.success();
}else{
return ResultVoUtil.error();
}
}
}

@ -13,4 +13,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface IOcrCheckDuplicateService extends IService<OcrCheckDuplicate> {
OcrCheckDuplicate getCheckDuplicateStatus(String checkDuplicateNo);
String getLastCheckNo(String tenantId);
}

@ -1,8 +1,14 @@
package cn.jyjz.xiaoyao.ocr.service;
import cn.jyjz.xiaoyao.common.base.vo.ResultVo;
import cn.jyjz.xiaoyao.common.base.vo.UserToken;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrPicture;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrTaskPackage;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* <p>
* (20240323)
@ -13,4 +19,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface IOcrTaskPackageService extends IService<OcrTaskPackage> {
ResultVo duplicateCheck(List<OcrPicture> pageList, String tenantId, UserToken userToken, HttpServletRequest req);
}

@ -1,11 +1,22 @@
package cn.jyjz.xiaoyao.ocr.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.jyjz.xiaoyao.admin.dataobject.User;
import cn.jyjz.xiaoyao.common.base.exception.CommonExceptionCodeEnum;
import cn.jyjz.xiaoyao.common.base.exception.ServiceException;
import cn.jyjz.xiaoyao.common.base.util.StringUtils;
import cn.jyjz.xiaoyao.ocr.dataDao.OcrCheckDuplicateMapper;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrCheckDuplicate;
import cn.jyjz.xiaoyao.ocr.service.IOcrCheckDuplicateService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.function.Function;
/**
* <p>
*
@ -17,4 +28,35 @@ import org.springframework.stereotype.Service;
@Service
public class OcrCheckDuplicateServiceImpl extends ServiceImpl<OcrCheckDuplicateMapper, OcrCheckDuplicate> implements IOcrCheckDuplicateService {
@Resource
private OcrCheckDuplicateMapper ocrCheckDuplicateMapper;
@Override
public OcrCheckDuplicate getCheckDuplicateStatus(String checkDuplicateNo) {
if(StringUtils.isBlank(checkDuplicateNo)){
throw new ServiceException(CommonExceptionCodeEnum.PARAM_NOTVALID);
}
QueryWrapper<OcrCheckDuplicate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("check_duplicate_no",checkDuplicateNo);
OcrCheckDuplicate ocrCheckDuplicate = ocrCheckDuplicateMapper.selectOne(queryWrapper);
return ocrCheckDuplicate;
}
@Override
public String getLastCheckNo(String tenantId) {
QueryWrapper<OcrCheckDuplicate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("tenant_id",tenantId);
queryWrapper.orderByDesc("create_time");
List<OcrCheckDuplicate> list = ocrCheckDuplicateMapper.selectList(queryWrapper);
if(CollUtil.isNotEmpty(list)){
return list.get(0).getCheckDuplicateNo();
}else{
return null;
}
}
}

@ -1,11 +1,30 @@
package cn.jyjz.xiaoyao.ocr.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.jyjz.xiaoyao.admin.service.LogService;
import cn.jyjz.xiaoyao.common.base.vo.ResultVo;
import cn.jyjz.xiaoyao.common.base.vo.ResultVoUtil;
import cn.jyjz.xiaoyao.common.base.vo.UserToken;
import cn.jyjz.xiaoyao.ocr.dataDao.OcrTaskPackageMapper;
import cn.jyjz.xiaoyao.ocr.dataobject.OcrTaskPackage;
import cn.jyjz.xiaoyao.ocr.service.IOcrTaskPackageService;
import cn.jyjz.xiaoyao.ocr.dataobject.*;
import cn.jyjz.xiaoyao.ocr.service.*;
import cn.jyjz.xiaoyao.ocr.util.HashCompareUtil;
import cn.jyjz.xiaoyao.ocr.util.ImageClassUtil;
import cn.jyjz.xiaoyao.ocr.util.SearchEnum;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* (20240323)
@ -17,4 +36,207 @@ import org.springframework.stereotype.Service;
@Service
public class OcrTaskPackageServiceImpl extends ServiceImpl<OcrTaskPackageMapper, OcrTaskPackage> implements IOcrTaskPackageService {
@Resource
private OcrPictureService ocrPictureService;
@Resource
private IOcrCheckDuplicateResultService checkDuplicateResultService;
@Resource
private IOcrCheckDuplicateService checkDuplicateService;
@Resource
private IOcrPictrueDuplicateHisService pictureDuplicateHisService;
@Resource
private LogService logService;
@Value("${image.classifyPath}")
private String classifyPath;
/**
*
*/
@Override
public ResultVo duplicateCheck(List<OcrPicture> ocrPictureList, String tenantId, UserToken sysUser, HttpServletRequest req) {
if (null != ocrPictureList && !ocrPictureList.isEmpty()) {
//生成查重任务插入表ocr_check_duplicate
OcrCheckDuplicate ocrCheckDuplicate = new OcrCheckDuplicate();
ocrCheckDuplicate.setCheckDuplicateNo("");// 生成查重任务编号,规则
ocrCheckDuplicate.setTenantId(Long.valueOf(tenantId));
ocrCheckDuplicate.setCreateBy(sysUser.getUserid());
ocrCheckDuplicate.setCreateTime(DateUtil.current());
ocrCheckDuplicate.setPictureCount(ocrPictureList.size());
ocrCheckDuplicate.setStatus(1);
ocrCheckDuplicate.setSearchingJson("");//查重时左侧的筛选条件
checkDuplicateService.save(ocrCheckDuplicate);
//异步执行图片比对查重功能 comparePictureResultSave()
//
}
return ResultVoUtil.success();
//生成查重任务插入ocr_check_duplicate
//异步执行查重任务比对查重
//异步查重结果回写 回写orc_check_duplicate_result
//图片比对历史 ocr_pictrue_duplicate_his 这个表的数据 以图片为维度,该图片与其他图片对比结果的保存
//回写 orc_check_duplicate_result表 max_similarity字段字段值是本次查重相似度最高的阈值。
//回写ocr_picture表similarity_score字段字段值是该图片所有历史比对的最高值如果本次比对的最高阈值小于最高值则不进行回写。
}
/**
* ocr_check_duplicate_result
*/
public void comparePictureResultSave(List<OcrPicture> ocrPictureList,UserToken sysUser) {
List<OcrCheckDuplicateResult> list = new ArrayList<>();
//图片错误信息
StringBuffer error = new StringBuffer();
//项目错误信息
StringBuffer errorProject = new StringBuffer();
//流程错误信息
StringBuffer errorFlow = new StringBuffer();
//记录任务相似度为百分百的任务主键
List<Long> pointsList = new ArrayList<>();
//图片信息不能为空
if (null != ocrPictureList && !ocrPictureList.isEmpty()) {
//用于标记相似度是否存在百分百的情况
List<OcrPicture> newList = new ArrayList<>();
Map<String, String> resultMap = new HashMap<>();
for (OcrPicture ocrPicture : ocrPictureList) {
//将比对结果按json格式存储
OcrCheckDuplicateResult ocrCheckDuplicateResult = new OcrCheckDuplicateResult();
//图片比对历史数据增量存储 ocr_pictrue_duplicate_his
OcrPictrueDuplicateHis pictrueDuplicateHis = new OcrPictrueDuplicateHis();
//如果当前图片已经生成任务包,直接跳过
if (ocrPicture.getTaskstatus().equals("1")) {
continue;
}
//图片查重的比对图片集合
List<OcrPicture> compareList = new ArrayList<>();
//非历史图片主键集合
List<String> picturecompareList = new ArrayList<>();
boolean havePoint = false;
logService.addLog(103, "AI获取图片相似度接口", sysUser, "sendParams");
if (StringUtils.isBlank(ocrPicture.getImgHash())) {
Map<String, String> map = this.getOcrPictureClassifyAndHash(ocrPicture.getLocalpictrueurl());
if (map != null) {
ocrPicture.setImgHash(map.get("hash"));
ocrPicture.setClassificationid(map.get("classId"));
}
// this.updateById(ocrPicture);
}
//二次遍历进行比对
for (OcrPicture ocrPictureNext : ocrPictureList) {
//分类不一致的也不需要进行比对
if (ocrPictureNext.getId().longValue() == ocrPicture.getId().longValue()) {
continue;
}
//分类不一致的也不需要进行比对
//TODO 接口请求判断重复情况
if (StringUtils.isBlank(ocrPictureNext.getImgHash())) {
Map<String, String> map = this.getOcrPictureClassifyAndHash(ocrPictureNext.getLocalpictrueurl());
if (map != null) {
ocrPictureNext.setImgHash(map.get("hash"));
ocrPictureNext.setClassificationid(map.get("classId"));
}
// this.updateById(ocrPictureNext);
}
String resultValue = "";
String strId = ocrPicture.getId() + ":" + ocrPictureNext.getId();
String strNextId = ocrPictureNext.getId() + ":" + ocrPicture.getId();
if (resultMap.containsKey(strId) || resultMap.containsKey(strNextId)) {
resultValue = resultMap.get(strId) == null ? resultMap.get(strNextId) : resultMap.get(strId);
} else {
String img = StringUtils.isBlank(ocrPicture.getImgHash()) ? StringUtils.isBlank(ocrPicture.getLocalpictrueurl()) ? ocrPicture.getImgurl() : ocrPicture.getLocalpictrueurl() : ocrPicture.getImgHash();
String imgNext = StringUtils.isBlank(ocrPictureNext.getImgHash()) ? StringUtils.isBlank(ocrPictureNext.getLocalpictrueurl()) ? ocrPictureNext.getImgurl() : ocrPictureNext.getLocalpictrueurl() : ocrPictureNext.getImgHash();
resultValue = HashCompareUtil.cmpHash(img, imgNext);
resultMap.put(strId, resultValue);
}
ocrPictureNext.setResult(resultValue);
BigDecimal b1 = new BigDecimal(resultValue);
BigDecimal b2 = new BigDecimal("100");
int val = b1.compareTo(b2);
if (val == 0) {
havePoint = true;
}
//如果当前图片未生成任务需要临时保存
if (ocrPictureNext.getTaskstatus().equals("0")) {
picturecompareList.add(ocrPictureNext.getId().toString());
}
compareList.add(ocrPictureNext);
}
// this.updateBatchById(ocrPictureList);
bubbleSortOpt(compareList);
//从大到小进行排序
ocrPicture.setListCom(compareList);
//非历史图片主键集合
ocrPicture.setPicturecompareList(picturecompareList);
ocrPicture.setTaskstatus("1");
}
}
boolean b = checkDuplicateResultService.saveOrUpdateBatch(list);
}
/**
* ocr_pictrue_duplicate_his
*/
public void comparePicture(){
}
/**
* ocr_pictrue_duplicate_his
*/
public void newComparePicture(){
}
public Map<String, String> getOcrPictureClassifyAndHash(String img) {
JSONObject jsonObjectSimi = ImageClassUtil.getClassify(img, "1", classifyPath);
//返回内容为零,表示成功,否则表示失败
if (null != jsonObjectSimi && jsonObjectSimi.getString("code").equals("0") && jsonObjectSimi.get("data") != null && jsonObjectSimi.getJSONArray("data").size() > 0) {
JSONObject data = jsonObjectSimi.getJSONArray("data").getJSONObject(0);
Map<String, String> map = new HashMap();
map.put("classId", data.getString("classId"));
map.put("hash", data.getString("hash"));
return map;
} else {
return null;
}
}
public void bubbleSortOpt(List<OcrPicture> compareList) {
if (null == compareList) {
return;
}
OcrPicture temp = null;
for (int i = 0; i < compareList.size() - 1; i++) {
for (int j = 0; j < compareList.size() - i - 1; j++) {
if (Double.parseDouble(compareList.get(j).getResult()) < Double.parseDouble(compareList.get(j + 1).getResult())) {
temp = compareList.get(j);
compareList.set(j, compareList.get(j + 1));
compareList.set((j + 1), temp);
}
}
}
}
}

Loading…
Cancel
Save