materials;
}
diff --git a/src/main/java/com/gxwebsoft/hjc/dto/HjcOcrRecognizeRequest.java b/src/main/java/com/gxwebsoft/hjc/dto/HjcOcrRecognizeRequest.java
new file mode 100644
index 0000000..dfdb5e0
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/hjc/dto/HjcOcrRecognizeRequest.java
@@ -0,0 +1,18 @@
+package com.gxwebsoft.hjc.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 汇吉采 证件 OCR 识别请求
+ */
+@Data
+@Schema(name = "HjcOcrRecognizeRequest", description = "汇吉采证件OCR识别请求")
+public class HjcOcrRecognizeRequest {
+
+ @Schema(description = "材料类型:idcard_front(身份证人像面)/ license(营业执照)", required = true)
+ private String materialType;
+
+ @Schema(description = "已上传证件的可访问地址(fileUrl)", required = true)
+ private String fileUrl;
+}
diff --git a/src/main/java/com/gxwebsoft/hjc/dto/HjcOcrResult.java b/src/main/java/com/gxwebsoft/hjc/dto/HjcOcrResult.java
new file mode 100644
index 0000000..330830b
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/hjc/dto/HjcOcrResult.java
@@ -0,0 +1,36 @@
+package com.gxwebsoft.hjc.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 汇吉采 证件 OCR 识别结果
+ *
+ * 字段按材料类型填写:营业执照填 enterpriseName/creditCode/address/legalPerson;
+ * 身份证人像面填 agentName/idCardNo;未识别到的字段为 null。
+ */
+@Data
+@Schema(name = "HjcOcrResult", description = "汇吉采证件OCR识别结果")
+public class HjcOcrResult {
+
+ @Schema(description = "材料类型:idcard_front / license")
+ private String materialType;
+
+ @Schema(description = "营业执照-企业名称(仅作只读核对,不覆盖登录账号)")
+ private String enterpriseName;
+
+ @Schema(description = "营业执照-统一社会信用代码")
+ private String creditCode;
+
+ @Schema(description = "营业执照-住所/企业地址")
+ private String address;
+
+ @Schema(description = "营业执照-法定代表人(仅展示供人工参考)")
+ private String legalPerson;
+
+ @Schema(description = "身份证-经办人姓名")
+ private String agentName;
+
+ @Schema(description = "身份证-经办人身份证号")
+ private String idCardNo;
+}
diff --git a/src/main/java/com/gxwebsoft/hjc/entity/HjcEnterprise.java b/src/main/java/com/gxwebsoft/hjc/entity/HjcEnterprise.java
index 165135e..83cd57c 100644
--- a/src/main/java/com/gxwebsoft/hjc/entity/HjcEnterprise.java
+++ b/src/main/java/com/gxwebsoft/hjc/entity/HjcEnterprise.java
@@ -55,6 +55,9 @@ public class HjcEnterprise implements Serializable {
@Schema(description = "经办人手机号")
private String agentPhone;
+ @Schema(description = "经办人身份证号")
+ private String idCardNo;
+
@Schema(description = "授权委托书到期时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime authorizeExpire;
diff --git a/src/main/java/com/gxwebsoft/hjc/service/HjcOcrService.java b/src/main/java/com/gxwebsoft/hjc/service/HjcOcrService.java
new file mode 100644
index 0000000..e7bfd43
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/hjc/service/HjcOcrService.java
@@ -0,0 +1,18 @@
+package com.gxwebsoft.hjc.service;
+
+import com.gxwebsoft.hjc.dto.HjcOcrResult;
+
+/**
+ * 汇吉采 证件 OCR 识别(阿里云文字识别 OCR,服务端调用)
+ */
+public interface HjcOcrService {
+
+ /**
+ * 识别证件
+ *
+ * @param materialType 材料类型:idcard_front(身份证人像面)/ license(营业执照)
+ * @param fileUrl 已上传证件的可访问地址
+ * @return 识别结果;不支持的材料类型或识别失败返回 null
+ */
+ HjcOcrResult recognize(String materialType, String fileUrl);
+}
diff --git a/src/main/java/com/gxwebsoft/hjc/service/impl/HjcOcrServiceImpl.java b/src/main/java/com/gxwebsoft/hjc/service/impl/HjcOcrServiceImpl.java
new file mode 100644
index 0000000..373e1ff
--- /dev/null
+++ b/src/main/java/com/gxwebsoft/hjc/service/impl/HjcOcrServiceImpl.java
@@ -0,0 +1,107 @@
+package com.gxwebsoft.hjc.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.ocr.model.v20191230.RecognizeBusinessLicenseRequest;
+import com.aliyuncs.ocr.model.v20191230.RecognizeBusinessLicenseResponse;
+import com.aliyuncs.ocr.model.v20191230.RecognizeIdentityCardRequest;
+import com.aliyuncs.ocr.model.v20191230.RecognizeIdentityCardResponse;
+import com.aliyuncs.profile.DefaultProfile;
+import com.gxwebsoft.hjc.dto.HjcOcrResult;
+import com.gxwebsoft.hjc.service.HjcOcrService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * 汇吉采 证件 OCR 识别实现(阿里云文字识别 OCR)
+ *
+ * AK 需具备 OCR 服务权限;未配置(占位值为空)时直接返回 null,由前端提示「识别失败,请手动填写」,
+ * 不阻断注册流程。
+ */
+@Service
+public class HjcOcrServiceImpl implements HjcOcrService {
+
+ /** 材料类型:身份证人像面 */
+ public static final String MATERIAL_IDCARD_FRONT = "idcard_front";
+ /** 材料类型:营业执照 */
+ public static final String MATERIAL_LICENSE = "license";
+
+ @Value("${aliyun.ocr.access-key-id:}")
+ private String accessKeyId;
+
+ @Value("${aliyun.ocr.access-key-secret:}")
+ private String accessKeySecret;
+
+ @Value("${aliyun.ocr.region:cn-hangzhou}")
+ private String region;
+
+ @Value("${aliyun.ocr.endpoint:ocr-api.cn-hangzhou.aliyuncs.com}")
+ private String endpoint;
+
+ @Override
+ public HjcOcrResult recognize(String materialType, String fileUrl) {
+ if (StrUtil.isBlank(materialType) || StrUtil.isBlank(fileUrl)) {
+ return null;
+ }
+ if (StrUtil.isBlank(accessKeyId) || StrUtil.isBlank(accessKeySecret)) {
+ // OCR 未配置 AK(占位),不阻断注册
+ System.out.println("HjcOcr: aliyun.ocr 未配置 AccessKey,跳过识别");
+ return null;
+ }
+ try {
+ IAcsClient client = createClient();
+ if (MATERIAL_IDCARD_FRONT.equals(materialType)) {
+ return recognizeIdCard(client, fileUrl);
+ }
+ if (MATERIAL_LICENSE.equals(materialType)) {
+ return recognizeBusinessLicense(client, fileUrl);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private IAcsClient createClient() throws Exception {
+ DefaultProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
+ DefaultProfile.addEndpoint(region, region, "ocr", endpoint);
+ return new DefaultAcsClient(profile);
+ }
+
+ /** 身份证人像面:回填经办人姓名 + 身份证号 */
+ private HjcOcrResult recognizeIdCard(IAcsClient client, String fileUrl) throws Exception {
+ RecognizeIdentityCardRequest request = new RecognizeIdentityCardRequest();
+ request.setImageURL(fileUrl);
+ request.setSide("face");
+ RecognizeIdentityCardResponse response = client.getAcsResponse(request);
+ if (response == null || response.getData() == null
+ || response.getData().getFrontResult() == null) {
+ return null;
+ }
+ RecognizeIdentityCardResponse.Data.FrontResult front = response.getData().getFrontResult();
+ HjcOcrResult result = new HjcOcrResult();
+ result.setMaterialType(MATERIAL_IDCARD_FRONT);
+ result.setAgentName(front.getName());
+ result.setIdCardNo(front.getIDNumber());
+ return result;
+ }
+
+ /** 营业执照:回填统一社会信用代码 + 企业地址;企业名称/法定代表人仅作展示提示 */
+ private HjcOcrResult recognizeBusinessLicense(IAcsClient client, String fileUrl) throws Exception {
+ RecognizeBusinessLicenseRequest request = new RecognizeBusinessLicenseRequest();
+ request.setImageURL(fileUrl);
+ RecognizeBusinessLicenseResponse response = client.getAcsResponse(request);
+ if (response == null || response.getData() == null) {
+ return null;
+ }
+ RecognizeBusinessLicenseResponse.Data data = response.getData();
+ HjcOcrResult result = new HjcOcrResult();
+ result.setMaterialType(MATERIAL_LICENSE);
+ result.setEnterpriseName(data.getName());
+ result.setCreditCode(data.getRegisterNumber());
+ result.setAddress(data.getAddress());
+ result.setLegalPerson(data.getLegalPerson());
+ return result;
+ }
+}
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 7c17894..1073da1 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -77,3 +77,9 @@ aliyun:
access-key-id: LTAI5tEsyhW4GCKbds1qsopg
access-key-secret: zltFlQrYVAoq2KMFDWgLa3GhkMNeyO
endpoint: mt.cn-hangzhou.aliyuncs.com
+ # 阿里云文字识别 OCR(身份证/营业执照识别),AK 需具备 OCR 服务权限;未开通前为占位值
+ ocr:
+ access-key-id: ""
+ access-key-secret: ""
+ region: cn-hangzhou
+ endpoint: ocr-api.cn-hangzhou.aliyuncs.com
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 3c1c894..57246f8 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -105,6 +105,14 @@ config:
bucketDomain: https://oss.wsdns.cn
aliyunDomain: https://oss-gxwebsoft.oss-cn-shenzhen.aliyuncs.com
+# 阿里云文字识别 OCR(身份证/营业执照识别),AK 需具备 OCR 服务权限;未开通前为占位值
+aliyun:
+ ocr:
+ access-key-id: ""
+ access-key-secret: ""
+ region: cn-hangzhou
+ endpoint: ocr-api.cn-hangzhou.aliyuncs.com
+
# 商城订单配置
shop:
order:
diff --git a/src/main/resources/sql/hjc_enterprise_add_id_card_no.sql b/src/main/resources/sql/hjc_enterprise_add_id_card_no.sql
new file mode 100644
index 0000000..79c1128
--- /dev/null
+++ b/src/main/resources/sql/hjc_enterprise_add_id_card_no.sql
@@ -0,0 +1,3 @@
+-- 汇吉采:企业资质新增「经办人身份证号」字段(注册/资质认证页,身份证人像面 OCR 回填)
+ALTER TABLE `hjc_enterprise`
+ ADD COLUMN `id_card_no` varchar(64) DEFAULT NULL COMMENT '经办人身份证号' AFTER `agent_phone`;
diff --git a/src/main/resources/sql/hjc_init.sql b/src/main/resources/sql/hjc_init.sql
index 7d85dfd..20cfbe9 100644
--- a/src/main/resources/sql/hjc_init.sql
+++ b/src/main/resources/sql/hjc_init.sql
@@ -51,6 +51,7 @@ CREATE TABLE `hjc_enterprise` (
`agent_name` varchar(64) DEFAULT NULL COMMENT '经办人姓名',
`agent_email` varchar(128) DEFAULT NULL COMMENT '经办人邮箱',
`agent_phone` varchar(32) DEFAULT NULL COMMENT '经办人手机号',
+ `id_card_no` varchar(64) DEFAULT NULL COMMENT '经办人身份证号',
`authorize_expire` datetime DEFAULT NULL COMMENT '授权委托书到期时间',
`auth_status` tinyint(4) DEFAULT 0 COMMENT '资质状态:0待审核 1已通过 2已驳回',
`reject_reason` varchar(500) DEFAULT NULL COMMENT '驳回原因',