From fb47f5554c6b1b1af688bc2fc42799f1a18a6f8f Mon Sep 17 00:00:00 2001 From: jiang Date: Mon, 26 Aug 2024 17:48:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=BA=E8=84=B8=E8=AF=86=E5=88=AB=E4=B8=8E?= =?UTF-8?q?=E5=A4=A7=E6=A8=A1=E5=9E=8B=E9=97=AE=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bonus/ai/domain/vo/FaceResultVo.java | 2 +- .../service/AiFaceRecognizeResultService.java | 2 - .../AiFaceRecognizeResultServiceImpl.java | 2 +- .../ai/service/impl/FaceServiceImpl.java | 234 +++++++++--------- .../mapper/ai/AiFaceRecognizeResultMapper.xml | 3 + 5 files changed, 116 insertions(+), 127 deletions(-) diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/vo/FaceResultVo.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/vo/FaceResultVo.java index d36c1d5..068940c 100644 --- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/vo/FaceResultVo.java +++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/vo/FaceResultVo.java @@ -18,7 +18,7 @@ public class FaceResultVo implements Serializable { /** * 人脸库表id */ - private String faceId; + private Long faceId; /** * 服务id */ diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/AiFaceRecognizeResultService.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/AiFaceRecognizeResultService.java index 8481164..6b94fe0 100644 --- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/AiFaceRecognizeResultService.java +++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/AiFaceRecognizeResultService.java @@ -3,8 +3,6 @@ package com.bonus.ai.service; import com.bonus.ai.domain.vo.FaceResultVo; import com.bonus.common.core.web.domain.AjaxResult; -import java.util.List; - /** * @author bonus */ diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/AiFaceRecognizeResultServiceImpl.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/AiFaceRecognizeResultServiceImpl.java index 18c1f69..db0a1ec 100644 --- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/AiFaceRecognizeResultServiceImpl.java +++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/AiFaceRecognizeResultServiceImpl.java @@ -92,7 +92,7 @@ public class AiFaceRecognizeResultServiceImpl implements AiFaceRecognizeResultSe public AjaxResult selectAllAiFaceRecognizeResults() { try { List faceResultVos = aiFaceRecognizeResultMapper.selectAllAiFaceRecognizeResults(); - return ObjectUtils.isNotEmpty(faceResultVos) ? AjaxResult.success(faceResultVos) : AjaxResult.error(); + return AjaxResult.success(faceResultVos); } catch (Exception e) { return AjaxResult.error(); } diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/FaceServiceImpl.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/FaceServiceImpl.java index 9c7071f..c63b797 100644 --- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/FaceServiceImpl.java +++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/impl/FaceServiceImpl.java @@ -1,13 +1,17 @@ package com.bonus.ai.service.impl; +import cn.hutool.core.io.unit.DataUnit; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import com.bonus.ai.domain.vo.FaceResultVo; import com.bonus.ai.domain.vo.FaceVo; +import com.bonus.ai.mapper.AiFaceRecognizeResultMapper; import com.bonus.ai.mapper.FaceMapper; import com.bonus.ai.service.FaceService; import com.bonus.ai.utils.FaceUtils; import com.bonus.common.core.domain.R; +import com.bonus.common.core.utils.DateUtils; import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.common.security.utils.SecurityUtils; import com.bonus.system.api.RemoteFileService; @@ -17,16 +21,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.*; -/** - * @author bonus - * 人脸识别服务层 - */ @Service public class FaceServiceImpl implements FaceService { @@ -35,20 +31,18 @@ public class FaceServiceImpl implements FaceService { @Resource private RemoteFileService remoteFileService; - /** - * 查询全部人脸信息 - */ + @Resource + private AiFaceRecognizeResultMapper aiFaceRecognizeResultMapper; + + private static final Set VALID_IMAGE_TYPES = new HashSet<>(Arrays.asList("image/jpeg", "image/png")); + private static final String BASE64_PREFIX = "data:"; + private static final String BASE64_SUFFIX = ";base64,"; + @Override public AjaxResult getList() { return AjaxResult.success(faceMapper.getList()); } - /** - * 插入人脸信息 - * - * @param face 人脸信息对象 - * @return 受影响的行数 - */ @Override public AjaxResult insertFace(MultipartFile file, FaceVo face) { if (isFileOrFaceInvalid(file, face)) { @@ -57,159 +51,153 @@ public class FaceServiceImpl implements FaceService { try { String base64WithMimeType = getBase64WithMimeType(file); String response = FaceUtils.updateDb(base64WithMimeType, "add", face.getIdCardNumber()); - return handleInsertResponse(file, response, face, base64WithMimeType); + return handleInsertResponse(file, response, face); } catch (Exception e) { return AjaxResult.error("插入人脸信息失败"); } } - /** - * 人脸识别 - * - * @param file - * @return - */ @Override public AjaxResult recognition(MultipartFile file) { + long startTime = System.currentTimeMillis(); if (ObjectUtils.isEmpty(file)) { return AjaxResult.error("文件不能为空, 请选择文件"); } - try { String base64WithMimeType = getBase64WithMimeType(file); String response = FaceUtils.faceRecognition(base64WithMimeType); - return handleRecognitionResponse(response); + return handleRecognitionResponse(response, startTime); } catch (Exception e) { return AjaxResult.error("人脸识别失败"); } } - /** - * 识别结果统计 - * - * @return 结果 - */ @Override public AjaxResult resultStatistics() { return AjaxResult.success(faceMapper.resultStatistics()); } - /** - * 判断文件的 MIME 类型是否为图片类型 - */ private boolean isImageMimeType(String mimeType) { - Set validMimeTypes = new HashSet<>(); - validMimeTypes.add("image/jpeg"); - validMimeTypes.add("image/png"); - return mimeType != null && validMimeTypes.contains(mimeType); + return VALID_IMAGE_TYPES.contains(mimeType); } - /** - * 检查文件和人员信息是否为空 - */ private boolean isFileOrFaceInvalid(MultipartFile file, FaceVo face) { return ObjectUtils.isEmpty(file) || ObjectUtils.isEmpty(face.getName()) || ObjectUtils.isEmpty(face.getIdCardNumber()); } - /** - * 获取Base64编码的文件内容,并添加MIME类型 - */ private String getBase64WithMimeType(MultipartFile file) throws Exception { String mimeType = file.getContentType(); if (!isImageMimeType(mimeType)) { throw new IllegalArgumentException("文件类型不支持,请上传图片文件"); } - byte[] fileBytes = file.getBytes(); String base64String = Base64.getEncoder().encodeToString(fileBytes); - return "data:" + mimeType + ";base64," + base64String; + return BASE64_PREFIX + mimeType + BASE64_SUFFIX + base64String; } - /** - * 处理插入人脸信息的响应 - */ - private AjaxResult handleInsertResponse(MultipartFile file, String response, FaceVo face, String base64WithMimeType) { - if (response == null) return AjaxResult.error(); - JSONObject jsonObject = JSON.parseObject(response); - String code = jsonObject.getString("code"); - switch (code) { - case "30002": - face.setCreateTime(new Date()); - face.setCreateBy(SecurityUtils.getUsername()); - face.setUpdateBy(SecurityUtils.getUsername()); - face.setUpdateTime(new Date()); - try { - R upload = remoteFileService.upload(file); - if (upload.getCode() == 200) { - face.setFaceAddress(upload.getData().getUrl().replaceFirst("http://[^/]+", "")); - return faceMapper.insertFace(face) > 0 ? AjaxResult.success() : AjaxResult.error(); - } else { - return AjaxResult.error(); - } - - } catch (Exception e) { - return AjaxResult.error(); - } - case "30006": - return AjaxResult.error("文件类型不支持"); - case "30007": - return AjaxResult.error("不支持的操作类型"); - case "30008": - return AjaxResult.error("存在多张人脸"); - case "30009": - return AjaxResult.error("光照条件差"); - case "30016": - return AjaxResult.error("人脸图片不清晰"); - case "30010": - case "30011": - return AjaxResult.error("人脸不全"); - case "30019": - return AjaxResult.error("人员信息已存在"); - case "30018": - return AjaxResult.error("未检测到人脸"); - default: - return AjaxResult.error(); - } - } - - /** - * 处理人脸识别的响应 - */ - private AjaxResult handleRecognitionResponse(String response) { + private AjaxResult handleInsertResponse(MultipartFile file, String response, FaceVo face) { if (response == null) { return AjaxResult.error(); } JSONObject jsonObject = JSON.parseObject(response); String code = jsonObject.getString("code"); - switch (code) { - case "30000": - JSONArray dataArray = jsonObject.getJSONArray("data"); - String idCardNumber = dataArray.getString(0); - List faceByIdCardNumber = faceMapper.getFaceByIdCardNumber(idCardNumber); - return faceByIdCardNumber != null && !faceByIdCardNumber.isEmpty() - ? AjaxResult.success(faceByIdCardNumber.get(0)) - : AjaxResult.error("人员不存在"); - case "30001": - return AjaxResult.error("人员不存在"); - case "30006": - return AjaxResult.error("文件类型不支持"); - case "30007": - return AjaxResult.error("不支持的操作类型"); - case "30008": - return AjaxResult.error("存在多张人脸"); - case "30009": - return AjaxResult.error("光照条件差"); - case "30010": - case "30011": - return AjaxResult.error("人脸不全"); - case "30019": - return AjaxResult.error("人员信息已存在"); - case "30018": - return AjaxResult.error("未检测到人脸"); - default: + + if ("30002".equals(code)) { + face.setCreateTime(new Date()); + face.setCreateBy(SecurityUtils.getUsername()); + face.setUpdateBy(SecurityUtils.getUsername()); + face.setUpdateTime(new Date()); + + try { + return handleFileUpload(file, face); + } catch (Exception e) { return AjaxResult.error(); + } } + + return handleCommonErrors(code, null, 0); + } + + private AjaxResult handleFileUpload(MultipartFile file, FaceVo face) throws Exception { + R upload = remoteFileService.upload(file); + if (upload.getCode() == 200) { + face.setFaceAddress(upload.getData().getUrl().replaceFirst("http://[^/]+", "")); + return faceMapper.insertFace(face) > 0 ? AjaxResult.success() : AjaxResult.error(); + } + return AjaxResult.error(); + } + + private AjaxResult handleCommonErrors(String code, FaceResultVo faceResultVo, long startTime) { + Map errorMessages = new HashMap<>(); + errorMessages.put("30006", "文件类型不支持"); + errorMessages.put("30007", "不支持的操作类型"); + errorMessages.put("30008", "存在多张人脸"); + errorMessages.put("30009", "光照条件差"); + errorMessages.put("30016", "人脸图片不清晰"); + errorMessages.put("30010", "人脸不全"); + errorMessages.put("30011", "人脸不全"); + errorMessages.put("30019", "人员信息已存在"); + errorMessages.put("30018", "未检测到人脸"); + if (ObjectUtils.isEmpty(faceResultVo)) { + faceResultVo.setResultStatus("1"); + faceResultVo.setFailureReason(errorMessages.get(code)); + long endTime = System.currentTimeMillis(); + long elapsedTime = endTime - startTime; + faceResultVo.setResponseLong(String.valueOf(elapsedTime)); + aiFaceRecognizeResultMapper.insertAiFaceRecognizeResult(faceResultVo); + } + return errorMessages.containsKey(code) + ? AjaxResult.error(errorMessages.get(code)) + : AjaxResult.error(); + } + + private AjaxResult handleRecognitionResponse(String response, long startTime) { + if (response == null) { + return AjaxResult.error(); + } + JSONObject jsonObject = JSON.parseObject(response); + String code = jsonObject.getString("code"); + FaceResultVo faceResultVo = buildFaceResultVo(); + if ("30000".equals(code)) { + return handleRecognitionSuccess(jsonObject, faceResultVo, startTime); + } + return handleCommonErrors(code, faceResultVo, startTime); + } + + private FaceResultVo buildFaceResultVo() { + FaceResultVo faceResultVo = new FaceResultVo(); + faceResultVo.setInvokeIp("192.168.0.14"); + faceResultVo.setServiceId("4"); + faceResultVo.setResultType("0"); + faceResultVo.setDelFlag("0"); + faceResultVo.setUpdateBy(SecurityUtils.getUsername()); + faceResultVo.setUpdateTime(DateUtils.getTime()); + faceResultVo.setRecognizeTime(DateUtils.getTime()); + return faceResultVo; + } + + private AjaxResult handleRecognitionSuccess(JSONObject jsonObject, FaceResultVo faceResultVo, long startTime) { + JSONArray dataArray = jsonObject.getJSONArray("data"); + String idCardNumber = dataArray.getString(0); + List faceByIdCardNumber = faceMapper.getFaceByIdCardNumber(idCardNumber); + if (faceByIdCardNumber != null && !faceByIdCardNumber.isEmpty()) { + faceResultVo.setFaceId(faceByIdCardNumber.get(0).getFaceId()); + faceResultVo.setFaceAddress(faceByIdCardNumber.get(0).getFaceAddress()); + faceResultVo.setResultStatus("0"); + long endTime = System.currentTimeMillis(); + long elapsedTime = endTime - startTime; + faceResultVo.setResponseLong(String.valueOf(elapsedTime)); + aiFaceRecognizeResultMapper.insertAiFaceRecognizeResult(faceResultVo); + return AjaxResult.success(faceByIdCardNumber.get(0)); + } + faceResultVo.setResultStatus("1"); + faceResultVo.setFailureReason("人员不存在"); + long endTime = System.currentTimeMillis(); + long elapsedTime = endTime - startTime; + faceResultVo.setResponseLong(String.valueOf(elapsedTime)); + aiFaceRecognizeResultMapper.insertAiFaceRecognizeResult(faceResultVo); + return AjaxResult.error("人员不存在"); } } diff --git a/bonus-modules/bonus-ai/src/main/resources/mapper/ai/AiFaceRecognizeResultMapper.xml b/bonus-modules/bonus-ai/src/main/resources/mapper/ai/AiFaceRecognizeResultMapper.xml index 869b761..2cf63fb 100644 --- a/bonus-modules/bonus-ai/src/main/resources/mapper/ai/AiFaceRecognizeResultMapper.xml +++ b/bonus-modules/bonus-ai/src/main/resources/mapper/ai/AiFaceRecognizeResultMapper.xml @@ -37,6 +37,7 @@ result_status = #{resultStatus}, failure_reason = #{failureReason} WHERE result_id = #{resultId} + AND del_flag = '0' @@ -57,6 +58,7 @@ failure_reason AS failureReason FROM ai_facerecognize_result WHERE result_id = #{resultId} + AND del_flag = '0' @@ -76,6 +78,7 @@ result_status AS resultStatus, failure_reason AS failureReason FROM ai_facerecognize_result + WHERE del_flag = '0'