Browse Source

就诊人三方身份校验

ct 6 days ago
parent
commit
04ad98f731

+ 4 - 0
fs-service/src/main/java/com/fs/his/config/StoreConfig.java

@@ -18,5 +18,9 @@ public class StoreConfig implements Serializable {
     private String refundPhoneNumber;
     private String refundAddress;
     private Integer storeCall;
+    private Integer isIdVerification; //1开启三方身份认证 0不开启
+    private String API_URL;
+    private String HASHCODE;
+    private String SECRET_KEY;
 
 }

+ 143 - 0
fs-service/src/main/java/com/fs/his/utils/IdCardUtil.java

@@ -0,0 +1,143 @@
+package com.fs.his.utils;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.config.StoreConfig;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 三方身份验证
+ */
+@Service
+public class IdCardUtil {
+    @Autowired
+    private static ISysConfigService configService;
+
+    /**
+     * 身份证信息隐藏 中间
+     * @param idCard   身份证信息
+     * @return  隐藏后信息
+     */
+    public static String hiddenIdCard(String idCard) {
+        if (StringUtils.isBlank(idCard)) {
+            return idCard;
+        }
+
+        return idCard.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1**********$2");
+    }
+
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+
+    private static String generateSign(String hashcode, String passname, String pid, String mobile,String secretKey) {
+        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
+        String raw = null;
+        if (StringUtils.isNotBlank(mobile)){
+            raw = hashcode + mobile + passname + secretKey + date;
+        } else {
+            raw = hashcode + passname + pid + secretKey + date;
+        }
+        return DigestUtil.md5Hex(raw.getBytes(StandardCharsets.UTF_8));
+    }
+
+    /**
+     * 检查身份证与姓名是否匹配
+     *
+     * @param passname 姓名
+     * @param pid      身份证号
+     * @return true 表示一致,false 表示不一致
+     */
+    public static boolean isMatchById(StoreConfig storeConfig,String passname, String pid) {
+        if (storeConfig == null) {
+            return false;
+        }
+        String API_URL = storeConfig.getAPI_URL() + "/HrmApi/Idverify";
+        String HASHCODE = storeConfig.getHASHCODE();
+        String SECRET_KEY = storeConfig.getSECRET_KEY();
+        try {
+            String sign = generateSign(HASHCODE, passname, pid,null, SECRET_KEY);
+            String bodyJson = String.format(
+                    "{\"passname\":\"%s\",\"pid\":\"%s\",\"hashcode\":\"%s\",\"sign\":\"%s\"}",
+                    passname, pid, HASHCODE, sign
+            );
+
+            HttpResponse response = HttpRequest.post(API_URL)
+                    .body(bodyJson)
+                    .header("Content-Type", "application/json;charset=UTF-8")
+                    .timeout(5000)
+                    .execute();
+
+            if (response.getStatus() != 200) {
+                throw new RuntimeException("HTTP请求失败,状态码:" + response.getStatus());
+            }
+
+            JsonNode root = OBJECT_MAPPER.readTree(response.body());
+            JsonNode errorRes = root.get("errorRes");
+            String errTransCode = root.get("err_TransCode").asText();
+            System.out.println(DateUtils.getNowDate());
+            System.out.println("流水号"+errTransCode);
+            if (errorRes != null && "200".equals(errorRes.get("err_code").asText())) {
+                return true; // 一致
+            }
+            return false; // 不一致或接口异常
+        } catch (Exception e) {
+            throw new RuntimeException("匹配请求异常", e);
+        }
+    }
+
+    /**
+     * 检查身份证与姓名是否匹配
+     *
+     * @param passname 姓名
+     * @param mobile      身份证号
+     * @return true 表示一致,false 表示不一致
+     */
+    public static boolean isMatchByMobile(StoreConfig storeConfig,String passname, String mobile) {
+        if (storeConfig == null) {
+            return false;
+        }
+        String API_URL = storeConfig.getAPI_URL() + "/HrmApi/mobile2everify";
+        String HASHCODE = storeConfig.getHASHCODE();
+        String SECRET_KEY = storeConfig.getSECRET_KEY();
+        try {
+            String sign = generateSign(HASHCODE, passname, null,mobile, SECRET_KEY);
+            String bodyJson = String.format(
+                    "{\"passname\":\"%s\",\"mobile\":\"%s\",\"hashcode\":\"%s\",\"sign\":\"%s\"}",
+                    passname, mobile, HASHCODE, sign
+            );
+
+            HttpResponse response = HttpRequest.post(API_URL)
+                    .body(bodyJson)
+                    .header("Content-Type", "application/json;charset=UTF-8")
+                    .timeout(5000)
+                    .execute();
+
+            if (response.getStatus() != 200) {
+                throw new RuntimeException("HTTP请求失败,状态码:" + response.getStatus());
+            }
+
+            JsonNode root = OBJECT_MAPPER.readTree(response.body());
+            JsonNode errorRes = root.get("errorRes");
+            String errTransCode = root.get("err_TransCode").asText();
+            System.out.println(DateUtils.getNowDate());
+            System.out.println("流水号"+errTransCode);
+            if (errorRes != null && "200".equals(errorRes.get("err_code").asText())) {
+                return true; // 一致
+            }
+            return false; // 不一致或接口异常
+        } catch (Exception e) {
+            throw new RuntimeException("匹配请求异常", e);
+        }
+    }
+}

+ 78 - 9
fs-user-app/src/main/java/com/fs/app/controller/PatientController.java

