删除 EmoneyRequestConfig 和 ProxyConfig 设置,改为数据库(SQLite)配置。默认配置的设置和删除逻辑由

SQLite 触发器配置。
This commit is contained in:
2025-11-15 14:57:02 +08:00
parent 6ccfe67aff
commit edcbfd4ffd
77 changed files with 1240 additions and 1620 deletions

View File

@@ -8,9 +8,13 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import quant.rich.emoney.annotation.LockByCaller;
import quant.rich.emoney.util.CallerLockUtil;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.concurrent.locks.ReentrantLock;
@@ -20,7 +24,7 @@ public class CallerLockAspect {
private final SpelExpressionParser parser = new SpelExpressionParser();
@Around("@annotation(me.qwq.emoney.annotation.LockByCaller)")
@Around("@annotation(quant.rich.emoney.component.CallerLockAspect.LockByCaller)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
@@ -52,4 +56,25 @@ public class CallerLockAspect {
lock.unlock();
}
}
/**
* 在方法上添加此注解,可针对调用方加锁,即:<br>
* 调用方法为 A 的,多次从 A 调用则加锁,从 B 调用时不受影响<br>
* 需要开启 AOP在任意配置类上增加注解<i><code>@EnableAspectJAutoProxy</code></i>
* @see CallerLockAspect
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public static @interface LockByCaller {
/**
* 可选参数,用于 SpEL 表达式获取 key
* 例如:<ul>
* <li>@LockByCaller(key = "#userId")</li>
* <li>@LockByCaller(key = "#userId + ':' + #userName")</li>
* </ul>
* 当不指定时,不校验参数,单纯校验 Caller
*/
String key() default "";
}
}

View File

@@ -19,6 +19,7 @@ import jakarta.validation.ConstraintViolationException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
@@ -94,15 +95,7 @@ public class EmoneyAutoPlatformExceptionHandler {
if (ex instanceof PageNotFoundException) {
throw (PageNotFoundException) ex;
}
String message = null;
if (ex.getMessage() != null) {
message = ex.getMessage();
}
else if (ex.getCause() != null) {
message = ex.getCause().getMessage();
}
ex.printStackTrace();
log.warn("Resolved exception {}", message);
log.warn("Resolved exception {}", ex);
log.warn(httpServletRequestToString(request));
return bodyOrPage(HttpStatus.INTERNAL_SERVER_ERROR, ex);
}
@@ -161,16 +154,9 @@ public class EmoneyAutoPlatformExceptionHandler {
}
private R<?> bodyOrPage(HttpStatus httpStatus, Exception ex) {
boolean isPage = true;
String message = null;
if (ex instanceof RException ||
ex instanceof LoginException) {
isPage = false;
message = ex.getMessage();
}
else {
isPage = isPage();
}
String message = getMessage(ex, ex instanceof UncategorizedSQLException);
boolean isPage = (ex instanceof RException || ex instanceof LoginException) ?
false : isPage();
if (isPage) {
if (ex instanceof NoResourceFoundException nrfe) {
if (StringUtils.isNotEmpty(nrfe.getMessage())
@@ -182,7 +168,7 @@ public class EmoneyAutoPlatformExceptionHandler {
}
throw ex == null ? new RuntimeException("Page exception raised") : new RuntimeException(ex);
}
R<?> r = message != null ?
R<?> r = StringUtils.isNotEmpty(message) ?
R.status(httpStatus).setMessage(message).setData(message)
: R.status(httpStatus);
return r;
@@ -217,4 +203,19 @@ public class EmoneyAutoPlatformExceptionHandler {
return sb.toString();
}
public String getMessage(Throwable e, boolean causeMessageFirst) {
String causeMessage = null;
if (e.getCause() != null && e.getCause() != e) {
if (causeMessageFirst) {
return getMessage(e.getCause(), true);
}
else {
causeMessage = e.getCause().getMessage();
}
}
String mainMessage = e.getMessage();
if (mainMessage != null) return mainMessage;
return causeMessage;
}
}

View File

@@ -0,0 +1,81 @@
package quant.rich.emoney.component;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import quant.rich.emoney.client.EmoneyClient;
import quant.rich.emoney.entity.sqlite.ProxySetting;
import quant.rich.emoney.entity.sqlite.RequestInfo;
import quant.rich.emoney.service.sqlite.ProxySettingService;
import quant.rich.emoney.service.sqlite.RequestInfoService;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
@Aspect
@Component
public class RequireAuthAndProxyAspect {
@Autowired
RequestInfoService requestInfoService;
@Autowired
ProxySettingService proxySettingService;
@Around("@annotation(quant.rich.emoney.component.RequireAuthAndProxyAspect.RequireAuthAndProxy)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
ProxySetting defualtProxySetting = proxySettingService.getDefaultProxySetting();
if (defualtProxySetting == null) {
throw new RuntimeException("需要配置默认代理设置");
}
RequestInfo defaultRequestInfo = requestInfoService.getDefaultRequestInfo();
if (defaultRequestInfo == null) {
throw new RuntimeException("需要配置默认请求信息");
}
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
RequireAuthAndProxy annotation = method.getAnnotation(RequireAuthAndProxy.class);
if (StringUtils.isBlank(defaultRequestInfo.getAuthorization())) {
if (!annotation.autoLogin()) {
throw new RuntimeException("需要手动为请求信息鉴权");
}
if (!EmoneyClient.loginWithManaged()) {
throw new RuntimeException("鉴权登录失败");
}
}
return pjp.proceed();
}
/**
* 在方法上添加此注解,则进入该方法前先校验 defaultRequestInfo 已鉴权、代理已配置,否则不允许进入方法
* <p>需要开启 AOP在任意配置类上增加注解<i><code>@EnableAspectJAutoProxy</code></i>
* @see RequireAuthAndProxyAspect
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public static @interface RequireAuthAndProxy {
/**
* 当存在默认请求配置但未鉴权时,是否自动鉴权
* @return
*/
boolean autoLogin() default false;
}
}