From 4da1379f67758184be2c9865ca1f36c01baee76c Mon Sep 17 00:00:00 2001 From: GUO <1923636941@qq.com> Date: Sun, 16 Jun 2024 23:48:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=B7=E5=BA=B7=E4=B8=8B=E5=8F=91=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/zhgd/xmgl/call/HikvisionCall.java | 30 ++- .../service/impl/WorkerInfoServiceImpl.java | 66 +++-- .../controller/XzHikvisionSyncController.java | 2 +- .../java/com/zhgd/xmgl/util/IdCardUtils.java | 242 +++++++++++++++--- 4 files changed, 269 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java b/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java index bd9fbe9af..f18007376 100644 --- a/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java +++ b/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java @@ -1307,19 +1307,21 @@ public class HikvisionCall { * @param project */ public void saveWorkerFace(WorkerInfo workerInfo, Project project) throws Exception { - ArrayList workerFaceIds = getWorkerFaceIds(String.valueOf(workerInfo.getId()), project); - if (CollUtil.isNotEmpty(workerFaceIds)) { - String workerFaceId = workerFaceIds.get(0); - final String ARTEMIS_PATH = "/artemis"; - final String path = ARTEMIS_PATH + "/api/resource/v1/face/single/update"; - String host = "https://" + project.getArtemisConfigHost(); - JSONObject jo = new JSONObject(); - jo.put("faceId", workerFaceId); - jo.put("faceData", Base64Util.convertFileToBase64(PathUtil.reviseSlash(basePath + "/" + workerInfo.getFieldAcquisitionUrl()))); - String rs = HikvisionUtil.doPost(host, path, jo.toJSONString(), null, project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()); - sendNoticeAndSetStatusForWorker("更新人员照片到海康isc", rs, workerInfo, 2, 2, true); - } else { - addWorkerFace(workerInfo, project); + if (StrUtil.isNotBlank(workerInfo.getFieldAcquisitionUrl())) { + ArrayList workerFaceIds = getWorkerFaceIds(String.valueOf(workerInfo.getId()), project); + if (CollUtil.isNotEmpty(workerFaceIds)) { + String workerFaceId = workerFaceIds.get(0); + final String ARTEMIS_PATH = "/artemis"; + final String path = ARTEMIS_PATH + "/api/resource/v1/face/single/update"; + String host = "https://" + project.getArtemisConfigHost(); + JSONObject jo = new JSONObject(); + jo.put("faceId", workerFaceId); + jo.put("faceData", Base64Util.convertFileToBase64(PathUtil.reviseSlash(basePath + "/" + workerInfo.getFieldAcquisitionUrl()))); + String rs = HikvisionUtil.doPost(host, path, jo.toJSONString(), null, project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()); + sendNoticeAndSetStatusForWorker("更新人员照片到海康isc", rs, workerInfo, 2, 2, true); + } else { + addWorkerFace(workerInfo, project); + } } } @@ -1346,7 +1348,7 @@ public class HikvisionCall { } public void deleteWorkerFace(String uniqueId, WorkerInfo workerInfo, Project project, boolean sendNotice) throws Exception { - ArrayList workerFaceIds = getWorkerFaceIds(uniqueId, project); + List workerFaceIds = getWorkerFaceIds(uniqueId, project); if (CollUtil.isNotEmpty(workerFaceIds)) { for (String workerFaceId : workerFaceIds) { JSONObject rsJo = HikvisionUtil.deleteWorkerFace(project, workerFaceId); diff --git a/src/main/java/com/zhgd/xmgl/modules/worker/service/impl/WorkerInfoServiceImpl.java b/src/main/java/com/zhgd/xmgl/modules/worker/service/impl/WorkerInfoServiceImpl.java index 5f26bac84..2ac9f9f43 100644 --- a/src/main/java/com/zhgd/xmgl/modules/worker/service/impl/WorkerInfoServiceImpl.java +++ b/src/main/java/com/zhgd/xmgl/modules/worker/service/impl/WorkerInfoServiceImpl.java @@ -59,6 +59,7 @@ import com.zhgd.xmgl.modules.worker.service.*; import com.zhgd.xmgl.modules.xz.entity.XzHikvisionSync; import com.zhgd.xmgl.modules.xz.mapper.XzHikvisionSyncMapper; import com.zhgd.xmgl.modules.xz.service.impl.XzSupplierQualificationApplyServiceImpl; +import com.zhgd.xmgl.security.entity.UserInfo; import com.zhgd.xmgl.security.util.SecurityUtils; import com.zhgd.xmgl.util.*; import lombok.extern.slf4j.Slf4j; @@ -1684,6 +1685,9 @@ public class WorkerInfoServiceImpl extends ServiceImpl result = new Result(); StringBuilder existName = new StringBuilder(""); + ArrayList errIdCards = new ArrayList<>(); + String rtMsg = ""; + String existMsg = ""; String ufaceId = null; try { InputStream is = excelFile.getInputStream(); @@ -1805,40 +1809,56 @@ public class WorkerInfoServiceImpl extends ServiceImpl queryById(@RequestParam(name = "id", required = true) String id) { - Result result = new Result(); + Result result = new Result<>(); XzHikvisionSync xzHikvisionSync = xzHikvisionSyncService.getById(id); if (xzHikvisionSync == null) { result.error500("未找到对应实体"); diff --git a/src/main/java/com/zhgd/xmgl/util/IdCardUtils.java b/src/main/java/com/zhgd/xmgl/util/IdCardUtils.java index 58f14f3e1..cba6b4a3d 100644 --- a/src/main/java/com/zhgd/xmgl/util/IdCardUtils.java +++ b/src/main/java/com/zhgd/xmgl/util/IdCardUtils.java @@ -4,10 +4,12 @@ import cn.hutool.http.HttpRequest; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.*; +import java.util.regex.Pattern; /** * @program: wisdomSite @@ -19,6 +21,46 @@ import java.util.*; @Slf4j public class IdCardUtils { + /** + * 大陆地区地域编码最大值 + **/ + public static final int MAX_MAINLAND_AREACODE = 659004; + /** + * 大陆地区地域编码最小值 + **/ + public static final int MIN_MAINLAND_AREACODE = 110000; + /** + * 香港地域编码值 + **/ + public static final int HONGKONG_AREACODE = 810000; // 香港地域编码值 + /** + * 台湾地域编码值 + **/ + public static final int TAIWAN_AREACODE = 710000; + /** + * 澳门地域编码值 + **/ + public static final int MACAO_AREACODE = 820000; + /** + * 数字正则 + **/ + public static final String regexNum = "^[0-9]*$"; + /** + * 闰年生日正则 + **/ + public static final String regexBirthdayInLeapYear = "^((19[0-9]{2})|(200[0-9])|(201[0-5]))((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))$"; + /** + * 平年生日正则 + **/ + public static final String regexBirthdayInCommonYear = "^((19[0-9]{2})|(200[0-9])|(201[0-5]))((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))$"; + private static final HashSet BLACK_SET = new HashSet() { + + private static final long serialVersionUID = 48136604486603324L; + + { + add("111111111111111"); + } + }; private static String tokenurl = "https://iam.cn-east-3.myhuaweicloud.com/v3/auth/tokens"; private static String username; private static String domainname; @@ -30,37 +72,6 @@ public class IdCardUtils { */ private static Boolean enable; - @Value("${hw-ocr-enable:false}") - public void setEnable(Boolean enable) { - IdCardUtils.enable = enable; - } - - @Value("${hw-ocr-username}") - public void setUsername(String hwusername) { - username = hwusername; - } - - @Value("${hw-ocr-domainname}") - public void setDomainname(String hwdomainname) { - domainname = hwdomainname; - } - - @Value("${hw-ocr-password}") - public void setPassword(String hwpassword) { - password = hwpassword; - } - - @Value("${hw-ocr-projectid}") - public void setProjectid(String hwprojectid) { - projectid = hwprojectid; - } - - @Value("${hw-ocr-endpoint}") - public void setEndpoint(String hwendpoint) { - endpoint = hwendpoint; - } - - /** * 识别身份证信息 * @@ -184,7 +195,172 @@ public class IdCardUtils { return map; } - public static void main(String[] args) { - System.out.println(getBirthdayAgeSex("")); + /** + *

+ * 身份证格式强校验 + *

+ *

+ * 1、号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码, + * 八位数字出生日期码,三位数字顺序码和一位数字校验码。 + *

+ *

+ * 2、地址码(前六位数)表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。 + *

+ *

+ * 3、出生日期码(第七位至十四位)表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。 + *

+ *

+ * 4、顺序码(第十五位至十七位)表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号, 顺序码的奇数分配给男性,偶数分配给女性。 + *

+ *

+ * 5、校验码(第十八位数) + * (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和 + * Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 + * 2 (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0 + * X 9 8 7 6 5 4 3 2 + *

+ */ + public static final boolean strongVerifyIdNumber(String idNumber) { + if (StringUtils.isBlank(idNumber)) { + return false; + } + idNumber = idNumber.trim(); + + if (BLACK_SET.contains(idNumber)) { + return false; + } + if (!checkIdNumberRegex(idNumber)) { + return false; + } + if (!checkIdNumberArea(idNumber.substring(0, 6))) { + return false; + } + idNumber = convertFifteenToEighteen(idNumber); + if (!checkBirthday(idNumber.substring(6, 14))) { + return false; + } + if (!checkIdNumberVerifyCode(idNumber)) { + return false; + } + return true; } + + /** + * 身份证正则校验 + */ + private static boolean checkIdNumberRegex(String idNumber) { + return Pattern.matches("^([0-9]{17}[0-9Xx])|([0-9]{15})$", idNumber); + } + + /** + * 身份证地区码检查 + */ + private static boolean checkIdNumberArea(String idNumberArea) { + int areaCode = Integer.parseInt(idNumberArea); + if (areaCode == HONGKONG_AREACODE || areaCode == MACAO_AREACODE || areaCode == TAIWAN_AREACODE) { + return true; + } + if (areaCode <= MAX_MAINLAND_AREACODE && areaCode >= MIN_MAINLAND_AREACODE) { + return true; + } + return false; + } + + /** + * 将15位身份证转换为18位 + */ + private static String convertFifteenToEighteen(String idNumber) { + if (15 != idNumber.length()) { + return idNumber; + } + idNumber = idNumber.substring(0, 6) + "19" + idNumber.substring(6, 15); + idNumber = idNumber + getVerifyCode(idNumber); + return idNumber; + } + + /** + * 根据身份证前17位计算身份证校验码 + */ + private static String getVerifyCode(String idNumber) { + if (!Pattern.matches(regexNum, idNumber.substring(0, 17))) { + return null; + } + String[] ValCodeArr = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + String[] Wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"}; + + int sum = 0; + for (int i = 0; i < 17; i++) { + sum = sum + Integer.parseInt(String.valueOf(idNumber.charAt(i))) * Integer.parseInt(Wi[i]); + } + return ValCodeArr[sum % 11]; + } + + /** + * 身份证出生日期嘛检查 + */ + private static boolean checkBirthday(String idNumberBirthdayStr) { + Integer year = null; + try { + year = Integer.valueOf(idNumberBirthdayStr.substring(0, 4)); + } catch (Exception e) { + } + if (null == year) { + return false; + } + if (isLeapYear(year)) { + return Pattern.matches(regexBirthdayInLeapYear, idNumberBirthdayStr); + } else { + return Pattern.matches(regexBirthdayInCommonYear, idNumberBirthdayStr); + } + } + + /** + * 判断是否为闰年 + */ + private static boolean isLeapYear(int year) { + return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0); + } + + /** + * 身份证校验码检查 + */ + private static boolean checkIdNumberVerifyCode(String idNumber) { + return getVerifyCode(idNumber).equalsIgnoreCase(idNumber.substring(17)); + } + + public static void main(String[] args) { + System.out.println(strongVerifyIdNumber("121")); + System.out.println(strongVerifyIdNumber("420101198101019701")); + } + + @Value("${hw-ocr-enable:false}") + public void setEnable(Boolean enable) { + IdCardUtils.enable = enable; + } + + @Value("${hw-ocr-username}") + public void setUsername(String hwusername) { + username = hwusername; + } + + @Value("${hw-ocr-domainname}") + public void setDomainname(String hwdomainname) { + domainname = hwdomainname; + } + + @Value("${hw-ocr-password}") + public void setPassword(String hwpassword) { + password = hwpassword; + } + + @Value("${hw-ocr-projectid}") + public void setProjectid(String hwprojectid) { + projectid = hwprojectid; + } + + @Value("${hw-ocr-endpoint}") + public void setEndpoint(String hwendpoint) { + endpoint = hwendpoint; + } + }