|
@@ -4,20 +4,31 @@ import com.alibaba.fastjson2.JSON;
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
import com.hrsk.cloud.eg.clinet.dto.data.plan.command.EgLoanApiConfigInfoCmd;
|
|
import com.hrsk.cloud.eg.clinet.dto.data.plan.command.EgLoanApiConfigInfoCmd;
|
|
import com.hrsk.cloud.eg.clinet.dto.data.plan.command.PlanCmd;
|
|
import com.hrsk.cloud.eg.clinet.dto.data.plan.command.PlanCmd;
|
|
|
|
+import com.hrsk.cloud.eg.clinet.dto.data.user.command.UserAssetHouseInfoCmd;
|
|
|
|
+import com.hrsk.cloud.eg.clinet.dto.data.user.command.UserAssetInsuranceInfoCmd;
|
|
import com.hrsk.cloud.eg.clinet.dto.data.user.command.UserBaseInfoCmd;
|
|
import com.hrsk.cloud.eg.clinet.dto.data.user.command.UserBaseInfoCmd;
|
|
|
|
+import com.hrsk.cloud.eg.clinet.dto.data.user.command.XdApplyCmd;
|
|
import com.hrsk.cloud.eg.clinet.vo.DataVo;
|
|
import com.hrsk.cloud.eg.clinet.vo.DataVo;
|
|
|
|
+import com.hrsk.cloud.eg.clinet.vo.OrderResponseVo;
|
|
import com.hrsk.cloud.eg.domain.common.constant.ServerCodeEnums;
|
|
import com.hrsk.cloud.eg.domain.common.constant.ServerCodeEnums;
|
|
|
|
+import com.hrsk.cloud.eg.domain.utils.Md5Util;
|
|
import com.hrsk.cloud.eg.infrastructure.config.client.HessianUtils;
|
|
import com.hrsk.cloud.eg.infrastructure.config.client.HessianUtils;
|
|
import com.hrsk.cloud.eg.infrastructure.config.client.RetryRestTemplate;
|
|
import com.hrsk.cloud.eg.infrastructure.config.client.RetryRestTemplate;
|
|
-import com.hrsk.cloud.eg.infrastructure.repository.database.entity.EgLoanApiConfigInfoDo;
|
|
|
|
-import com.hrsk.cloud.eg.infrastructure.service.EgApiService;
|
|
|
|
import com.hrsk.cloud.eg.infrastructure.loanMannager.threedocking.LoanDockingApi;
|
|
import com.hrsk.cloud.eg.infrastructure.loanMannager.threedocking.LoanDockingApi;
|
|
-import com.hrsk.cloud.eg.infrastructure.utils.Md5Util;
|
|
|
|
|
|
+import com.hrsk.cloud.eg.infrastructure.utils.UserUtils;
|
|
import lombok.Data;
|
|
import lombok.Data;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.commons.codec.Charsets;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
|
|
+import javax.crypto.Cipher;
|
|
|
|
+import javax.crypto.KeyGenerator;
|
|
|
|
+import javax.crypto.SecretKey;
|
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
|
+import java.security.MessageDigest;
|
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
|
+import java.security.SecureRandom;
|
|
import java.time.Instant;
|
|
import java.time.Instant;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
|
@@ -32,15 +43,70 @@ public class AnHuiHengDaoCreditService implements LoanDockingApi {
|
|
@Resource
|
|
@Resource
|
|
private RetryRestTemplate httpRestTemplate;
|
|
private RetryRestTemplate httpRestTemplate;
|
|
|
|
|
|
- @Resource
|
|
|
|
- private EgApiService egApiService;
|
|
|
|
-
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public ServerCodeEnums getType() {
|
|
public ServerCodeEnums getType() {
|
|
return ServerCodeEnums.AnHuiHengDao;
|
|
return ServerCodeEnums.AnHuiHengDao;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public OrderResponseVo qualityApply(UserBaseInfoCmd user, PlanCmd planDto, EgLoanApiConfigInfoCmd configInfoCmd) {
|
|
|
|
+ try {
|
|
|
|
+ log.info("credit AnHuiHengDaoCreditService createApplyAndOrder begin...userId:{}",user.getUserId());
|
|
|
|
+ String configJson = HessianUtils.deserialize(configInfoCmd.getRequestConfig()).toString();
|
|
|
|
+ JSONObject config = JSONObject.parseObject(configJson);
|
|
|
|
+ log.info("安徽恒道代对接参数:{}", JSON.toJSONString(config));
|
|
|
|
+ ApplyInfo applyInfoApi = new ApplyInfo();
|
|
|
|
+ String millisecondsSinceEpoch = String.valueOf(Instant.now().toEpochMilli());
|
|
|
|
+ applyInfoApi.setTimeStamp(millisecondsSinceEpoch);//当前时间搓
|
|
|
|
+ applyInfoApi.setOrderNo(config.getString("channel")+millisecondsSinceEpoch);//订单号
|
|
|
|
+ CheckData prams=new CheckData();
|
|
|
|
+ prams.setClientname(UserUtils.getUserName(user.getRealName(),user.getPoliceSex()));
|
|
|
|
+ prams.setPhone(user.getUserMobile());
|
|
|
|
+ prams.setChannelId(config.getString("channelId"));
|
|
|
|
+ ApplyInfoData applyInfoData=new ApplyInfoData();
|
|
|
|
+ getLoanTerm(user.getXdApplyCmd(), applyInfoData);//贷款期限
|
|
|
|
+ applyInfoData.setCar(user.getCarInfo() == null || user.getCarInfo().getCarType() == null || user.getCarInfo().getCarType() == 1 ? "无车产" : "有车产");//车
|
|
|
|
+ UserAssetHouseInfoCmd houseInfo = user.getHouseInfo();
|
|
|
|
+ applyInfoData.setHouse(houseInfo == null || houseInfo.getHouseType() == null || houseInfo.getHouseType() == 2 ? "无房产" : "有房产");//房产
|
|
|
|
+
|
|
|
|
+ getsocialSecurity(user,applyInfoData);//社保
|
|
|
|
+ getreservedFunds(user,applyInfoData);//公积金
|
|
|
|
+ UserAssetInsuranceInfoCmd xdAssetInsuranceInfo = user.getInsuranceInfo();
|
|
|
|
+ applyInfoData.setInsurance(xdAssetInsuranceInfo==null||xdAssetInsuranceInfo.getInsuranceType()==1?"无":"有");//保单
|
|
|
|
+ applyInfoData.setCreditCard(user.getCreditLimit() == null || user.getCreditLimit() == 5?"无信用卡":"有信用卡");
|
|
|
|
+ getzhima(user,applyInfoData);//芝麻分
|
|
|
|
+ prams.setRemarks("贷款金额:"+user.getXdApplyCmd().getBorrowMoney()*10000+",贷款期限:"+applyInfoData.getLoanLimit()+",车产:"+applyInfoData.getCar()
|
|
|
|
+ +",房产:"+applyInfoData.getHouse()+",社保:"+applyInfoData.getSocialSecurity()+",公积金:"+applyInfoData.getReservedFunds()+",寿险保单:"+applyInfoData.getInsurance()
|
|
|
|
+ +",信用卡:"+applyInfoData.getCreditCard() +",芝麻分:"+applyInfoData.getZhima());
|
|
|
|
+ String data = encrypt(JSONObject.toJSONString(prams), config.getString("key"));
|
|
|
|
+ applyInfoApi.setData(data);
|
|
|
|
+ JSONObject jsons = JSONObject.parseObject(JSON.toJSONString(applyInfoApi));
|
|
|
|
+ jsons.remove("sign");
|
|
|
|
+ String sign = getSign(jsons,config.getString("key"));
|
|
|
|
+ applyInfoApi.setSign(Md5Util.encoderByMd5(sign));
|
|
|
|
+ log.info("安徽恒道代请求参数:{},用户信息:{}",JSON.toJSONString(applyInfoApi),JSON.toJSONString(prams));
|
|
|
|
+ String url = config.getString("applyUrl");
|
|
|
|
+ JSONObject response = null;
|
|
|
|
+ try{
|
|
|
|
+ response =httpRestTemplate.restTemplate().postForObject(url, applyInfoApi , JSONObject.class);
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ log.error("安徽恒道申请异常,异常信息:{}", e.getMessage(), e);
|
|
|
|
+ }
|
|
|
|
+ log.info("credit createApplyAndOrder AnHuiHengDaoCreditService response userId:{}, result:{}",user.getUserId(), response);
|
|
|
|
+ if (response == null) {
|
|
|
|
+ return OrderResponseVo.fail("请求返回结果为空",ServerCodeEnums.AnHuiHengDao.getMsg());
|
|
|
|
+ }
|
|
|
|
+ if (response.getString("code").equals("000")) {
|
|
|
|
+ return OrderResponseVo.ok(ServerCodeEnums.AnHuiHengDao.getMsg());
|
|
|
|
+ }
|
|
|
|
+ return OrderResponseVo.fail(response.getString("msg"),ServerCodeEnums.AnHuiHengDao.getMsg());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("安徽恒道代申请失败", e);
|
|
|
|
+ return OrderResponseVo.fail("安徽恒道代申请失败",ServerCodeEnums.AnHuiHengDao.getMsg());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
@Data
|
|
@Data
|
|
private static class CheckInfo{
|
|
private static class CheckInfo{
|
|
private String timeStamp;//时间戳:1627538679006
|
|
private String timeStamp;//时间戳:1627538679006
|
|
@@ -162,5 +228,234 @@ public class AnHuiHengDaoCreditService implements LoanDockingApi {
|
|
ret = ret.substring(0, ret.length() - 1);
|
|
ret = ret.substring(0, ret.length() - 1);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
+ private void getzhima(UserBaseInfoCmd userBasicInfo, ApplyInfoData applyInfoData) {
|
|
|
|
+ if (userBasicInfo.getSesame()==null||userBasicInfo.getSesame()==0){
|
|
|
|
+ applyInfoData.setZhima("550分以下");
|
|
|
|
+ }else if (userBasicInfo.getSesame()==2){
|
|
|
|
+ applyInfoData.setZhima("600分以下");
|
|
|
|
+ }else if (userBasicInfo.getSesame()==3){
|
|
|
|
+ applyInfoData.setZhima("600-650分以下");
|
|
|
|
+ }else if (userBasicInfo.getSesame()==4){
|
|
|
|
+ applyInfoData.setZhima("650-700分以下");
|
|
|
|
+ }else {
|
|
|
|
+ applyInfoData.setZhima("700分以上");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void getreservedFunds(UserBaseInfoCmd userBasicInfo, ApplyInfoData applyInfoData) {
|
|
|
|
+ if (userBasicInfo.getAccumulation()==null||userBasicInfo.getAccumulation()==0){
|
|
|
|
+ applyInfoData.setReservedFunds("无公积金");
|
|
|
|
+ }else if (userBasicInfo.getAccumulation()==1){
|
|
|
|
+ applyInfoData.setReservedFunds("缴纳未满6个月");
|
|
|
|
+ }else {
|
|
|
|
+ applyInfoData.setReservedFunds("缴纳超过6个月以上");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void getsocialSecurity(UserBaseInfoCmd userBasicInfo, ApplyInfoData applyInfoData) {
|
|
|
|
+ if (userBasicInfo.getSocialSecurity()==null||userBasicInfo.getSocialSecurity()==0){
|
|
|
|
+ applyInfoData.setSocialSecurity("无社保");
|
|
|
|
+ }else if (userBasicInfo.getSocialSecurity()==1){
|
|
|
|
+ applyInfoData.setSocialSecurity("缴纳未满6个月");
|
|
|
|
+ }else {
|
|
|
|
+ applyInfoData.setSocialSecurity("缴纳超过6个月以上");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void getLoanTerm(XdApplyCmd xdApplyParam, ApplyInfoData applyInfoData) {
|
|
|
|
+ if (xdApplyParam==null||xdApplyParam.getBorrowLimit() == null||xdApplyParam.getBorrowLimit() == 2) {
|
|
|
|
+ applyInfoData.setLoanLimit("3个月");
|
|
|
|
+ }else if (xdApplyParam.getBorrowLimit() == 3){
|
|
|
|
+ applyInfoData.setLoanLimit("6个月");
|
|
|
|
+ }else if (xdApplyParam.getBorrowLimit() == 4){
|
|
|
|
+ applyInfoData.setLoanLimit("9个月");
|
|
|
|
+ }else if (xdApplyParam.getBorrowLimit() == 5){
|
|
|
|
+ applyInfoData.setLoanLimit("12个月");
|
|
|
|
+ }else if (xdApplyParam.getBorrowLimit() == 6){
|
|
|
|
+ applyInfoData.setLoanLimit("24个月");
|
|
|
|
+ }else {
|
|
|
|
+ applyInfoData.setLoanLimit("32个月");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public static class AESUtil {
|
|
|
|
+
|
|
|
|
+ private static final String KEY_ALGORITHM = "AES";
|
|
|
|
+
|
|
|
|
+ //默认的加密算法
|
|
|
|
+ private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * AES 加密操作
|
|
|
|
+ *
|
|
|
|
+ * @param content 待加密内容
|
|
|
|
+ * @param key 加密密钥
|
|
|
|
+ * @return 返回Base64转码后的加密数据
|
|
|
|
+ */
|
|
|
|
+ public static String encrypt(String content, String key) throws Exception {
|
|
|
|
+ Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
|
|
|
+
|
|
|
|
+ byte[] byteContent = content.getBytes(Charsets.UTF_8);
|
|
|
|
+ // 初始化为加密模式的密码器
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
|
|
|
|
+ // 加密
|
|
|
|
+ byte[] result = cipher.doFinal(byteContent);
|
|
|
|
+ //通过Base64转码返回
|
|
|
|
+ return Base64.getEncoder().encodeToString(result);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * AES 解密操作
|
|
|
|
+ *
|
|
|
|
+ * @param content 待解密数据
|
|
|
|
+ * @param key 秘钥
|
|
|
|
+ * @return 返回数据明文
|
|
|
|
+ */
|
|
|
|
+ public static String decrypt(String content, String key) throws Exception {
|
|
|
|
+ //实例化
|
|
|
|
+ Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
|
|
|
+ //使用密钥初始化,设置为解密模式
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
|
|
|
|
+
|
|
|
|
+ //执行操作
|
|
|
|
+ byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
|
|
|
|
+
|
|
|
|
+ return new String(result, Charsets.UTF_8);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 生成加密秘钥
|
|
|
|
+ */
|
|
|
|
+ private static SecretKeySpec getSecretKey(final String key) throws NoSuchAlgorithmException {
|
|
|
|
+ //返回生成指定算法密钥生成器的 KeyGenerator 对象
|
|
|
|
+ KeyGenerator kg = null;
|
|
|
|
+ kg = KeyGenerator.getInstance(KEY_ALGORITHM);
|
|
|
|
+ //AES 要求密钥长度为 128
|
|
|
|
+ SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
|
|
|
+ secureRandom.setSeed(key.getBytes(Charsets.UTF_8));
|
|
|
|
+ kg.init(128, secureRandom);
|
|
|
|
+ //生成一个密钥
|
|
|
|
+ SecretKey secretKey = kg.generateKey();
|
|
|
|
+ // 转换为AES专用密钥
|
|
|
|
+ return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String MD5(String input) {
|
|
|
|
+ try {
|
|
|
|
+ // 获得MD5摘要算法的 MessageDigest 对象
|
|
|
|
+ MessageDigest mdInst = MessageDigest.getInstance("MD5");
|
|
|
|
+ // 使用指定的字节更新摘要
|
|
|
|
+ mdInst.update(input.getBytes());
|
|
|
|
+ // 获得密文
|
|
|
|
+ byte[] md = mdInst.digest();
|
|
|
|
+ // 把密文转换成十六进制的字符串形式
|
|
|
|
+ StringBuffer hexString = new StringBuffer();
|
|
|
|
+ // 字节数组转换为 十六进制 数
|
|
|
|
+ for (int i = 0; i < md.length; i++) {
|
|
|
|
+ String shaHex = Integer.toHexString(md[i] & 0xFF);
|
|
|
|
+ if (shaHex.length() < 2) {
|
|
|
|
+ hexString.append(0);
|
|
|
|
+ }
|
|
|
|
+ hexString.append(shaHex);
|
|
|
|
+ }
|
|
|
|
+ return hexString.toString();
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return "";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private static final String KEY_ALGORITHM = "AES";
|
|
|
|
+
|
|
|
|
+ //默认的加密算法
|
|
|
|
+ private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * AES 加密操作
|
|
|
|
+ *
|
|
|
|
+ * @param content 待加密内容
|
|
|
|
+ * @param key 加密密钥
|
|
|
|
+ * @return 返回Base64转码后的加密数据
|
|
|
|
+ */
|
|
|
|
+ public static String encrypt(String content, String key) throws Exception {
|
|
|
|
+ Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
|
|
|
+
|
|
|
|
+ byte[] byteContent = content.getBytes(Charsets.UTF_8);
|
|
|
|
+ // 初始化为加密模式的密码器
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
|
|
|
|
+ // 加密
|
|
|
|
+ byte[] result = cipher.doFinal(byteContent);
|
|
|
|
+ //通过Base64转码返回
|
|
|
|
+ return Base64.getEncoder().encodeToString(result);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * AES 解密操作
|
|
|
|
+ *
|
|
|
|
+ * @param content 待解密数据
|
|
|
|
+ * @param key 秘钥
|
|
|
|
+ * @return 返回数据明文
|
|
|
|
+ */
|
|
|
|
+ public static String decrypt(String content, String key) throws Exception {
|
|
|
|
+ //实例化
|
|
|
|
+ Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
|
|
|
+ //使用密钥初始化,设置为解密模式
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
|
|
|
|
|
|
|
|
+ //执行操作
|
|
|
|
+ byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
|
|
|
|
+
|
|
|
|
+ return new String(result, Charsets.UTF_8);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 生成加密秘钥
|
|
|
|
+ */
|
|
|
|
+ private static SecretKeySpec getSecretKey(final String key) throws NoSuchAlgorithmException {
|
|
|
|
+ //返回生成指定算法密钥生成器的 KeyGenerator 对象
|
|
|
|
+ KeyGenerator kg = null;
|
|
|
|
+ kg = KeyGenerator.getInstance(KEY_ALGORITHM);
|
|
|
|
+ //AES 要求密钥长度为 128
|
|
|
|
+ SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
|
|
|
+ secureRandom.setSeed(key.getBytes(Charsets.UTF_8));
|
|
|
|
+ kg.init(128, secureRandom);
|
|
|
|
+ //生成一个密钥
|
|
|
|
+ SecretKey secretKey = kg.generateKey();
|
|
|
|
+ // 转换为AES专用密钥
|
|
|
|
+ return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String MD5(String input) {
|
|
|
|
+ try {
|
|
|
|
+ // 获得MD5摘要算法的 MessageDigest 对象
|
|
|
|
+ MessageDigest mdInst = MessageDigest.getInstance("MD5");
|
|
|
|
+ // 使用指定的字节更新摘要
|
|
|
|
+ mdInst.update(input.getBytes());
|
|
|
|
+ // 获得密文
|
|
|
|
+ byte[] md = mdInst.digest();
|
|
|
|
+ // 把密文转换成十六进制的字符串形式
|
|
|
|
+ StringBuffer hexString = new StringBuffer();
|
|
|
|
+ // 字节数组转换为 十六进制 数
|
|
|
|
+ for (int i = 0; i < md.length; i++) {
|
|
|
|
+ String shaHex = Integer.toHexString(md[i] & 0xFF);
|
|
|
|
+ if (shaHex.length() < 2) {
|
|
|
|
+ hexString.append(0);
|
|
|
|
+ }
|
|
|
|
+ hexString.append(shaHex);
|
|
|
|
+ }
|
|
|
|
+ return hexString.toString();
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return "";
|
|
|
|
+ }
|
|
}
|
|
}
|