@@ -2,16 +2,21 @@ package com.fs.app.controller;
 
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.app.annotation.Login;
 import com.fs.app.param.FsPatientAddEditParam;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.FsPatient;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.service.IFsPatientService;
 import com.fs.his.service.IFsUserIntegralLogsService;
+import com.fs.his.utils.IdCardUtil;
+import com.fs.system.service.ISysConfigService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -38,6 +43,8 @@ public class PatientController extends  AppBaseController {
     private IFsPatientService patientService;
     @Autowired
     private IFsUserIntegralLogsService userIntegralLogsService;
+    @Autowired
+    private ISysConfigService configService;
 
     @Login
     @ApiOperation("获取病人列表")
@@ -77,15 +84,32 @@ public class PatientController extends  AppBaseController {
     @ApiOperation("添加病人")
     @PostMapping("/addPatient")
     public R addPatient(@Valid @RequestBody FsPatientAddEditParam param, HttpServletRequest request){
+        String json = configService.selectConfigByKey("his.store");
+        StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+        Integer isIdVerification = storeConfig.getIsIdVerification();
 
         String idCardNumber = param.getIdCard(); // 替换为要验证的身份证号码
-        if (idCardNumber == null || idCardNumber.length() != 18) {
+        String mobile = param.getMobile();
+        if (idCardNumber == null || idCardNumber.trim().isEmpty()) {
             return R.error("身份证号码不合法");
         }
-        String regex = "\\d{17}[0-9Xx]";
-        if (!Pattern.matches(regex, idCardNumber)) {
-            return   R.error("身份证号码不合法");
+        if (idCardNumber.length() != 18) {
+            //大陆身份证是18位
+            if (isIdVerification != 1) {
+                return R.error("身份证号码不合法");
+            } else {
+                //非大陆身份校验需要手机号 手机号只支持大陆的办理的手机号
+                if (StringUtils.isBlank(mobile)){
+                    R.error("手机号不能为空");
+                }
+            }
+        } else {
+            String regex = "\\d{17}[0-9Xx]";
+            if (!Pattern.matches(regex, idCardNumber)) {
+                return   R.error("身份证号码不合法");
+            }
         }
+
         if (param.getPatientName().length()<2||param.getPatientName().length()>30||!param.getPatientName().matches("^[\u4e00-\u9fa5]+$")) {
             return   R.error("就诊人名称不合法");
         }
@@ -127,6 +151,19 @@ public class PatientController extends  AppBaseController {
             return   R.error("身份证校验错误");
         }
 
+        //三方校验
+        if (isIdVerification == 1){
+            boolean match = true;
+            if (idCardNumber.length() != 18) {
+                match = IdCardUtil.isMatchByMobile(storeConfig,param.getPatientName(), mobile);
+            } else {
+                match = IdCardUtil.isMatchById(storeConfig,param.getPatientName(), param.getIdCard());
+            }
+            if (!match){
+                return R.error("身份证校验错误");
+            }
+        }
+
         FsPatient patient=new FsPatient();
         BeanUtil.copyProperties(param, patient);
         patient.setUserId(Long.parseLong(getUserId()));
@@ -148,14 +185,32 @@ public class PatientController extends  AppBaseController {
     @ApiOperation("编辑病人")
     @PostMapping("/editPatient")
     public R editPatient(@Valid @RequestBody FsPatientAddEditParam param, HttpServletRequest request){
+        String json = configService.selectConfigByKey("his.store");
+        StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+        Integer isIdVerification = storeConfig.getIsIdVerification();
+        String mobile = param.getMobile();
+
         String idCardNumber = param.getIdCard(); // 替换为要验证的身份证号码
-        if (idCardNumber == null || idCardNumber.length() != 18) {
-            throw new CustomException("身份证号码不合法");
+        if (idCardNumber == null || idCardNumber.trim().isEmpty()) {
+            return R.error("身份证号码不合法");
         }
-        String regex = "\\d{17}[0-9Xx]";
-        if (!Pattern.matches(regex, idCardNumber)) {
-            throw new CustomException("身份证号码不合法");
+        if (idCardNumber.length() != 18) {
+            //大陆身份证是18位
+            if (isIdVerification != 1) {
+                return R.error("身份证号码不合法");
+            } else {
+                //非大陆身份校验需要手机号 手机号只支持大陆的办理的手机号
+                if (StringUtils.isBlank(mobile)){
+                    R.error("手机号不能为空");
+                }
+            }
+        } else {
+            String regex = "\\d{17}[0-9Xx]";
+            if (!Pattern.matches(regex, idCardNumber)) {
+                return   R.error("身份证号码不合法");
+            }
         }
+
         if (param.getPatientName().length()<2||param.getPatientName().length()>30||!param.getPatientName().matches("^[\u4e00-\u9fa5]+$")) {
             return   R.error("就诊人名称不合法");
         }
@@ -191,6 +246,20 @@ public class PatientController extends  AppBaseController {
 //        if (age2 > 200) {
 //            throw new CustomException("年龄超过200岁");
 //        }
+
+        //三方校验
+        if (isIdVerification == 1){
+            boolean match = true;
+            if (idCardNumber.length() != 18) {
+                match = IdCardUtil.isMatchByMobile(storeConfig,param.getPatientName(), mobile);
+            } else {
+                match = IdCardUtil.isMatchById(storeConfig,param.getPatientName(), param.getIdCard());
+            }
+            if (!match){
+                return R.error("身份证校验错误");
+            }
+        }
+
         FsPatient patient=new FsPatient();
         BeanUtil.copyProperties(param, patient);
         patientService.updateFsPatient(patient);