package com.nova.sankuai.domain.api.yangqianguan; import cfca.sadk.extend.session.util.TextUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper; import com.nova.sankuai.domain.api.yangqianguan.dto.*; import com.nova.sankuai.domain.api.yangqianguan.response.CreditAuthRecordResponse; import com.nova.sankuai.domain.api.yangqianguan.response.CreditResultResponse; import com.nova.sankuai.domain.api.yangqianguan.response.RepayPlanResponse; import com.nova.sankuai.domain.api.yangqianguan.vo.VerifySignVo; import com.nova.sankuai.infra.utils.ImageUtil; import com.nova.sankuai.security.HttpClientUtil; import io.swagger.annotations.ApiModelProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; /** * @Description 洋钱罐工具类 * @Author CWR * @Date 2022/5/20 12:06 */ @Component public class YqgUtil { @ApiModelProperty(value = "host地址") @Value("${yqg.host}") private String host; @ApiModelProperty(value = "洋钱罐appId") @Value("${yqg.appId}") private String appId; @ApiModelProperty(value = "己方私钥") @Value("${yqg.self.privateKey}") private String privateKey; @ApiModelProperty(value = "洋钱罐公钥") @Value("${yqg.other.publicKey}") private String yqgPublicKey; @ApiModelProperty(value = "系统图片访问域名") @Value("${upload.imageHost}") private String imageHost; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final String HEADER_SIGNATURE = "B-SIGNATURE"; private static final String HEADER_TIMESTAMP = "B-TIMESTAMP"; private static final String HEADER_REQUEST_ID = "B-REQUEST-ID"; private static final String HEADER_APP_ID = "B-APP-ID"; private static final Logger yqgLogger = LoggerFactory.getLogger("yqgLogger"); @Resource private ImageUtil imageUtil; /** * 创建请求头 * * @param data 请求参数json字符串 * @return */ public Map buildHeaders(String data) { Map headers = new HashMap<>(16); headers.put(HEADER_APP_ID, this.appId); headers.put(HEADER_TIMESTAMP, System.currentTimeMillis()); // 使用私钥加密数据 String sign = UnifiedRsaUtils.signWithPriKey(data, privateKey); yqgLogger.info("签名:" + sign + "APPId:" + appId); headers.put(HEADER_SIGNATURE, sign); return headers; } /** * 授信图片获取 * * @param creditNo 授信编号 * @param token 图片token */ public String getImageUrl(String creditNo, String token, Logger logger, String logNumber) { try { // 请求参数 JSONObject param = new JSONObject(); param.put("credit_no", creditNo); param.put("token", token); // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(param)); logger.info("日志编号:" + logNumber + "洋钱罐授信图片获取接口参数->:{}", param); InputStream inputStream = HttpClientUtil.getInstance() .filePostData(host + "/yqg/api/v2/credit/image/fetch", OBJECT_MAPPER.writeValueAsString(param), headers); if (inputStream != null) { String url = imageUtil.uploadFileByInputStream(inputStream, false); return imageHost + "/api" + url; } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐授信图片获取接口出错", e); } return null; } /** * 授信结果反馈 * * @param dto */ public MoneyPotResultJson creditResultFeedBack(CreditResultResponse dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐授信结果反馈接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v2/credit/result/feedBack", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐授信结果反馈接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐授信结果反馈成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐授信结果反馈失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐授信结果反馈接口出错", e); } return null; } /** * 授信额度反馈 * * @param dto */ public MoneyPotResultJson creditLimitFeedBack(CreditLimitFeedBackDto dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐授信额度反馈接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v2/credit/limit/feedBack", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐授信额度反馈接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐授信额度反馈成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐授信额度反馈失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐授信额度反馈接口出错", e); } return null; } /** * 借款确认反馈 * * @param dto */ public MoneyPotResultJson loanConfirmFeedBack(LoanConfirmFeedBackDto dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐借款确认反馈接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v2/loan/confirm/feedBack", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐借款确认反馈接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐借款确认反馈成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐借款确认反馈失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐借款确认反馈接口出错", e); } return null; } /** * 还款计划反馈 * * @param dto */ public MoneyPotResultJson repaymentUpdatePlan(RepayPlanResponse dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐还款计划反馈接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v1/repayment/updatePlan", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐还款计划反馈接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐还款计划反馈成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐还款计划反馈失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐还款计划反馈接口出错", e); } return null; } /** * 还款结果反馈 * * @param dto */ public MoneyPotResultJson repayResultFeedBack(RepayResultReturnDto dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐还款结果反馈接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v2/repay/result/feedBack", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐还款结果反馈接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐还款结果反馈成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐还款结果反馈失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐还款结果反馈接口出错", e); } return null; } /** * 用户授信授权记录获取 * * @param dto */ public MoneyPotResultJson creditAuthRecord(CreditAuthRecordDto dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐用户授信授权记录获取接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v2/credit/authRecord", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐用户授信授权记录获取接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐用户授信授权记录获取成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐用户授信授权记录获取失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐用户授信授权记录获取接口出错", e); } return null; } /** * 订单状态反馈 * * @param dto */ public MoneyPotResultJson orderUpdateStatus(OrderUpdateStatusDto dto, Logger logger, String logNumber) { try { // 创建请求头 Map headers = buildHeaders(OBJECT_MAPPER.writeValueAsString(dto)); logger.info("日志编号:" + logNumber + "洋钱罐订单状态反馈接口参数->:{}", OBJECT_MAPPER.writeValueAsString(dto)); String responseString = HttpClientUtil.getInstance() .postJsonData(host + "/yqg/api/v1/order/updateStatus", OBJECT_MAPPER.writeValueAsString(dto), headers); logger.info("日志编号:" + logNumber + "洋钱罐订单状态反馈接口返回->:{}", responseString); if (!TextUtils.isEmpty(responseString)) { YqgResponse yqgResponse = JSON.parseObject(responseString, YqgResponse.class); if (yqgResponse.isSuccess()) { logger.info("日志编号:" + logNumber + "洋钱罐订单状态反馈接口成功" + yqgResponse.toString()); } else { logger.error("日志编号:" + logNumber + "洋钱罐订单状态反馈接口失败" + yqgResponse.toString()); } } } catch (Exception e) { logger.error("日志编号:" + logNumber + "洋钱罐订单状态反馈接口出错", e); } return null; } public VerifySignVo verifyYqgSign(HttpServletRequest request) throws IOException { request = new ReReadableRequestWrapper(request); String rawContent = generateRawContent(request); String signature = request.getHeader(HEADER_SIGNATURE); String timestamp = request.getHeader(HEADER_TIMESTAMP); // 请求头校验 if (signature == null || timestamp == null) { return new VerifySignVo(false, null); } yqgLogger.info("签名:" + signature + "时间戳:" + timestamp + "原始参数:" + rawContent); boolean verify = UnifiedRsaUtils.verifyWithPubKey(rawContent, signature, yqgPublicKey); return new VerifySignVo(verify, rawContent); } private String generateRawContent(HttpServletRequest request) throws IOException { StringBuilder sb = new StringBuilder(); String line; BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) { sb.append(line); } return sb.toString(); } public static String parseRemark(Double principal, Double interest, Double serviceFee, Double overdueInterest, Double otherFee) { StringBuilder sb = new StringBuilder(); if (principal != null) { sb.append("本金" + principal + "元"); } if (interest != null) { sb.append("利息" + interest + "元"); } if (serviceFee != null) { sb.append("服务费" + serviceFee + "元"); } if (overdueInterest != null) { sb.append("罚息" + overdueInterest + "元"); } if (otherFee != null) { sb.append("其他费用" + otherFee + "元"); } return sb.toString(); } }