kongxiangyang 3 päivää sitten
vanhempi
commit
b9999df7a9

+ 8 - 11
crm-manager/src/main/java/com/crm/manager/service/impl/OcrServiceImpl.java

@@ -1,6 +1,7 @@
 package com.crm.manager.service.impl;
 
 import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import com.crm.manager.config.ImageConfig;
 import com.crm.manager.repository.ImageRecognizeConfigRepository;
 import com.crm.manager.service.OcrService;
@@ -11,17 +12,13 @@ import com.crm.rely.backend.core.dto.base.BaseResultDto;
 import com.crm.rely.backend.core.exception.ServiceException;
 import com.crm.rely.backend.core.pojo.table.SysConfigTable;
 import com.crm.rely.backend.model.constant.ConfigConstants;
-import com.crm.rely.backend.model.entity.ocr.IdCardData;
 import com.crm.rely.backend.model.entity.ocr.OcrCheckEntity;
-import com.crm.rely.backend.model.entity.ocr.OcrResult;
 import com.crm.rely.backend.model.pojo.table.ImageRecognizeConfigTable;
 import com.crm.rely.backend.util.AESUtil;
-import org.apache.commons.lang3.StringUtils;
 import org.jsoup.Connection;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -49,8 +46,8 @@ public class OcrServiceImpl implements OcrService {
             entity.setImageBase64(HutoolAesUtil.decrypt(entity.getImageBase64(),getPropertyKey()));
             // 这里开始调用 python 接口
             ImageConfig imageConfig = getImagePythonConfig();
-            return BaseResultDto.success(Constants.SUCCESS, HutoolAesUtil.encrypt(JSON.toJSONString(idCardOcr(entity.getImageBase64(),imageConfig.getOcrRequestUrl())),getPropertyKey()));
-        } catch (UnsupportedEncodingException e) {
+            return BaseResultDto.success(Constants.SUCCESS, HutoolAesUtil.encrypt(idCardOcr(entity.getImageBase64(),imageConfig.getOcrRequestUrl()),getPropertyKey()));
+        } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
@@ -93,7 +90,7 @@ public class OcrServiceImpl implements OcrService {
      * @param base64Image 图片 base64 字符串(不带前缀 data:image/png;base64,)
      * @return IdCardData 识别后的身份证实体
      */
-    public static IdCardData idCardOcr(String base64Image,String url) {
+    public static String idCardOcr(String base64Image,String url) {
         try {
             // 1. 接口地址
 //            String url = "http://103.214.175.29:5000/ocr/idcard/base64";
@@ -111,12 +108,12 @@ public class OcrServiceImpl implements OcrService {
             String json = response.body();
 
             // 5. 解析结果
-            OcrResult result = JSON.parseObject(json, OcrResult.class);
+            JSONObject result = JSON.parseObject(json, JSONObject.class);
 
-            if (result.getCode() == 0) {
-                return result.getData();
+            if (result.getIntValue("code") == 0) {
+                return result.getJSONObject("data").getString("full_text");
             } else {
-                System.err.println("OCR 识别失败:" + result.getMsg());
+                System.err.println("OCR 识别失败:" + result.getString("msg"));
                 return null;
             }
 

+ 64 - 0
crm-manager/src/main/java/com/crm/manager/util/HkIdCardOcrUtil.java

@@ -0,0 +1,64 @@
+package com.crm.manager.util;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
+
+public class HkIdCardOcrUtil {
+
+    public static OcrResultDto parseHkIdCard(String fullText) {
+        OcrResultDto dto = new OcrResultDto();
+        if (StrUtil.isBlank(fullText)) {
+            return dto;
+        }
+
+        // 1. 精准提取姓名:证件标题之后,出生日期之前的中英文内容
+        String nameContent = ReUtil.getGroup1("香港永久性居民身份證(.+?)出生日期", fullText);
+        if (StrUtil.isNotBlank(nameContent)) {
+            dto.setName(StrUtil.trim(nameContent));
+        }
+
+        // 2. 性别:F女 M男,原样返回
+        String gender = ReUtil.getGroup1("(F|M)", fullText);
+        dto.setGender(StrUtil.trim(gender));
+
+        // 3. 无民族信息
+        dto.setEthnicity(null);
+
+        // 4. 出生日期 dd-MM-yyyy 转 yyyy-MM-dd
+        String birthStr = ReUtil.getGroup1("(\\d{2}-\\d{2}-\\d{4})", fullText);
+        dto.setBirthDate(formatBirthDate(birthStr));
+
+        // 5. 香港身份证无地址
+        dto.setAddress(null);
+
+        // 6. 香港身份证号
+        String idCard = ReUtil.getGroup1("([A-Z]\\d{6}\\([A-Z]\\))", fullText);
+        dto.setIdCard(StrUtil.trim(idCard));
+
+        return dto;
+    }
+
+    private static String formatBirthDate(String dateStr) {
+        if (StrUtil.isBlank(dateStr)) {
+            return null;
+        }
+        String[] arr = dateStr.split("-");
+        if (arr.length != 3) {
+            return null;
+        }
+        try {
+            String day = arr[0];
+            String month = arr[1];
+            String year = arr[2];
+            return String.format("%s-%02d-%02d", year, Integer.parseInt(month), Integer.parseInt(day));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        String text = "香港永久性居民身份證HONG KONGPERMANENTIDENTITY CARD李智能LEE,ChiiNan262125355174出生日期DateofBirth女F01-01-1968***AZ签發日期DateofIssue(01-79)15-09-03C668668(E)";
+        OcrResultDto dto = parseHkIdCard(text);
+        System.out.println(dto);
+    }
+}

+ 38 - 0
crm-manager/src/main/java/com/crm/manager/util/OcrResultDto.java

@@ -0,0 +1,38 @@
+package com.crm.manager.util;
+
+import lombok.Data;
+
+@Data
+public class OcrResultDto {
+    /**
+     * 姓名
+     */
+    private String name;
+
+    /**
+     * 性别:男/女
+     */
+    private String gender;
+
+    /**
+     * 民族:汉/回/壮等
+     */
+    private String ethnicity;
+
+    /**
+     * 出生日期:yyyy-MM-dd
+     */
+    private String birthDate;
+
+    /**
+     * 住址
+     */
+    private String address;
+
+    /**
+     * 身份证号码
+     */
+    private String idCard;
+
+    private String[] names;
+}

+ 77 - 0
crm-manager/src/main/java/com/crm/manager/util/VietIdCardOcrUtil.java

@@ -0,0 +1,77 @@
+package com.crm.manager.util;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
+
+public class VietIdCardOcrUtil {
+
+    /**
+     * 解析越南身份证正反面OCR全文,封装到OcrResultDto
+     * @param frontFullText 正面full_text
+     * @param backFullText 反面full_text
+     * @return OcrResultDto
+     */
+    public static OcrResultDto parseVietIdCard(String frontFullText, String backFullText) {
+        OcrResultDto dto = new OcrResultDto();
+        if (StrUtil.isBlank(frontFullText) && StrUtil.isBlank(backFullText)) {
+            return dto;
+        }
+        String allText = StrUtil.emptyToDefault(frontFullText, "") + StrUtil.emptyToDefault(backFullText, "");
+
+        // 1. 姓名
+        String name = ReUtil.getGroup1("Full name\\.(.+?)(Gioi tinh|Sex|$)", allText);
+        dto.setName(StrUtil.trim(name));
+
+        // 2. 性别:直接提取Nam/Nu,不转中文,去掉单词边界适配粘连文本
+        String genderRaw = ReUtil.getGroup1("(Nam|Nu)", allText);
+        dto.setGender(StrUtil.trim(genderRaw));
+
+        // 3. 国籍存入ethnicity
+        String nationality = ReUtil.getGroup1("Nationality(.+?)(\\d|$)", allText);
+        dto.setEthnicity(StrUtil.trim(nationality));
+
+        // 4. 直接正则匹配 dd/MM/yyyy 标准日期
+        String birthDateStr = ReUtil.getGroup1("(\\d{2}/\\d{2}/\\d{4})", allText);
+        dto.setBirthDate(parseDDMMYYYYToYMD(StrUtil.trim(birthDateStr)));
+
+        // 5. 常住地址
+        String address = ReUtil.getGroup1("Placeofresidence\\.(.+?)(Noidangky|Placeofbirth|$)", backFullText);
+        dto.setAddress(StrUtil.trim(address));
+
+        // 6. 12位身份证号码
+        String idCard = ReUtil.getGroup1("Personal identification number(\\d{12})", allText);
+        dto.setIdCard(StrUtil.trim(idCard));
+
+        return dto;
+    }
+
+    /**
+     * dd/MM/yyyy 转 yyyy-MM-dd
+     */
+    private static String parseDDMMYYYYToYMD(String dateStr) {
+        if (StrUtil.isBlank(dateStr)) {
+            return null;
+        }
+        String[] arr = dateStr.split("/");
+        if (arr.length != 3) {
+            return null;
+        }
+        try {
+            int day = Integer.parseInt(arr[0]);
+            int month = Integer.parseInt(arr[1]);
+            int year = Integer.parseInt(arr[2]);
+            return String.format("%04d-%02d-%02d", year, month, day);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+
+    // 测试
+    public static void main(String[] args) {
+        String front = "CONG HOA XA HOI CHU NGHIA VIET NAMDoc lap-Tu do-Hanh phucSOCIALIST REPUBLIC OFVIET NAMIndependence-Ereedom-HappinessCAN CU'O'CIDENTITY CARDSo dinh danh ca nhan/Personal identification number056200008442Ho, chu dem va ten khai sinh / Full name.TRAN THENGUYENGioi tinh/ SexNgay,thang,nam sinh/Date of birthNam28/11/2000Quoc tich/ NationalityViet Nam3";
+        String back = "Noicutru/Placeofresidence.ThonTanSinhTayCam Lam,KhanhHoaNoidangkykhai sinh/PlaceofbirthCam Lam,KhanhHoaNgay,thang,namcap/Dateofissue17/11/2025Ngay,thang,nam het han/Date of expiry.28/11/2040BOCONGAN/MINISTRYOFPUBLICSECURITYIDVNM2000084424056200008442<<50011282M4011280VNM<<<<<<<<<<<6TRAN<<THE<NGUYEN<<<<<<<<<<<<<";
+
+        OcrResultDto dto = parseVietIdCard(front, back);
+        System.out.println(dto);
+    }
+}

+ 0 - 3
crm-manager/src/main/resources/application-dev.yml

@@ -23,9 +23,6 @@ web:
 role:
   excludePathPatterns:
     /**
-
-ocr:
-  host: http://103.214.175.29:5000/ocr/idcard/base64
 #logging:
 #  config: classpath:logback-dev.xml
 

+ 6 - 0
crm-model/pom.xml

@@ -82,5 +82,11 @@
             <artifactId>hutool-crypto</artifactId>
             <version>5.8.25</version>
         </dependency>
+
+        <dependency>
+            <groupId>com.maxmind.geoip2</groupId>
+            <artifactId>geoip2</artifactId>
+            <version>4.2.0</version>
+        </dependency>
     </dependencies>
 </project>

+ 3 - 0
crm-model/src/main/java/com/crm/rely/backend/model/entity/ocr/OcrCheckEntity.java

@@ -4,5 +4,8 @@ import lombok.Data;
 
 @Data
 public class OcrCheckEntity {
+    /**
+     * 图片 base64 值
+     */
     private String imageBase64;
 }