Commit 015d4257 authored by kang.nie@inzymeits.com's avatar kang.nie@inzymeits.com
Browse files

初始化代码

parent bd38ff8b
Pipeline #3108 failed with stages
in 0 seconds
package com.cusc.nirvana.user.rnr.fp.common;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.*;
import java.util.Date;
/**
* <p>
* rnr的PO基类
* </p>
*
* @author yuyi
* @since 2021-10-21
*/
@Data
public class BaseRnrPO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 逻辑删除(0-未删除,1-已删除)
*/
@TableField("is_delete")
private Integer isDelete;
/**
* 创建时间
*/
@TableField(value = "create_time", insertStrategy = FieldStrategy.NOT_NULL, updateStrategy = FieldStrategy.NEVER)
private Date createTime;
/**
* 更新时间
*/
@TableField(value = "update_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private Date updateTime;
/**
* 创建人
*/
@TableField(value = "creator", updateStrategy = FieldStrategy.NEVER)
private String creator;
}
package com.cusc.nirvana.user.rnr.fp.common.cloud;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@RefreshScope
@Component
public class CloudConstant {
public static String ORGID = "orgId";
private String HOST;
private String VERSION;
private String APPID;
private String APPSCRET;
private String ENCRYPT_KEY;
private String DECRYPT_KEY;
public String getAPPID() {
return APPID;
}
@Value("${rnr.cloud.appid}")
public void setAPPID(String APPID) {
this.APPID = APPID;
}
public String getAPPSCRET() {
return APPSCRET;
}
@Value("${rnr.cloud.appsecret}")
public void setAPPSCRET(String APPSCRET) {
this.APPSCRET = APPSCRET;
}
public String getHOST() {
return HOST;
}
@Value("${rnr.cloud.host}")
public void setHOST(String HOST) {
this.HOST = HOST;
}
public String getVERSION() {
return VERSION;
}
@Value("${rnr.cloud.version:1.0.0}")
public void setVERSION(String VERSION) {
this.VERSION = VERSION;
}
@Value("${rnr.cloud.encrypt}")
public void setENCRYPT_KEY(String ENCRYPT_KEY) {
this.ENCRYPT_KEY = ENCRYPT_KEY;
}
@Value("${rnr.cloud.decrypt}")
public void setDECRYPT_KEY(String DECRYPT_KEY) {
this.DECRYPT_KEY = DECRYPT_KEY;
}
public String getENCRYPT_KEY() {
return ENCRYPT_KEY;
}
public String getDECRYPT_KEY() {
return DECRYPT_KEY;
}
}
package com.cusc.nirvana.user.rnr.fp.common.cloud;
public class CloudMethod {
//5.1标签查询
public static String QUERY_TAG_LIST = "/user-rnr-openapi/vehicleCard/manage/queryTagList";
//5.2批量卡导入
public static String SIM_IMPORT = "/user-rnr-openapi/vehicleCard/manage/simImport";
//5.3车卡绑定接口-批量
public static String SIM_BIND = "/user-rnr-openapi/vehicleCard/manage/bind";
//5.4车卡查询接口
public static String GET_ICCIDS_BY_VIN = "/user-rnr-openapi/vehicleCard/manage/getIccidsByVin";
//5.5判断车卡是否绑定接口
public static String VERIFY_VIN_CARD = "/user-rnr-openapi/vehicleCard/manage/verifyVinCard";
//6.文件上传
public static String FILE_UPLOAD = "/user-rnr-openapi/rnAuth/attachment/upload";
//7.1自然人实名-新车接口
public static String NEW_CAR = "/user-rnr-openapi/rnAuth/personal/newCar";
//7.2自然人实名-二手车接口
public static String USED_CAR = "/user-rnr-openapi/rnAuth/personal/usedCar";
//7.3自然人实名-一手车解绑
public static String UNBIND_FIRSTHAND_CAR = "/user-rnr-openapi/rnAuth/unbind/firstHandCar";
//7.4自然人实名-二手车解绑
public static String UNBIND_SECONDHAND_CAR = "/user-rnr-openapi/rnAuth/unbind/secondHandCar";
//8.1企业实名-新车
public static String COMPANY_NEWCAR = "/user-rnr-openapi/rnAuth/enterprise/newCar";
//8.2车企实名-解绑
public static String COMPANY_UNBIND = "/user-rnr-openapi/rnAuth/vehicleEnterprise/unbind";
//8.3企业责任人变更
public static String COMPANY_CHANGEOWNER = "/user-rnr-openapi/rnAuth/enterprise/changeOwner";
//9.1设备更换
public static String TBOX_CHANGE = "/user-rnr-openapi/rnAuth/tBox/change";
//11.1实名信息查询接口
public static String REALMSG_SEARCH = "/user-rnr-openapi/rnAuth/search/getRnAuthInfoByVin";
// 11.2实名状态查询接口
// public static String A = "";
// 11.3实名状态查询接口-批量
// public static String A = "";
//12.1车联网一证十卡接口
public static String IOVCARD_NUM = "/user-rnr-openapi/base/iovCardNum";
//12.2物联网一证十卡接口
public static String IOTCARD_NUM = "/user-rnr-openapi/base/iotCardNum";
//12.3活体认证
public static String LIVENESS = "/user-rnr-openapi/base/liveness";
//12.4活体验证码
// public static String LIVENESS_CODE = "/user-rnr-openapi/base/livenessCode";
//12.5身份证OCR
public static String OCR_NP = "/user-rnr-openapi/base/ocrNp";
//12.6人像比对
public static String ID_COMPARE = "/user-rnr-openapi/base/idCompare";
//12.7人脸比对
public static String FACE_COMPARE = "/user-rnr-openapi/base/faceCompare";
//12.8身份信息核查
public static String CERT_CHECK = "/user-rnr-openapi/base/certCheck";
//12.9后端活体检查
public static String FMP = "/user-rnr-openapi/base/fmp";
//13.1个人实名信息同步接口
public static String SYNC_PERSONAL = "/user-rnr-openapi/rnAuth/sync/personal";
//13.2企业实名历史数据同步
public static String ASYNC_ENTERPRISE = "/user-rnr-openapi/rnAuth/sync/enterprise";
//013 本地系统将实名结果回传给智网
public static String NOTIFY_RESULT = "/user-rnr-openapi/rnAuth/notify/result";
//013 h5接口
public static String H5LIVELOGIN_URL = "/user-rnr-openapi/base/getH5LiveLoginUrl";
//006 活体认证动(获取数字)
public static String LIVENESS_CODE_TIP = "/user-rnr-openapi/rnAuth/liveness/getCode";
//020 活体认证动作顺序(左右摇头)
public static String LIVENESS_CODE_ACTION = "/user-rnr-openapi/base/livenessCode";
//----------------------------------------openapi未提供接口
//一车多卡绑定接口
public static String ONE_CAR_MORE_CARDS = "/user-rnr-openapi/";
//根据订单编号获取H5活体认证结果
public static String GET_LIVENESSRESULT ="/user-rnr-openapi/base/getLivenessResult";
//文件下载
public static String ATTACHMENT_DOWNLOAD ="/user-rnr-openapi/rnAuth/attachment/download";
}
package com.cusc.nirvana.user.rnr.fp.common.cloud;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.cusc.nirvana.common.encrypt.sign.HMAC;
import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.rnr.fp.common.FpIgnoreBase64ImgJsonNoEncryptFilter;
import com.cusc.nirvana.user.rnr.fp.common.FpIgnoreBase64ImgJsonSerializeFilter;
import com.cusc.nirvana.user.rnr.fp.dto.OcrNpRespDTO;
import com.cusc.nirvana.user.util.CuscStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@Service
@Slf4j
public class CloudService<T> {
@Resource
private RestTemplate noBalanceRestTemplateRnrFp;
@Autowired
private CloudConstant cloudConstant;
public <T> Response<T> postForResponse(String url, Object rq, Class<T> rsClazz) {
if(url.equals(CloudMethod.LIVENESS)){
return postForResponseNoEncrypt(url,rq,rsClazz);
}
String rqUrl = cloudConstant.getHOST() + url;
try {
log.info("openapi key : {}", cloudConstant.getENCRYPT_KEY());
String encryptrq = Sm4DemoUtils.encryptEcbPaddingHexString(cloudConstant.getENCRYPT_KEY(), JSON.toJSONString(rq));
HttpHeaders headers = headers();
HttpEntity httpEntity = new HttpEntity(encryptrq, headers);
log.info("send 2 cloud begin , url : {}, rq : {}, header : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonSerializeFilter()),
headers.toString());
long startTime = System.currentTimeMillis();
ResponseEntity<String> entity =
noBalanceRestTemplateRnrFp.exchange(rqUrl, HttpMethod.POST, httpEntity, String.class);
long endTime = System.currentTimeMillis();
if (entity != null && entity.getStatusCodeValue() == 200) {
log.info("send 2 cloud success code 200, url : {}, rq : {}, body : {}, times : {}",
rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()), entity.getBody(), endTime - startTime);
Response<String> result = JSON.parseObject(entity.getBody(), new TypeReference<Response<String>>(String.class) {
}.getType());
T t = null ;
if (null != result) {
String data;
if (result.getCode() == 200) {
data = Sm4DemoUtils.decryptEcbPaddingString(cloudConstant.getDECRYPT_KEY(), result.getData());
} else {
data = result.getData();
}
t = JSON.parseObject(data, rsClazz);
}
Response<T> finalresult = new Response<T>(result.getMsg(), result.getCode(), t, result.getSuccess(), result.getException());
finalresult.setAttachment(result.getAttachment());
return finalresult;
} else {
log.info("send 2 cloud fail, url : {}, rq : {}, times : {}, entity : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()),
endTime - startTime, null == entity ? null : JSON.toJSONString(entity, new FpIgnoreBase64ImgJsonSerializeFilter()));
return Response.createError("网络异常");
}
} catch (Exception e) {
log.error("send 2 cloud error, url : {}, rq : {}, e : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()), e);
return Response.createError("系统异常");
}
}
public <T> Response<T> postForResponseNoEncrypt(String url, Object rq, Class<T> rsClazz) {
String rqUrl = cloudConstant.getHOST() + url;
try {
log.info("openapi key : {}", cloudConstant.getENCRYPT_KEY());
HttpHeaders headers = headers();
HttpEntity httpEntity = new HttpEntity(JSON.toJSONString(rq), headers);
log.info("send 2 cloud begin , url : {}, rq : {}, header : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonSerializeFilter()),
headers.toString());
// log.info("send 2 cloud begin , url : {}, rq : {}, header : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()),
// headers.toString());
long startTime = System.currentTimeMillis();
ResponseEntity<String> entity =
noBalanceRestTemplateRnrFp.exchange(rqUrl, HttpMethod.POST, httpEntity, String.class);
long endTime = System.currentTimeMillis();
if (entity != null && entity.getStatusCodeValue() == 200) {
log.info("send 2 cloud success code 200, url : {}, rq : {}, body : {}, times : {}",
rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()), entity.getBody(), endTime - startTime);
Response<T> result = JSON.parseObject(entity.getBody(), new TypeReference<Response<T>>(rsClazz) {
}.getType());
return result;
} else {
log.info("send 2 cloud fail, url : {}, rq : {}, times : {}, entity : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()),
endTime - startTime, null == entity ? null : JSON.toJSONString(entity, new FpIgnoreBase64ImgJsonSerializeFilter()));
return Response.createError("网络异常");
}
} catch (Exception e) {
log.error("send 2 cloud error, url : {}, rq : {}, e : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()), e);
return Response.createError("系统异常");
}
}
public <T> Response<List<T>> postForResponseList(String url, Object rq, Class<T> rsClazz) {
String rqUrl = cloudConstant.getHOST() + url;
try {
HttpEntity httpEntity = new HttpEntity(
Sm4DemoUtils.encryptEcbPaddingHexString(cloudConstant.getENCRYPT_KEY(), JSON.toJSONString(rq)),
headers());
log.info("send 2 cloud begin , url : {}, rq : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonSerializeFilter()));
long startTime = System.currentTimeMillis();
ResponseEntity<String> entity =
noBalanceRestTemplateRnrFp.exchange(rqUrl, HttpMethod.POST, httpEntity, String.class);
long endTime = System.currentTimeMillis();
if (entity != null && entity.getStatusCodeValue() == 200) {
log.info("send 2 cloud success code 200, url : {}, rq : {}, body : {}, times : {}",
rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()), entity.getBody(), endTime - startTime);
Response<String> result = JSON.parseObject(entity.getBody(), new TypeReference<Response<String>>(String.class) {
}.getType());
String data = Sm4DemoUtils.decryptEcbPaddingString(cloudConstant.getDECRYPT_KEY(), result.getData());
List<T> t = JSON.parseArray(data, rsClazz);
Response<List<T>> finalresult = new Response<List<T>>(result.getMsg(), result.getCode(), t, result.getSuccess(), result.getException());
finalresult.setAttachment(result.getAttachment());
return finalresult;
} else {
log.info("send 2 cloud fail, url : {}, rq : {}, times : {}, entity : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()),
endTime - startTime, null == entity ? null : JSON.toJSONString(entity, new FpIgnoreBase64ImgJsonSerializeFilter()));
return Response.createError("网络异常");
}
} catch (Exception e) {
log.error("send 2 cloud error, url : {}, rq : {}, e : {}", rqUrl, JSON.toJSONString(rq, new FpIgnoreBase64ImgJsonNoEncryptFilter()), e);
return Response.createError("系统异常");
}
}
/**
* 生成请求头
*
* @return
*/
public HttpHeaders headers() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(SignConstants.APP_ID, cloudConstant.getAPPID());
httpHeaders.add(SignConstants.NONCE_STR, CuscStringUtils.generateUuid());
httpHeaders.add(SignConstants.TIMESTAMP, String.valueOf(System.currentTimeMillis()));
httpHeaders.add(SignConstants.VERSION, cloudConstant.getVERSION());
httpHeaders.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
StringBuilder sb = new StringBuilder();
sb.append(SignConstants.APP_ID + cloudConstant.getAPPID());
sb.append(SignConstants.NONCE_STR + httpHeaders.get(SignConstants.NONCE_STR).get(0));
sb.append(SignConstants.TIMESTAMP + httpHeaders.get(SignConstants.TIMESTAMP).get(0));
sb.append(SignConstants.VERSION + httpHeaders.get(SignConstants.VERSION).get(0));
String scret = HMAC.sign(sb.toString(), cloudConstant.getAPPSCRET(), HMAC.Type.HmacSHA256);
httpHeaders.add(SignConstants.SIGN, scret);
return httpHeaders;
}
}
package com.cusc.nirvana.user.rnr.fp.common.cloud;
/**
* 签名静态属性
*/
public class SignConstants {
/**应用ID的key名称*/
public final static String APP_ID = "APPID";
/**随机数key*/
public final static String NONCE_STR = "NONCE_STR";
/**时间戳key*/
public final static String TIMESTAMP = "TIMESTAMP";
/**版本key*/
public final static String VERSION = "VERSION";
/**签名key*/
public final static String SIGN = "SIGN";
}
package com.cusc.nirvana.user.rnr.fp.common.cloud;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Base64;
/**
* Description: 国密SM4
* <br />
* BC库从1.59版本开始已经基本实现了国密算法(SM2、SM3、SM4)
**/
public class Sm4DemoUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(Sm4DemoUtils.class);
//算法名称
public static final String ALGORITHM_NAME = "SM4";
//ECB P5填充
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
static {
Security.addProvider(new BouncyCastleProvider());
}
private Sm4DemoUtils() {
}
/**
* ecb加密默认 hexString true
**/
public static String encryptEcbPaddingHexString(String key, String data) {
return encryptEcbPaddingHex(key, data, true, null);
}
/**
* ecb解密默认 hexString true
**/
public static String decryptEcbPaddingString(String key, String data) {
return decryptEcbPaddingHex(key, data, true, null);
}
/**
* Description: ecb解密,可以指定混淆
* <br />
* CreateDate 2021-11-17 15:53:34
*
* @author yuyi
**/
public static String decryptEcbPaddingHex(String key, String data, boolean hexString, String charset) {
if (StringUtils.isEmpty(data)) {
return null;
}
try {
byte[] keyBytes;
if (hexString) {
keyBytes = hexStringToBytes(key);
} else {
keyBytes = key.getBytes();
}
byte[] decrypted = decryptEcbPaddingByte(keyBytes, base64Decoder(data));
if (StringUtils.isNotEmpty(charset)) {
return new String(decrypted, charset);
}
return new String(decrypted, StandardCharsets.UTF_8);
} catch (Exception e) {
LOGGER.error("Sm4Util.decryptEcbPaddingHex error ! ", e);
return null;
}
}
/**
* ECB P5填充解密
*
* @param key 密钥
* @param cipherText 加密后的数据
* @return byte
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws NoSuchPaddingException
*/
private static byte[] decryptEcbPaddingByte(byte[] key, byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
/**
* Description: ecb加密,可以指定混淆
* <br />
* CreateDate 2021-11-17 15:53:34
*
* @author yuyi
**/
private static String encryptEcbPaddingHex(String key, String data, boolean hexString, String charset) {
if (StringUtils.isEmpty(data)) {
return null;
}
try {
byte[] keyBytes;
if (hexString) {
keyBytes = hexStringToBytes(key);
} else {
keyBytes = key.getBytes();
}
byte[] dataBytes;
if (StringUtils.isNotEmpty(charset)) {
dataBytes = data.getBytes(charset);
} else {
dataBytes = data.getBytes(StandardCharsets.UTF_8);
}
byte[] encrypted = encryptEcbPaddingByte(keyBytes, dataBytes);
return base64Encoder(encrypted);
} catch (Exception e) {
LOGGER.error("Sm4Util.encryptEcbPaddingHex error ! ", e);
return null;
}
}
/**
* base64编码
**/
private static String base64Encoder(byte[] encrypted) {
return Base64.getEncoder().encodeToString(encrypted);
}
/**
* base64解码
**/
private static byte[] base64Decoder(String encrypted) throws IOException {
return Base64.getDecoder().decode(encrypted);
}
/**
* ECB P5填充加密
*
* @param key 密钥
* @param data 明文数据
* @return byte
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws NoSuchPaddingException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
private static byte[] encryptEcbPaddingByte(byte[] key, byte[] data)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
/**
* ECB P5填充加解密Cipher初始化
*
* @param algorithmName 算法名称
* @param mode 1 加密 2解密
* @param key 密钥
* @return Cipher
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
*/
private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
/**
* Convert hex string to byte[]
*
* @param hexString
* the hex string
* @return byte[]
*/
public static byte[] hexStringToBytes(String hexString)
{
if (hexString == null || hexString.equals(""))
{
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++)
{
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* Convert char to byte
*
* @param c
* char
* @return byte
*/
public static byte charToByte(char c)
{
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import com.alibaba.fastjson.JSONObject;
import com.cusc.nirvana.user.rnr.fp.dto.EncryptionKeyDTO;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @className: SystemConfigMap
* @description: 密钥配置
* @author: jk
* @date: 2022/7/19 14:03
* @version: 1.0
**/
@Data
@Configuration
@ConfigurationProperties(prefix = "encryptionkey")
public class EncryptionConfig {
/** 第三方接口token */
private Map<String, String> keymap;
public EncryptionKeyDTO getKey(String keyCoder){
EncryptionKeyDTO encryptionKeyDATO = null;
String json = keymap.get(keyCoder);
if(StringUtils.isEmpty(json)){
return new EncryptionKeyDTO();
}
encryptionKeyDATO = JSONObject.parseObject(json, EncryptionKeyDTO.class);
return encryptionKeyDATO;
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.*;
/**
* 异步线程池配置
*/
@Configuration
@EnableAsync
public class ExecutorConfig {
private final static Logger LOGGER = LoggerFactory.getLogger(ExecutorConfig.class);
/**
* 上报线程池
*/
@Bean("uploadExecutor")
public Executor uploadExecutor() {
LOGGER.info("init uploadExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(2);
//配置最大线程数
executor.setMaxPoolSize(10);
//配置队列大小
executor.setQueueCapacity(100);
//允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("fp-upload");
//线程池的饱和策略,满了直接丢弃。 任务已经先入库了,并有定时任务执行。这列可以直接丢弃。
//AbortPolicy:直接抛出异常,这是默认策略;
//CallerRunsPolicy:用调用者所在的线程来执行任务;
//DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务;
//DiscardPolicy:直接丢弃任务;
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
//线程池的优雅关闭,表明等待所有线程执行完
executor.setWaitForTasksToCompleteOnShutdown(true);
//执行初始化
executor.initialize();
return executor;
}
@Bean
public Executor rnrExecutorService(){
return new ThreadPoolExecutor(6,60,60,TimeUnit.SECONDS,
new ArrayBlockingQueue<>(60), new ThreadPoolExecutor.CallerRunsPolicy());
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 异步线程池配置
*/
@Configuration
@EnableAsync
public class ExecutorIssueConfig {
private final static Logger LOGGER = LoggerFactory.getLogger(ExecutorIssueConfig.class);
/**
* 上报线程池
*/
@Bean("uploadIssueExecutor")
public Executor uploadExecutor() {
LOGGER.info("init uploadIssueExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(2);
//配置最大线程数
executor.setMaxPoolSize(10);
//配置队列大小
executor.setQueueCapacity(100);
//允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("fp-uploadIssue");
//线程池的饱和策略,满了直接丢弃。 任务已经先入库了,并有定时任务执行。这列可以直接丢弃。
//AbortPolicy:直接抛出异常,这是默认策略;
//CallerRunsPolicy:用调用者所在的线程来执行任务;
//DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务;
//DiscardPolicy:直接丢弃任务;
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
//线程池的优雅关闭,表明等待所有线程执行完
executor.setWaitForTasksToCompleteOnShutdown(true);
//执行初始化
executor.initialize();
return executor;
}
@Bean
public Executor fpExecutorService(){
return new ThreadPoolExecutor(6,60,60,TimeUnit.SECONDS,
new ArrayBlockingQueue<>(60), new ThreadPoolExecutor.CallerRunsPolicy());
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Description: resttemplate的连接池配置
* <br />
* CreateDate 2022-05-18 15:00
*
* @author yuy336
**/
@Component
@Data
public class FpFileHttpPoolConfig {
/**
* 设置整个连接池最大连接数
*/
@Value("${httpPool.rnrFp.maxTotal:200}")
private Integer maxTotal;
/**
* 路由是对maxTotal的细分,针对一个url的最大并发数,每路由最大连接数,默认值是2
*/
@Value("${httpPool.rnrFp.defaultMaxPerRoute:100}")
private Integer defaultMaxPerRoute;
/**
* 服务器返回数据(response)的时间,超过该时间抛出read timeout
*/
@Value("${httpPool.rnrFp.socketTimeout:20000}")
private Integer socketTimeout;
/**
* 连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
*/
@Value("${httpPool.rnrFp.connectTimeout:1000}")
private Integer connectTimeout;
/**
* 从连接池中获取连接的超时时间,超过该时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
*/
@Value("${httpPool.rnrFp.connectionRequestTimeout:500}")
private Integer connectionRequestTimeout;
/**
* 线程最大空闲时间
*/
@Value("${httpPool.rnrFp.maxIdleTime:10}")
private Integer maxIdleTime;
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Description: resttemplate的连接池配置
* <br />
* CreateDate 2022-05-18 15:00
*
* @author yuy336
**/
@Component
@Data
public class HttpPoolConfig {
/**
* 设置整个连接池最大连接数
*/
@Value("${httpPool.rnrBase.maxTotal:200}")
private Integer maxTotal;
/**
* 路由是对maxTotal的细分,针对一个url的最大并发数,每路由最大连接数,默认值是2
*/
@Value("${httpPool.rnrBase.defaultMaxPerRoute:100}")
private Integer defaultMaxPerRoute;
/**
* 服务器返回数据(response)的时间,超过该时间抛出read timeout
*/
@Value("${httpPool.rnrBase.socketTimeout:15000}")
private Integer socketTimeout;
/**
* 连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
*/
@Value("${httpPool.rnrBase.connectTimeout:1000}")
private Integer connectTimeout;
/**
* 从连接池中获取连接的超时时间,超过该时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
*/
@Value("${httpPool.rnrBase.connectionRequestTimeout:1000}")
private Integer connectionRequestTimeout;
/**
* 线程最大空闲时间
*/
@Value("${httpPool.rnrBase.maxIdleTime:10}")
private Integer maxIdleTime;
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;
/**
* @author stayAnd
* @date 2022/4/18
*/
@Configuration
@Slf4j
public class RestTemplateConfig {
@Autowired
private HttpPoolConfig httpPoolConstants;
@Bean
@LoadBalanced
public RestTemplate balancedRestTemplateRnrFp() {
return getRestTemplateRnrFp();
}
@Bean
public RestTemplate noBalanceRestTemplateRnrFp() {
return getRestTemplateRnrFp();
}
public RestTemplate getRestTemplateRnrFp() {
return new RestTemplate(httpRequestFactoryRnrFp());
}
private ClientHttpRequestFactory httpRequestFactoryRnrFp() {
return new HttpComponentsClientHttpRequestFactory(httpClientRnrFp());
}
private HttpClient httpClientRnrFp() {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
//设置整个连接池最大连接数
connectionManager.setMaxTotal(httpPoolConstants.getMaxTotal());
//路由是对maxTotal的细分
connectionManager.setDefaultMaxPerRoute(httpPoolConstants.getDefaultMaxPerRoute());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(httpPoolConstants.getSocketTimeout()) //返回数据的超时时间
.setConnectTimeout(httpPoolConstants.getConnectTimeout()) //连接上服务器的超时时间
.setConnectionRequestTimeout(httpPoolConstants.getConnectionRequestTimeout()) //从连接池中获取连接的超时时间
.build();
return HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
//设置后台线程剔除失效连接
.evictExpiredConnections().evictIdleConnections(httpPoolConstants.getMaxIdleTime(), TimeUnit.SECONDS)
.build();
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;
/**
* Description: 文件上传RestTemplate
* <br />
* CreateDate 2022-05-12 17:31:48
*
* @author yuyi
**/
@Configuration
@Slf4j
public class RestTemplateFpFileConfig {
@Autowired
private FpFileHttpPoolConfig httpPoolConstants;
@Bean
public RestTemplate noBalanceRestTemplateRnrFpFile() {
return new RestTemplate(httpRequestFactoryRnrFpFile());
}
private ClientHttpRequestFactory httpRequestFactoryRnrFpFile() {
return new HttpComponentsClientHttpRequestFactory(httpClientRnrFpFile());
}
private HttpClient httpClientRnrFpFile() {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
//设置整个连接池最大连接数
connectionManager.setMaxTotal(httpPoolConstants.getMaxTotal());
//路由是对maxTotal的细分
connectionManager.setDefaultMaxPerRoute(httpPoolConstants.getDefaultMaxPerRoute());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(httpPoolConstants.getSocketTimeout()) //返回数据的超时时间
.setConnectTimeout(httpPoolConstants.getConnectTimeout()) //连接上服务器的超时时间
.setConnectionRequestTimeout(httpPoolConstants.getConnectionRequestTimeout()) //从连接池中获取连接的超时时间
.build();
return HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
//设置后台线程剔除失效连接
.evictExpiredConnections().evictIdleConnections(httpPoolConstants.getMaxIdleTime(), TimeUnit.SECONDS)
.build();
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Description: 前台通用配置
* <br />
* CreateDate 2022-06-23 16:28:19
**/
@Component
@Data
public class RnrFpConfig {
//自然人错误次数,超过次数转人工
@Value("${rnr.person.errorCount:3}")
public Integer personErrorCount;
@Value("${rnr.fileSelect:oss}")
private String fileSelect;
@Value("${rnr.liveness.livenessType:LIP}")
private String livenessType;
@Value("${rnr.id.compare.similarity:50}")
private String idCompareSimilarity;
@Value("${rnr.face.compare.similarity:50}")
private String faceCompareSimilarity;
@Value("${rnr.card.num.limit:10}")
private Integer cardNumLimit;
@Value("${rnr.mock:false}")
private boolean mock;
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Description: 短信相关常量类
* <br />
* CreateDate 2021-11-03 20:36
*
* @author yuyi
**/
@Component
public class SmsPropertyConfig {
//短信的url,默认值是测试环境
@Value("${sms.cusc.url:}")
public String smsUrl;
//短信发送的url
@Value("${sms.cusc.sendUrl:/sms/v1/send}")
public String sendUrl;
//短信发送结果查询的url
@Value("${sms.cusc.sendResultQueryUrl:/sms/v1/list}")
public String sendResultQueryUrl;
@Value("${sms.cusc.version:1.0.0}")
private String VERSION;
@Value("${sms.cusc.appId:}")
private String APPID;
@Value("${sms.cusc.appSecret:}")
private String APPSCRET;
//短信平台的访问key
@Value("${sms.cusc.accessKey:}")
public String accessKey;
//短信平台的strategyCode
@Value("${sms.cusc.signatureCode:}")
public String signatureCode;
//短信验证码错误次数
@Value("${sms.cusc.errorCount:3}")
public Integer errorCount;
public String getSmsUrl() {
return smsUrl;
}
public void setSmsUrl(String smsUrl) {
this.smsUrl = smsUrl;
}
public String getSendUrl() {
return sendUrl;
}
public void setSendUrl(String sendUrl) {
this.sendUrl = sendUrl;
}
public String getSendResultQueryUrl() {
return sendResultQueryUrl;
}
public void setSendResultQueryUrl(String sendResultQueryUrl) {
this.sendResultQueryUrl = sendResultQueryUrl;
}
public String getAPPID() {
return APPID;
}
public void setAPPID(String APPID) {
this.APPID = APPID;
}
public String getAPPSCRET() {
return APPSCRET;
}
public void setAPPSCRET(String APPSCRET) {
this.APPSCRET = APPSCRET;
}
public String getVERSION() {
return VERSION;
}
public void setVERSION(String VERSION) {
this.VERSION = VERSION;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSignatureCode() {
return signatureCode;
}
public void setSignatureCode(String signatureCode) {
this.signatureCode = signatureCode;
}
public Integer getErrorCount() {
return errorCount;
}
public void setErrorCount(Integer errorCount) {
this.errorCount = errorCount;
}
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @author yubo
* @since 2022-04-20 20:34
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "fp.sms.templates")
public class SmsTemplateConfig {
private Map<String,String> smsTemplates;
}
package com.cusc.nirvana.user.rnr.fp.common.config;
import com.alibaba.fastjson.JSON;
import com.cusc.nirvana.user.rnr.fp.common.FpIgnoreBase64ImgJsonSerializeFilter;
import com.cusc.nirvana.user.util.CuscStringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* Description: mvc日志输出
* <br />
* CreateDate 2021-11-12 10:26
*
* @author yuyi
**/
@Aspect
@Component
public class WebLogAspect {
private final static Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class);
/**
* 以 controller 包下定义的所有请求为切入点
*/
@Pointcut("execution(* com.cusc.nirvana.user.rnr.fp.controller.*.*(..))")
public void webLog() {
}
/**
* 环绕
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("webLog()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
String requestId = CuscStringUtils.generateUuid();
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
String url = request.getRequestURL().toString();
String method = request.getMethod();
String params = "";
//获取请求参数集合并进行遍历拼接
if ("POST".equals(method)) {
Object[] args = proceedingJoinPoint.getArgs();
params = JSON.toJSONString(args, new FpIgnoreBase64ImgJsonSerializeFilter());
} else if ("GET".equals(method)) {
params = request.getQueryString();
}
LOGGER.info("requestId:{} , request url:{} , method:{} , params:{}", requestId, url, method, params);
// result的值就是被拦截方法的返回值
Object result = proceedingJoinPoint.proceed();
LOGGER.info("requestId:{} , response url:{} , result:{} , cost:{} ms", requestId, url,
JSON.toJSONString(result, new FpIgnoreBase64ImgJsonSerializeFilter()),
System.currentTimeMillis() - startTime);
return result;
}
}
package com.cusc.nirvana.user.rnr.fp.common.constant;
import com.cusc.nirvana.user.exception.CuscUserException;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@AllArgsConstructor
@Getter
public enum FIleSystemType {
MINIO("minio", "MINIO"),
OSS("oss", "OSS"),
;
private String code;
private String descprition;
public static FIleSystemType getBytype(String code) {
return Arrays.stream(FIleSystemType.values())
.filter(businessDetail -> businessDetail.getCode().equals(code))
.findFirst()
.orElseThrow(() -> new CuscUserException("", "未查询到对应的文件系统类型:" + code));
}
}
package com.cusc.nirvana.user.rnr.fp.common.constant;
/**
* Description: redis相关常量类
* <br />
* CreateDate 2021-11-03 20:36
**/
public class FpRedisConstant {
//工单定时任务锁
public static final String ORDER_SCHEDULED_LOCK = "CT:RNR:ORDER:SCHEDULED:INVALID";
//工单定时任务锁 单位秒
public static final int ORDER_SCHEDULED_LOCK_EXPIRE = 600;
}
package com.cusc.nirvana.user.rnr.fp.common.constant;
import com.cusc.nirvana.user.exception.CuscUserException;
import com.cusc.nirvana.user.rnr.fp.handler.VinCardCheckMessageHandler;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* @author stayAnd
* @date 2022/5/17
*/
@AllArgsConstructor
@Getter
public enum VinCardCheckBussinessDetailType {
/**
* 业务类型
* 1:自然人实名-新车主
* 2: 自然人实名-二手车新车主
* 3:企业实名
* 4:车企实名
* 5:一车多卡绑定
* 6:卡解绑-原车主解绑
* 7:卡解绑-二手车解绑
* 8:换件
* 9:车企实名解绑
*/
NATURALPERSON_NEW(1,"自然人实名-新车主","checkVinExistCheckHandler",""),
NATURALPERSON_SECOND(2,"自然人实名-二手车新车主","","commonUnBindVinCardCheckHandler"),
ENTERPRISE(3,"企业实名","checkVinExistCheckHandler",""),
VEHICLE(4,"车企实名","checkVinExistCheckHandler",""),
ONECAR_MORECARD(5,"一车多卡绑定","checkVinNotExistCheckHandler",""),
UNBIND_ORIGINAL(6,"卡解绑-原车主解绑","","commonUnBindVinCardCheckHandler"),
UNBIND_SECOND(7,"卡解绑-二手车解绑","","commonUnBindVinCardCheckHandler"),
CHANGE_BOX(8,"换件","commonBindVinCardCheckHandler","commonUnBindVinCardCheckHandler"),
UNBIND_VEHICLE(9,"车企实名解绑","","commonUnBindVinCardCheckHandler")
;
private Integer type;
private String descprition;
/**
* 绑定业务 车卡关系校验的实现服务名称
*/
private String bindVinCardCheckHandlerName;
/**
* 解绑业务 车卡关系校验的实现服务名称
*/
private String unBindVinCardCheckHandlerName;
public static VinCardCheckBussinessDetailType getBytype(Integer businessType) {
return Arrays.stream(VinCardCheckBussinessDetailType.values())
.filter(businessDetail->businessDetail.getType().equals(businessType))
.findFirst()
.orElseThrow(()->new CuscUserException("","未查询到对应的业务类型:"+businessType));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment