ai功能开发
This commit is contained in:
parent
2018c54dbb
commit
995476dc34
|
|
@ -90,6 +90,10 @@
|
|||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
package com.bonus.ai.controller;
|
||||
|
||||
//import com.bonus.ai.domain.IDCardInfo;
|
||||
import com.bonus.ai.domain.dto.ImageUpload;
|
||||
import com.bonus.ai.domain.po.AiIdcardrecognizeResult;
|
||||
import com.bonus.ai.domain.vo.IdCardVo;
|
||||
import com.bonus.ai.service.IOcrRecogService;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.ai.utils.FileTypeUtils;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import static com.bonus.common.core.web.domain.AjaxResult.error;
|
||||
import static com.bonus.common.core.web.domain.AjaxResult.success;
|
||||
|
||||
/**
|
||||
* 文件请求处理
|
||||
|
|
@ -25,12 +23,24 @@ public class OcrRecogController
|
|||
private IOcrRecogService ocrRecogService;
|
||||
|
||||
|
||||
@PostMapping("/recognition")
|
||||
public R<IdCardVo> idCardRecognize(
|
||||
@RequestBody ImageUpload imageUpload) {
|
||||
return R.ok(ocrRecogService.detectIdCard(imageUpload));
|
||||
@PostMapping("/recognition")
|
||||
public AjaxResult recognition(MultipartFile[] files, String type) {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
try {
|
||||
for (MultipartFile file : files) {
|
||||
String contentType = file.getContentType();
|
||||
if (!FileTypeUtils.FILE_TYPE_PNG.equals(contentType) && !FileTypeUtils.FILE_TYPE_JPEG.equals(contentType) && !FileTypeUtils.FILE_TYPE_PDF.equals(contentType)) {
|
||||
return error("仅允许导入doc、jpg、png格式文件");
|
||||
}
|
||||
}
|
||||
ajax = ocrRecogService.recognitionCheck(files,type);
|
||||
return success("数据上传成功!!!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return error("数据上传失败!!!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.bonus.ai.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Data
|
||||
public class IdCardVo {
|
||||
|
|
@ -18,5 +17,6 @@ public class IdCardVo {
|
|||
private String dateOfBirth;
|
||||
private String address;
|
||||
private String idNumber;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package com.bonus.ai.service;
|
||||
import com.bonus.ai.domain.dto.ImageUpload;
|
||||
import com.bonus.ai.domain.vo.IdCardVo;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface IOcrRecogService {
|
||||
IdCardVo detectIdCard(ImageUpload imageUpload);
|
||||
|
||||
AjaxResult recognitionCheck(MultipartFile[] files, String type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,73 +5,136 @@ import com.bonus.ai.domain.po.AiIdcardrecognizeResult;
|
|||
import com.bonus.ai.domain.vo.IdCardVo;
|
||||
import com.bonus.ai.mapper.AiIdcardrecognizeMapper;
|
||||
import com.bonus.ai.service.IOcrRecogService;
|
||||
import com.bonus.common.core.utils.ServletUtils;
|
||||
import com.bonus.common.core.utils.global.SystemGlobal;
|
||||
import com.bonus.common.core.utils.ip.IpUtils;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
import com.bonus.system.api.model.LoginUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class OcrRecogServiceImpl implements IOcrRecogService {
|
||||
// @Autowired
|
||||
// private RestTemplate restTemplate;
|
||||
|
||||
// private final AiIdcardrecognizeResult aiIdcardrecognizeResult;
|
||||
|
||||
private static final String FRONT_FILE_NAME_TEMPLATE = "%s_%s_front.jpg";
|
||||
private static final String BACK_FILE_NAME_TEMPLATE = "%s_%s_back.jpg";
|
||||
|
||||
|
||||
@Value("${idcard.record}")
|
||||
private String recogurl;
|
||||
|
||||
@Value("${idcard.directoryPath}")
|
||||
private String directoryPath;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private AiIdcardrecognizeMapper aiIdcardrecognizeMapper;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public IdCardVo detectIdCard(ImageUpload imageUpload) {
|
||||
// String recogUrl = "http://192.168.0.188:8080/recognition";
|
||||
//
|
||||
// ResponseEntity<String> response = restTemplate.postForEntity(
|
||||
// recogUrl,imageUpload,String.class);
|
||||
// String json = String.valueOf(response.getBody());
|
||||
// String json_deal= json.substring(1, json.length() - 1);
|
||||
String response = "{\"code\": 20000, \"msg\": \"身份证信息完整\", \"data\": {\"issuingAuthority\": \"湘乡市公安局\", \"dateOfBirth\":\"2020.09.02\",\"validTime\": \"2020.09.02-2040.09.02\", \"name\": \"性#\", \"gender\": \"男\", \"ethnicity\": \"出生1964年11月30日\", \"dateOfBirth\": \"1964年11月30日\", \"address\": \"住地湖南省会同县广评镇西楼村三组6号\", \"idNumber\": \"43302919641130423X\"}}";
|
||||
|
||||
// 创建Gson实例,将python模型返回值赋值给前端对象
|
||||
Gson gson = new Gson();
|
||||
IdCardVo idCardVo = gson.fromJson(response, IdCardVo.class);
|
||||
System.out.println(idCardVo);
|
||||
|
||||
|
||||
// 保存数据
|
||||
char ifComplete = '否';
|
||||
if ("身份证信息完整".equals(idCardVo.getMsg())) {
|
||||
ifComplete = '是';
|
||||
}
|
||||
|
||||
String directoryPath = "C:\\images"; // 指定保存图片的目录
|
||||
String idNumber = idCardVo.getData().getIdNumber();
|
||||
String currentDate = LocalDate.now().toString();
|
||||
String frontFileName = idNumber + "_" + currentDate + "_front.jpg";
|
||||
String backFileName = idNumber + "_" + currentDate + "_back.jpg";
|
||||
byte[] frontImageBytes = Base64.getDecoder().decode(imageUpload.getRecognitionFrontData());
|
||||
byte[] backImageBytes = Base64.getDecoder().decode(imageUpload.getRecognitionBackData());
|
||||
public AjaxResult recognitionCheck(MultipartFile[] files, String type) {
|
||||
AjaxResult ajax=null;
|
||||
// 记录开始时间
|
||||
long startTime = System.currentTimeMillis();
|
||||
IdCardVo idCardVo = null;
|
||||
String[] getfilePath = null;
|
||||
//针对获取到的file转化base64 进行python调用
|
||||
try {
|
||||
Path frontFilePath = Paths.get(directoryPath, frontFileName);
|
||||
Path backFilePath = Paths.get(directoryPath, backFileName);
|
||||
Files.write(frontFilePath, frontImageBytes); // 将解码后的字节数组写入到文件中
|
||||
Files.write(backFilePath, backImageBytes);
|
||||
System.out.println("图片保存成功:" + frontFilePath + backFilePath);
|
||||
} catch (IOException e) {
|
||||
getfilePath = convertFilesToBase64(files);
|
||||
idCardVo = processPythonResponse(getfilePath, recogurl);
|
||||
} catch (Exception e) {
|
||||
ajax.put("601", "调用大模型服务出错");
|
||||
e.printStackTrace();
|
||||
System.out.println("保存图片时出错:" + e.getMessage());
|
||||
}
|
||||
if (idCardVo != null) {
|
||||
char ifComplete = '否';
|
||||
if (SystemGlobal.IDCARD_RECORD_SUCCESS.equals(idCardVo.getCode())) {
|
||||
ifComplete = '是';
|
||||
}
|
||||
String idNumber = idCardVo.getData().getIdNumber();
|
||||
String currentDate = System.currentTimeMillis()+"";
|
||||
String frontFileName = String.format(FRONT_FILE_NAME_TEMPLATE, idNumber, currentDate);
|
||||
String backFileName = String.format(BACK_FILE_NAME_TEMPLATE, idNumber, currentDate);
|
||||
|
||||
try {
|
||||
byte[] frontImageBytes = Base64.getDecoder().decode(getfilePath[0]);
|
||||
byte[] backImageBytes = Base64.getDecoder().decode(getfilePath[1]);
|
||||
Path frontFilePath = Paths.get(directoryPath, frontFileName);
|
||||
Path backFilePath = Paths.get(directoryPath, backFileName);
|
||||
Files.write(frontFilePath, frontImageBytes);
|
||||
Files.write(backFilePath, backImageBytes);
|
||||
} catch (IOException e) {
|
||||
ajax.put("602", "获取身份证信息出错");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
saveRecognitionResult(idCardVo, ifComplete, frontFileName, backFileName,startTime);
|
||||
}
|
||||
return ajax;
|
||||
}
|
||||
|
||||
public String[] convertFilesToBase64(MultipartFile[] files) {
|
||||
String[] base64Strings = new String[files.length];
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
MultipartFile file = files[i];
|
||||
try {
|
||||
byte[] bytes = file.getBytes();
|
||||
String base64String = Base64.getEncoder().encodeToString(bytes);
|
||||
base64Strings[i] = base64String;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return base64Strings;
|
||||
}
|
||||
|
||||
private IdCardVo processPythonResponse(String[] strings, String recogurl) throws Exception {
|
||||
if (strings.length != 2) {
|
||||
throw new IllegalArgumentException("Python响应数据不完整。");
|
||||
}
|
||||
ImageUpload imageUpload = new ImageUpload();
|
||||
imageUpload.setRecognitionBackData(strings[0]);
|
||||
imageUpload.setRecognitionFrontData(strings[1]);
|
||||
imageUpload.setType("1");
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(recogurl, imageUpload, String.class);
|
||||
if (response.getStatusCodeValue() != 200) {
|
||||
throw new RestClientException("调用服务失败,状态码:" + response.getStatusCodeValue());
|
||||
}
|
||||
String json = response.getBody();
|
||||
// 移除首尾字符
|
||||
json = json.substring(1, json.length() - 1);
|
||||
// 解析转义字符
|
||||
json = StringEscapeUtils.unescapeJava(json);
|
||||
Gson gson = new Gson();
|
||||
return gson.fromJson(json, IdCardVo.class);
|
||||
}
|
||||
private void saveRecognitionResult(IdCardVo idCardVo, char ifComplete, String frontFileName, String backFileName,long startTime) {
|
||||
String idNumber = idCardVo.getData().getIdNumber();
|
||||
// 从SecurityUtils.getLoginUser()获取登录用户信息
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
// 记录结束时间
|
||||
long endTime = System.currentTimeMillis();
|
||||
// 计算响应时间
|
||||
long time = endTime - startTime;
|
||||
int responseTime = (int) time;
|
||||
AiIdcardrecognizeResult aiIdcardrecognizeResult = AiIdcardrecognizeResult.builder()
|
||||
.resultId(2L)
|
||||
.serviceId(1L)
|
||||
.name(idCardVo.getData().getName())
|
||||
.sex(idCardVo.getData().getGender())
|
||||
|
|
@ -82,19 +145,15 @@ public class OcrRecogServiceImpl implements IOcrRecogService {
|
|||
.issuingAuthority(idCardVo.getData().getIssuingAuthority())
|
||||
.idcardValidity(idCardVo.getData().getValidTime())
|
||||
.ifComplete(ifComplete)
|
||||
.frontImageAddress("a")
|
||||
.backImageAddress("a")
|
||||
.frontImageAddress(frontFileName)
|
||||
.backImageAddress(backFileName)
|
||||
.recognizeTime(LocalDateTime.now())
|
||||
.responseLong(2)
|
||||
.invokeIp("a")
|
||||
.updateBy("a")
|
||||
.responseLong(responseTime)
|
||||
.invokeIp(IpUtils.getIpAddr(ServletUtils.getRequest()))
|
||||
// .updateBy(loginUser.getUserid()) // 假设getUserid()已返回正确用户ID
|
||||
.updateTime(LocalDateTime.now())
|
||||
.delFlag('a')
|
||||
.build();
|
||||
System.out.println("最终结果:" + aiIdcardrecognizeResult);
|
||||
aiIdcardrecognizeMapper.insert(aiIdcardrecognizeResult);
|
||||
|
||||
return idCardVo;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package com.bonus.ai.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 文件类型工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileTypeUtils {
|
||||
public static final String FILE_TYPE_XLS = "application/vnd.ms-excel";
|
||||
public static final String FILE_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
public static final String FILE_TYPE_DOC = "application/msword";
|
||||
public static final String FILE_TYPE_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||||
public static final String FILE_TYPE_PDF = "application/pdf";
|
||||
public static final String FILE_TYPE_JSON = "application/json";
|
||||
public static final String FILE_TYPE_XML = "application/xml";
|
||||
public static final String FILE_TYPE_PNG = "image/png";
|
||||
public static final String FILE_TYPE_JPEG = "image/jpeg";
|
||||
public static final String FILE_TYPE_SVG = "image/svg";
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
* <p>
|
||||
* 例如: ruoyi.txt, 返回: txt
|
||||
*
|
||||
* @param file 文件名
|
||||
* @return 后缀(不含".")
|
||||
*/
|
||||
public static String getFileType(File file) {
|
||||
if (null == file) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return getFileType(file.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
* <p>
|
||||
* 例如: ruoyi.txt, 返回: txt
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 后缀(不含".")
|
||||
*/
|
||||
public static String getFileType(String fileName) {
|
||||
int separatorIndex = fileName.lastIndexOf(".");
|
||||
if (separatorIndex < 0) {
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(separatorIndex + 1).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
*
|
||||
* @param photoByte 文件字节码
|
||||
* @return 后缀(不含".")
|
||||
*/
|
||||
public static String getFileExtendName(byte[] photoByte) {
|
||||
String strFileExtendName = "JPG";
|
||||
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
|
||||
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
|
||||
strFileExtendName = "GIF";
|
||||
} else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
|
||||
strFileExtendName = "JPG";
|
||||
} else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
|
||||
strFileExtendName = "BMP";
|
||||
} else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
|
||||
strFileExtendName = "PNG";
|
||||
}
|
||||
return strFileExtendName;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,12 @@ server:
|
|||
port: 18083
|
||||
# Spring
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
# 文件最大
|
||||
max-file-size: 20MB
|
||||
# 设置总上传数据总大小
|
||||
max-request-size: 20MB
|
||||
application:
|
||||
# 应用名称
|
||||
name: bonus-ai
|
||||
|
|
|
|||
Loading…
Reference in New Issue