172 lines
6.8 KiB
Java
172 lines
6.8 KiB
Java
package com.evo.common.controller;
|
||
|
||
import com.alibaba.fastjson2.JSON;
|
||
import com.alibaba.fastjson2.JSONObject;
|
||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
|
||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||
import com.evo.common.annotation.ParamName;
|
||
import com.evo.common.core.controller.BaseController;
|
||
import com.evo.common.core.domain.AjaxResult;
|
||
import com.evo.common.utils.DateUtils;
|
||
import com.evo.common.utils.spring.SpringUtils;
|
||
import com.evo.common.vo.OpenParam;
|
||
import com.evo.ding.DingCallbackCrypto;
|
||
import com.evo.ding.DingGlobalParams;
|
||
import com.evo.ding.processor.callback.DingCallBackExchangeProcessor;
|
||
import com.evo.system.domain.SysPlatform;
|
||
import com.evo.system.service.SysPlatformService;
|
||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.aop.support.AopUtils;
|
||
import org.springframework.beans.BeanUtils;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.web.bind.annotation.PostMapping;
|
||
import org.springframework.web.bind.annotation.RequestBody;
|
||
import org.springframework.web.bind.annotation.RequestMapping;
|
||
import org.springframework.web.bind.annotation.RestController;
|
||
|
||
import java.lang.annotation.Annotation;
|
||
import java.lang.reflect.Method;
|
||
import java.lang.reflect.Parameter;
|
||
import java.util.Date;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* @desc:
|
||
* @ClassName:OpenController
|
||
* @date: 2026年09月24日 10:15
|
||
* @author: andy.shi
|
||
* @contact: 17330188597
|
||
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
|
||
*/
|
||
@RestController
|
||
@RequestMapping("/open/api")
|
||
@Slf4j
|
||
public class OpenController extends BaseController {
|
||
|
||
// 全局ObjectMapper,复用
|
||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||
|
||
@Autowired
|
||
private SysPlatformService platformService;
|
||
|
||
@PostMapping("/post")
|
||
public AjaxResult get(@RequestBody OpenParam openParam){
|
||
log.info("开发平台调用信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"+JSONObject.toJSONString(openParam));
|
||
try {
|
||
Assert.notEmpty(openParam.getPlatformCode(), "平台授权码不能为空");
|
||
Assert.notEmpty(openParam.getPlatformSecretKey(), "平台授权秘钥不能为空");
|
||
SysPlatform platform = platformService.getData(openParam.getPlatformCode(), openParam.getPlatformSecretKey());
|
||
if(ObjectUtils.isEmpty(platform)){
|
||
throw new RuntimeException("未找到授权平台信息");
|
||
}
|
||
Assert.notEmpty(openParam.getServiceName(), "服务方法不能为空");
|
||
Assert.notEmpty(openParam.getMethodName(), "服务接口不能为空");
|
||
|
||
//序列化参数
|
||
Object targetService =SpringUtils.getBean(openParam.getServiceName());
|
||
// 2. 找到目标方法(简单版:匹配方法名,暂不处理重载)
|
||
Method targetMethod = findMethod(targetService, openParam.getMethodName());
|
||
// 直接转Map
|
||
Map<String, Object> methodParamMap = JSON.parseObject(openParam.getParams());
|
||
|
||
if (targetMethod == null) {
|
||
throw new RuntimeException("找不到指定方法:" + openParam.getMethodName());
|
||
}
|
||
// 3. 解析方法,组装 invoke 需要的参数数组 Object[] args
|
||
Object[] args = buildMethodArgs(targetMethod, methodParamMap);
|
||
|
||
// 4. 反射执行方法
|
||
Object result = targetMethod.invoke(targetService, args);
|
||
// 1. 从http请求中获取加解密参数
|
||
return AjaxResult.success(result);
|
||
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
return AjaxResult.error(e.getMessage());
|
||
}
|
||
}
|
||
|
||
|
||
private Method findMethod(Object beanObj, String methodName) {
|
||
Class<?> targetCls = AopUtils.getTargetClass(beanObj);
|
||
Method[] declaredMethods = targetCls.getDeclaredMethods();
|
||
for (Method method : declaredMethods) {
|
||
if (method.getName().equals(methodName)) {
|
||
method.setAccessible(true);
|
||
return method;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 核心:构造方法入参数组,自动区分【单个实体】 / 【多个普通参数】
|
||
*/
|
||
private Object[] buildMethodArgs(Method method, Map<String, Object> paramMap) {
|
||
Parameter[] parameters = method.getParameters();
|
||
// ========== 重点:读取参数注解二维数组 ==========
|
||
Annotation[][] allParamAnnotations = method.getParameterAnnotations();
|
||
Object[] args = new Object[parameters.length];
|
||
|
||
// 分支1:单个参数,实体对象,不受注解影响
|
||
if (parameters.length == 1) {
|
||
Parameter param = parameters[0];
|
||
Class<?> paramType = param.getType();
|
||
Object entity = OBJECT_MAPPER.convertValue(paramMap, paramType);
|
||
args[0] = entity;
|
||
return args;
|
||
}
|
||
|
||
// 分支2:多个参数,循环读取注解
|
||
for (int i = 0; i < parameters.length; i++) {
|
||
Annotation[] annotations = allParamAnnotations[i];
|
||
String paramName = null;
|
||
for (Annotation anno : annotations) {
|
||
if (anno instanceof ParamName) {
|
||
ParamName paramNameAnno = (ParamName) anno;
|
||
paramName = paramNameAnno.value();
|
||
break;
|
||
}
|
||
}
|
||
if(paramName == null){
|
||
throw new RuntimeException("方法【"+method.getName()+"】第"+i+"个参数缺少@ParamName注解");
|
||
}
|
||
Object rawVal = paramMap.get(paramName);
|
||
Object castVal = convertType(rawVal, parameters[i].getType());
|
||
args[i] = castVal;
|
||
}
|
||
return args;
|
||
}
|
||
|
||
|
||
/**
|
||
* 简单类型转换 Object -> Integer/Long/String/Boolean等
|
||
*/
|
||
private Object convertType(Object value, Class<?> targetType) {
|
||
if (value == null) {
|
||
return null;
|
||
}
|
||
if (targetType.isInstance(value)) {
|
||
return value;
|
||
}
|
||
String str = value.toString();
|
||
if (Integer.class == targetType || int.class == targetType) {
|
||
return Integer.parseInt(str);
|
||
} else if (Long.class == targetType || long.class == targetType) {
|
||
return Long.parseLong(str);
|
||
} else if (Boolean.class == targetType || boolean.class == targetType) {
|
||
return Boolean.parseBoolean(str);
|
||
} else if (Double.class == targetType || double.class == targetType) {
|
||
return Double.parseDouble(str);
|
||
} else if (String.class == targetType) {
|
||
return str;
|
||
}else if(Date.class == targetType){
|
||
return DateUtils.parseDate(str);
|
||
}
|
||
// 其他类型直接返回,可扩展BigDecimal、Date等
|
||
return value;
|
||
}
|
||
}
|