初始化

This commit is contained in:
2026-02-22 18:56:10 +08:00
commit 26677972a6
3112 changed files with 255972 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>tech.easyflow</groupId>
<artifactId>easyflow-commons</artifactId>
<version>${revision}</version>
</parent>
<name>easyflow-common-captcha</name>
<artifactId>easyflow-common-captcha</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.933</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>tech.easyflow</groupId>
<artifactId>easyflow-common-base</artifactId>
</dependency>
<dependency>
<groupId>cloud.tianai.captcha</groupId>
<artifactId>tianai-captcha-springboot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,56 @@
package tech.easyflow.common.captcha.tainai;
import cloud.tianai.captcha.cache.CacheStore;
import cloud.tianai.captcha.cache.impl.LocalCacheStore;
import cloud.tianai.captcha.spring.store.impl.RedisCacheStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class CaptchaCacheAutoConfig {
@Bean
public CacheStore cacheStore(
@org.springframework.beans.factory.annotation.Autowired(required = false)
StringRedisTemplate stringRedisTemplate,
Environment environment) {
// 检查是否有Redis配置
boolean hasRedisConfig = hasRedisConfiguration(environment);
// 如果有Redis配置且RedisTemplate可用使用Redis
if (hasRedisConfig && stringRedisTemplate != null) {
try {
// 测试Redis连接
stringRedisTemplate.getConnectionFactory().getConnection().ping();
return new RedisCacheStore(stringRedisTemplate);
} catch (Exception e) {
// Redis不可用使用本地缓存
return new LocalCacheStore();
}
}
// 没有Redis配置使用本地缓存
return new LocalCacheStore();
}
private boolean hasRedisConfiguration(Environment environment) {
// 检查常见的Redis配置属性
String[] redisProperties = {
"spring.redis.host",
"spring.redis.port",
"spring.data.redis.host",
"spring.data.redis.port"
};
for (String property : redisProperties) {
if (environment.containsProperty(property)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,35 @@
package tech.easyflow.common.captcha.tainai;
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
import cloud.tianai.captcha.resource.CrudResourceStore;
import cloud.tianai.captcha.resource.ResourceStore;
import cloud.tianai.captcha.resource.common.model.dto.Resource;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;
@Component
public class CaptchaConfig {
private final ResourceStore resourceStore;
public CaptchaConfig(ResourceStore resourceStore) {
this.resourceStore = resourceStore;
}
@PostConstruct
public void init() {
CrudResourceStore resourceStore = (CrudResourceStore) this.resourceStore;
// 添加自定义背景图片
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/1.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/2.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/3.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/4.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/5.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/6.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/7.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/8.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/9.jpg", "default"));
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "captcha-images/10.jpg", "default"));
}
}

View File

@@ -0,0 +1,27 @@
package tech.easyflow.common.captcha.tainai;
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
public class CaptchaData {
// 验证码id
private String id;
// 验证码数据
private ImageCaptchaTrack data;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ImageCaptchaTrack getData() {
return data;
}
public void setData(ImageCaptchaTrack data) {
this.data = data;
}
}

View File

@@ -0,0 +1,21 @@
package tech.easyflow.common.captcha.tainai;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CaptchaMvcConfig implements WebMvcConfigurer {
@Resource
private CaptchaValidInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor)
.order(1)
.addPathPatterns("/api/v1/auth/login")
.addPathPatterns("/userCenter/auth/login");
}
}

View File

@@ -0,0 +1,41 @@
package tech.easyflow.common.captcha.tainai;
import cloud.tianai.captcha.application.ImageCaptchaApplication;
import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import tech.easyflow.common.domain.Result;
import tech.easyflow.common.util.RequestUtil;
import tech.easyflow.common.util.ResponseUtil;
@Component
public class CaptchaValidInterceptor implements HandlerInterceptor {
@Resource
private ImageCaptchaApplication application;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
JSONObject jsonObject = (JSONObject) RequestUtil.readJsonObjectOrArray(request);
String validToken = jsonObject.getString("validToken");
if (validToken == null || validToken.isEmpty()) {
renderNotLogin(response);
return false;
}
boolean valid = ((SecondaryVerificationApplication) application).secondaryVerification(validToken);
if (!valid) {
renderNotLogin(response);
return false;
}
return true;
}
private static void renderNotLogin(HttpServletResponse response) {
Result result = Result.fail(99, "验证失败,请重试!");
ResponseUtil.renderJson(response, result);
}
}