Files
jsowell-charger-web/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/ThirdPartyBaseController.java
2025-09-12 15:34:40 +08:00

238 lines
8.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.jsowell.api.thirdparty;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Maps;
import com.jsowell.common.annotation.Anonymous;
import com.jsowell.common.core.controller.BaseController;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.JWTUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.thirdparty.CommonParamsDTO;
import com.jsowell.pile.vo.ThirdPartySecretInfoVO;
import com.jsowell.thirdparty.platform.util.Cryptos;
import com.jsowell.thirdparty.platform.util.GBSignUtils;
import com.jsowell.thirdparty.service.ThirdpartySecretInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 基础Controller
*/
@Anonymous
@RestController
public class ThirdPartyBaseController extends BaseController {
@Autowired
private ThirdpartySecretInfoService thirdpartySecretInfoService;
/**
* 验证token
*/
protected boolean verifyToken(String token) {
if (StringUtils.equals(token, "jsowellTest")) {
// 为了方便测试token为jsowellTest校验通过
return true;
}
boolean result;
try {
result = JWTUtils.checkThirdPartyToken(token);
} catch (Exception e) {
result = false;
}
return result;
}
/**
* 解析DTO
* @param dto
* @param targetClass
* @return
* @param <T>
*/
protected <T> T parseParamsDTO(CommonParamsDTO dto, Class<T> targetClass) throws NoSuchFieldException, IllegalAccessException {
// 解密
String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID();
ThirdPartySecretInfoVO secretInfoVO;
if (StringUtils.isNotBlank(dto.getPlatformType())) {
// type不为空按照type查
secretInfoVO = thirdpartySecretInfoService.queryByThirdPlatformType(dto.getPlatformType());
}else {
secretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
}
// 通过operatorId 查出 operatorSecret
// ThirdPartySecretInfoVO secretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
if (secretInfoVO == null) {
throw new BusinessException("1", "无此对接平台");
}
String dataSecret = secretInfoVO.getOurDataSecret();
String dataSecretIv = secretInfoVO.getOurDataSecretIv();
// 解密data 获取参数中的OperatorSecret
String decrypt = Cryptos.decrypt(dto.getData(), dataSecret, dataSecretIv);
T t = JSONObject.parseObject(decrypt, targetClass);
// 校验是否有operatorId, 没有就set
verifyOperatorId(dto, t);
return t;
}
/**
* 获取OperatorId的值 verify
* @param t
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
private <T> void verifyOperatorId(CommonParamsDTO dto, T t) throws NoSuchFieldException, IllegalAccessException {
String targetFieldName = "operatorId";
String operatorId = (String) getFieldValueByObject(t, targetFieldName);
if (StringUtils.isBlank(operatorId)) {
setFieldValueByFieldName(t, targetFieldName, dto.getOperatorID());
}
}
private <T> void setFieldValueByFieldName(T t, String targetFieldName, Object value) {
// 获取该对象的class
Class<? extends Object> tClass = t.getClass();
// 获取所有的属性数组
Field[] fields = tClass.getDeclaredFields();
for (Field field : fields) {
// 属性名称
String currentFieldName = "";
try {
boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class);
if (has_JsonProperty) {
currentFieldName = field.getAnnotation(JsonProperty.class).value();
} else {
currentFieldName = field.getName();
}
// 忽略大小写对比
if (currentFieldName.equalsIgnoreCase(targetFieldName)) {
// 取消语言访问检查
field.setAccessible(true);
// 给变量赋值
field.set(t, value);
return;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/**
* 使用反射获取字段值
*/
private <T> Object getFieldValueByObject(T t, String targetFieldName) {
// 获取该对象的class
Class<? extends Object> tClass = t.getClass();
// 获取所有的属性数组
Field[] fields = tClass.getDeclaredFields();
/**
* 这里只需要 id 这个属性,所以直接取 fields[0] 这
* 一个如果id不是排在第一位自己取相应的位置
* 如果有需要可以写成for循环遍历全部属性
*/
for (Field field : fields) {
// 属性名称
String currentFieldName = "";
// 获取属性上面的注解 import com.fasterxml.jackson.annotation.JsonProperty;
/**
* 举例: @JsonProperty("roleIds")
* private String roleIds;
*/
try {
boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class);
if (has_JsonProperty) {
currentFieldName = field.getAnnotation(JsonProperty.class).value();
} else {
currentFieldName = field.getName();
}
// 忽略大小写对比
if (currentFieldName.equalsIgnoreCase(targetFieldName)) {
field.setAccessible(true);
currentFieldName = currentFieldName.replaceFirst(currentFieldName.substring(0, 1), currentFieldName.substring(0, 1).toUpperCase());
//整合出 getId() 属性这个方法
Method m = tClass.getMethod("get" + currentFieldName);
return m.invoke(t);
}
} catch (SecurityException e) {
// 安全性异常
e.printStackTrace();
} catch (IllegalArgumentException e) {
// 非法参数
e.printStackTrace();
} catch (IllegalAccessException | NoSuchMethodException e) {
// 无访问权限
e.printStackTrace();
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
return null;
}
/**
* 校验签名
*
* verifySignature
*/
protected boolean verifySignature(CommonParamsDTO dto) {
return this.verifySignature(dto, null);
}
protected boolean verifySignature(CommonParamsDTO dto, String signSecret) {
// 查询密钥
String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID();
ThirdPartySecretInfoVO secretInfoVO;
if (StringUtils.isNotBlank(dto.getPlatformType())) {
// type不为空按照type查
secretInfoVO = thirdpartySecretInfoService.queryByThirdPlatformType(dto.getPlatformType());
}else {
secretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId);
}
if (secretInfoVO == null) {
throw new BusinessException("1", "无此对接平台");
}
// 校验签名,使用响应方的密钥
if (StringUtils.isBlank(signSecret)) {
signSecret = secretInfoVO.getOurSigSecret();
}
Map<String, String> map = Maps.newLinkedHashMap();
String operatorID = dto.getOperatorID();
if (StringUtils.isNotBlank(operatorID)) {
map.put("OperatorID", operatorID);
}
String platformID = dto.getPlatformID();
if (StringUtils.isNotBlank(platformID)) {
map.put("PlatformID", platformID);
}
String data = dto.getData();
if (StringUtils.isNotBlank(data)) {
map.put("Data", data);
}
String timeStamp = dto.getTimeStamp();
if (StringUtils.isNotBlank(timeStamp)) {
map.put("TimeStamp", timeStamp);
}
String seq = dto.getSeq();
if (StringUtils.isNotBlank(seq)) {
map.put("Seq", seq);
}
// 计算sign
String sign = GBSignUtils.sign(map, signSecret);
logger.info("sign:{}, dto.getSig():{}", sign, dto.getSig());
return StringUtils.equals(dto.getSig(), sign);
}
}