v0.0.4 #3
38
pom.xml
38
pom.xml
@@ -13,7 +13,7 @@
|
||||
|
||||
<groupId>com.imyeyu.spring</groupId>
|
||||
<artifactId>timi-spring</artifactId>
|
||||
<version>0.0.3</version>
|
||||
<version>0.0.4</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
@@ -37,10 +37,42 @@
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok-maven-plugin</artifactId>
|
||||
<version>1.18.20.0</version>
|
||||
<configuration>
|
||||
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
||||
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
|
||||
<addOutputDirectory>false</addOutputDirectory>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>delombok</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.36</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.11.2</version>
|
||||
<configuration>
|
||||
<sourcepath>${project.build.directory}/delombok</sourcepath>
|
||||
<encoding>UTF-8</encoding>
|
||||
<charset>UTF-8</charset>
|
||||
<docencoding>UTF-8</docencoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -130,5 +162,9 @@
|
||||
<artifactId>timi-io</artifactId>
|
||||
<version>0.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
package com.imyeyu.spring;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.imyeyu.io.IO;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.Language;
|
||||
import com.imyeyu.java.bean.timi.TimiCode;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.java.bean.timi.TimiResponse;
|
||||
import com.imyeyu.java.ref.Ref;
|
||||
import com.imyeyu.spring.bean.RequestRange;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
@@ -21,8 +18,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -39,56 +35,12 @@ import java.util.Locale;
|
||||
*/
|
||||
public class TimiSpring {
|
||||
|
||||
/** 版本号 */
|
||||
public static final String VERSION = "0.0.1";
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TimiSpring.class);
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
/**
|
||||
* 工具类禁止实例化
|
||||
*/
|
||||
private TimiSpring() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 回调数据
|
||||
*
|
||||
* @param response 返回
|
||||
* @param resp 返回结果
|
||||
*/
|
||||
public static void render(HttpServletResponse response, TimiResponse<?> resp) {
|
||||
try {
|
||||
HttpSession session = getSession();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
OutputStream out = response.getOutputStream();
|
||||
out.write(GSON.toJson(resp).getBytes(StandardCharsets.UTF_8));
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
log.error("TimiSpring.render Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 回调错误
|
||||
*
|
||||
* @param response 返回
|
||||
* @param code 代码
|
||||
* @param msgKey 消息映射键
|
||||
*/
|
||||
public static void renderError(HttpServletResponse response, TimiCode code, String msgKey) {
|
||||
try {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
OutputStream out = response.getOutputStream();
|
||||
out.write(GSON.toJson(code.toResponse().msg(msgKey)).getBytes(StandardCharsets.UTF_8));
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
log.error("TimiSpring.renderError error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Servlet 请求属性
|
||||
*
|
||||
@@ -380,9 +332,9 @@ public class TimiSpring {
|
||||
if (cookies == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < cookies.length; i++) {
|
||||
if (cookies[i].getName().equals(key)) {
|
||||
return cookies[i];
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals(key)) {
|
||||
return cookie;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -469,11 +421,11 @@ public class TimiSpring {
|
||||
/**
|
||||
* 解析 Range 请求范围
|
||||
*
|
||||
* @param fileLength 文件长度
|
||||
* @param total 总数据量
|
||||
* @return 请求范围
|
||||
* @throws IOException IO 异常
|
||||
*/
|
||||
public static RequestRange requestRange(long fileLength) throws IOException {
|
||||
public static RequestRange getRequestRange(long total) throws IOException {
|
||||
HttpServletResponse resp = getResponse();
|
||||
|
||||
String range = getRequestAttrAsString("Range");
|
||||
@@ -485,14 +437,14 @@ public class TimiSpring {
|
||||
String[] ranges = rangeValue.split("-");
|
||||
TimiException.requiredTrue(2 == ranges.length, "Invalid Range format");
|
||||
long start = Long.parseLong(ranges[0]);
|
||||
long end = ranges[1].isEmpty() ? fileLength - 1 : Long.parseLong(ranges[1]);
|
||||
long end = ranges[1].isEmpty() ? total - 1 : Long.parseLong(ranges[1]);
|
||||
// 验证范围有效性
|
||||
if (start < 0 || fileLength <= end || end < start) {
|
||||
resp.setHeader("Content-Range", "bytes */" + fileLength);
|
||||
if (start < 0 || total <= end || end < start) {
|
||||
resp.setHeader("Content-Range", "bytes */" + total);
|
||||
resp.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
|
||||
return null;
|
||||
}
|
||||
return new RequestRange(start, end);
|
||||
return new RequestRange(start, end, total);
|
||||
}
|
||||
|
||||
public static void copyPropertiesNotNull(Object source, Object target) {
|
||||
@@ -507,4 +459,22 @@ public class TimiSpring {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void responseRangeStream(InputStream stream, long total) throws IOException {
|
||||
HttpServletResponse resp = getResponse();
|
||||
RequestRange range = getRequestRange(total);
|
||||
if (range == null) {
|
||||
// 完整文件
|
||||
resp.setContentLengthLong(total);
|
||||
resp.setStatus(HttpServletResponse.SC_OK);
|
||||
IO.toOutputStream(stream, resp.getOutputStream());
|
||||
} else {
|
||||
// 分片文件
|
||||
resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
||||
resp.setHeader("Content-Range", "bytes %s-%s/%s".formatted(range.getStart(), range.getEnd(), range.getTotal()));
|
||||
resp.setContentLengthLong(range.getLength());
|
||||
IO.toOutputStream(stream, resp.getOutputStream(), range.getStart(), range.getEnd());
|
||||
resp.flushBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class AOPLogInterceptor {
|
||||
}
|
||||
|
||||
/** 注入注解 */
|
||||
@Pointcut("@annotation(annotation.com.imyeyu.spring.AOPLog)")
|
||||
@Pointcut("@annotation(com.imyeyu.spring.annotation.AOPLog)")
|
||||
public void logPointCut() {
|
||||
}
|
||||
|
||||
@@ -63,22 +63,24 @@ public class AOPLogInterceptor {
|
||||
@AfterReturning(returning = "response", pointcut = "logPointCut()")
|
||||
public void doAfterReturning(Object response) throws Throwable {
|
||||
String msg = "ID: {} Response <- Return.";
|
||||
if (response instanceof IDEntity<?> entity) {
|
||||
switch (response) {
|
||||
case IDEntity<?> entity ->
|
||||
// 返回实体
|
||||
msg += entity.getClass().getSimpleName() + "." + entity.getId();
|
||||
} else if (response instanceof PageResult<?> pageResult) {
|
||||
case PageResult<?> pageResult -> {
|
||||
// 返回数组
|
||||
if (pageResult.getList().isEmpty()) {
|
||||
msg += "PageResult<?> Empty";
|
||||
} else {
|
||||
if (pageResult.getList().get(0) == null) {
|
||||
if (pageResult.getList().getFirst() == null) {
|
||||
msg += "PageResult<?>." + pageResult.getList().size();
|
||||
} else {
|
||||
msg += "PageResult<" + pageResult.getList().get(0).getClass().getSimpleName() + ">[" + pageResult.getList().size() + "]";
|
||||
msg += "PageResult<%s>[%s]".formatted(pageResult.getList().getFirst().getClass().getSimpleName(), pageResult.getList().size());
|
||||
}
|
||||
}
|
||||
// 返回数据页
|
||||
} else if (response instanceof String string) {
|
||||
}
|
||||
case String string -> {
|
||||
// 返回字符串
|
||||
if (string.length() < 64) {
|
||||
msg += string;
|
||||
@@ -86,13 +88,14 @@ public class AOPLogInterceptor {
|
||||
msg += string.substring(0, 64) + "..";
|
||||
}
|
||||
msg = msg.replaceAll("[\\r\\n]+", "");
|
||||
} else if (response instanceof Boolean bool) {
|
||||
}
|
||||
case Boolean bool ->
|
||||
// 返回布尔值
|
||||
msg += bool;
|
||||
} else if (response instanceof Number number) {
|
||||
case Number number ->
|
||||
// 返回数字
|
||||
msg += response.getClass().getSimpleName() + ".[" + number.doubleValue() + "]";
|
||||
} else {
|
||||
case null, default -> {
|
||||
// 其他对象
|
||||
if (TimiJava.isNotEmpty(response)) {
|
||||
msg += response.getClass().getSimpleName();
|
||||
@@ -100,6 +103,7 @@ public class AOPLogInterceptor {
|
||||
msg += "NULL";
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info(msg, TimiSpring.getSessionAttr(REQUEST_ID));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ public abstract class CaptchaValidAbstractInterceptor {
|
||||
}
|
||||
if (joinPoint.getSignature() instanceof MethodSignature ms) {
|
||||
Object[] args = joinPoint.getArgs();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] instanceof CaptchaData<?> captchaData) {
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof CaptchaData<?> captchaData) {
|
||||
// 校验请求参数的验证码
|
||||
verify(captchaData.getCaptchaId(), captchaData.getCaptcha());
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.imyeyu.spring.annotation;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
@@ -12,14 +13,9 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||
* @author 夜雨
|
||||
* @version 2021-08-16 18:07
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public abstract class RequestRateLimitAbstractInterceptor implements HandlerInterceptor {
|
||||
|
||||
/**
|
||||
* 创建访问频率限制拦截器
|
||||
*/
|
||||
protected RequestRateLimitAbstractInterceptor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建接口标识
|
||||
*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.imyeyu.spring.bean;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 含验证码数据实体
|
||||
@@ -9,6 +10,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||
* @author 夜雨
|
||||
* @version 2021-03-01 17:10
|
||||
*/
|
||||
@Data
|
||||
public class CaptchaData<T> {
|
||||
|
||||
/** 来源 */
|
||||
@@ -21,64 +23,4 @@ public class CaptchaData<T> {
|
||||
|
||||
/** 数据体 */
|
||||
protected T data;
|
||||
|
||||
/**
|
||||
* 创建验证码数据实体
|
||||
*/
|
||||
public CaptchaData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码 ID
|
||||
*
|
||||
* @return 验证码 ID
|
||||
*/
|
||||
public String getCaptchaId() {
|
||||
return captchaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置验证码 ID
|
||||
*
|
||||
* @param captchaId 验证码 ID
|
||||
*/
|
||||
public void setCaptchaId(String captchaId) {
|
||||
this.captchaId = captchaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*
|
||||
* @return 验证码
|
||||
*/
|
||||
public String getCaptcha() {
|
||||
return captcha;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置验证码
|
||||
*
|
||||
* @param captcha 验证码
|
||||
*/
|
||||
public void setCaptcha(String captcha) {
|
||||
this.captcha = captcha;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据体
|
||||
*
|
||||
* @return 数据体
|
||||
*/
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据体
|
||||
*
|
||||
* @param data 数据体
|
||||
*/
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import com.imyeyu.spring.entity.Creatable;
|
||||
import com.imyeyu.spring.entity.Deletable;
|
||||
import com.imyeyu.spring.entity.IDEntity;
|
||||
import com.imyeyu.spring.entity.Updatable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 多语言实体基类
|
||||
@@ -15,6 +17,8 @@ import com.imyeyu.spring.entity.Updatable;
|
||||
* @author 夜雨
|
||||
* @since 2025-10-17 15:21
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Multilingual extends Language implements IDEntity<String>, Creatable, Updatable, Deletable {
|
||||
|
||||
/** 唯一标识 */
|
||||
@@ -31,12 +35,6 @@ public class Multilingual extends Language implements IDEntity<String>, Creatabl
|
||||
/** 删除时间 */
|
||||
protected Long deletedAt;
|
||||
|
||||
/**
|
||||
* 创建多语言实体
|
||||
*/
|
||||
public Multilingual() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定语言值
|
||||
*
|
||||
@@ -50,44 +48,4 @@ public class Multilingual extends Language implements IDEntity<String>, Creatabl
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreatedAt(Long createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdatedAt(Long updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getDeletedAt() {
|
||||
return deletedAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeletedAt(Long deletedAt) {
|
||||
this.deletedAt = deletedAt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.BasePage;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.utils.Text;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
@@ -14,6 +17,9 @@ import java.util.LinkedHashMap;
|
||||
* @author 夜雨
|
||||
* @version 2023-06-02 14:47
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Page<T> extends BasePage {
|
||||
|
||||
/** 精确匹配示例 */
|
||||
@@ -31,12 +37,6 @@ public class Page<T> extends BasePage {
|
||||
/** 排序字段映射 */
|
||||
protected LinkedHashMap<String, BaseMapper.OrderType> orderMap;
|
||||
|
||||
/**
|
||||
* 创建分页参数
|
||||
*/
|
||||
public Page() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建分页参数
|
||||
*
|
||||
@@ -65,96 +65,6 @@ public class Page<T> extends BasePage {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取精确匹配示例
|
||||
*
|
||||
* @return 精确匹配示例
|
||||
*/
|
||||
public T getEqualsExample() {
|
||||
return equalsExample;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置精确匹配示例
|
||||
*
|
||||
* @param equalsExample 精确匹配示例
|
||||
*/
|
||||
public void setEqualsExample(T equalsExample) {
|
||||
this.equalsExample = equalsExample;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模糊匹配示例
|
||||
*
|
||||
* @return 模糊匹配示例
|
||||
*/
|
||||
public T getLikesExample() {
|
||||
return likesExample;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模糊匹配示例
|
||||
*
|
||||
* @param likesExample 模糊匹配示例
|
||||
*/
|
||||
public void setLikesExample(T likesExample) {
|
||||
this.likesExample = likesExample;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取精确匹配连接逻辑
|
||||
*
|
||||
* @return 连接逻辑
|
||||
*/
|
||||
public Logic getEqualsLogic() {
|
||||
return equalsLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置精确匹配连接逻辑
|
||||
*
|
||||
* @param equalsLogic 连接逻辑
|
||||
*/
|
||||
public void setEqualsLogic(Logic equalsLogic) {
|
||||
this.equalsLogic = equalsLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模糊匹配连接逻辑
|
||||
*
|
||||
* @return 连接逻辑
|
||||
*/
|
||||
public Logic getLikesLogic() {
|
||||
return likesLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模糊匹配连接逻辑
|
||||
*
|
||||
* @param likesLogic 连接逻辑
|
||||
*/
|
||||
public void setLikesLogic(Logic likesLogic) {
|
||||
this.likesLogic = likesLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排序映射
|
||||
*
|
||||
* @return 排序映射
|
||||
*/
|
||||
public LinkedHashMap<String, BaseMapper.OrderType> getOrderMap() {
|
||||
return orderMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置排序映射
|
||||
*
|
||||
* @param orderMap 排序映射
|
||||
*/
|
||||
public void setOrderMap(LinkedHashMap<String, BaseMapper.OrderType> orderMap) {
|
||||
this.orderMap = orderMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加排序字段
|
||||
*
|
||||
|
||||
@@ -11,9 +11,4 @@ import com.imyeyu.java.bean.BasePageResult;
|
||||
*/
|
||||
public class PageResult<T> extends BasePageResult<T> {
|
||||
|
||||
/**
|
||||
* 创建分页结果
|
||||
*/
|
||||
public PageResult() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
package com.imyeyu.spring.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* RedisConfig 配置参数
|
||||
*
|
||||
* @author 夜雨
|
||||
* @version 2021-11-21 10:02
|
||||
*/
|
||||
@Data
|
||||
public class RedisConfigParams {
|
||||
|
||||
/**
|
||||
* 创建 Redis 配置参数
|
||||
*/
|
||||
public RedisConfigParams() {
|
||||
}
|
||||
|
||||
/** 地址 */
|
||||
private String host;
|
||||
|
||||
@@ -35,129 +32,4 @@ public class RedisConfigParams {
|
||||
/** 最大空闲连接 */
|
||||
private int maxIdle;
|
||||
|
||||
/**
|
||||
* 获取地址
|
||||
*
|
||||
* @return 地址
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地址
|
||||
*
|
||||
* @param host 地址
|
||||
*/
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取端口
|
||||
*
|
||||
* @return 端口
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置端口
|
||||
*
|
||||
* @param port 端口
|
||||
*/
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取密码
|
||||
*
|
||||
* @return 密码
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置密码
|
||||
*
|
||||
* @param password 密码
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取超时(毫秒)
|
||||
*
|
||||
* @return 超时(毫秒)
|
||||
*/
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置超时(毫秒)
|
||||
*
|
||||
* @param timeout 超时(毫秒)
|
||||
*/
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最大活跃连接
|
||||
*
|
||||
* @return 最大活跃连接
|
||||
*/
|
||||
public int getMaxActive() {
|
||||
return maxActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最大活跃连接
|
||||
*
|
||||
* @param maxActive 最大活跃连接
|
||||
*/
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.maxActive = maxActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最小空闲连接
|
||||
*
|
||||
* @return 最小空闲连接
|
||||
*/
|
||||
public int getMinIdle() {
|
||||
return minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最小空闲连接
|
||||
*
|
||||
* @param minIdle 最小空闲连接
|
||||
*/
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最大空闲连接
|
||||
*
|
||||
* @return 最大空闲连接
|
||||
*/
|
||||
public int getMaxIdle() {
|
||||
return maxIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最大空闲连接
|
||||
*
|
||||
* @param maxIdle 最大空闲连接
|
||||
*/
|
||||
public void setMaxIdle(int maxIdle) {
|
||||
this.maxIdle = maxIdle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
package com.imyeyu.spring.bean;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 请求范围参数
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2025-07-14 17:09
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class RequestRange {
|
||||
|
||||
/** 起始值 */
|
||||
@@ -14,52 +21,8 @@ public class RequestRange {
|
||||
/** 结束值 */
|
||||
private long end;
|
||||
|
||||
/**
|
||||
* 创建请求范围
|
||||
*
|
||||
* @param start 起始值
|
||||
* @param end 结束值
|
||||
*/
|
||||
public RequestRange(long start, long end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取起始值
|
||||
*
|
||||
* @return 起始值
|
||||
*/
|
||||
public long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置起始值
|
||||
*
|
||||
* @param start 起始值
|
||||
*/
|
||||
public void setStart(long start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结束值
|
||||
*
|
||||
* @return 结束值
|
||||
*/
|
||||
public long getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置结束值
|
||||
*
|
||||
* @param end 结束值
|
||||
*/
|
||||
public void setEnd(long end) {
|
||||
this.end = end;
|
||||
}
|
||||
/** 总数据量 */
|
||||
private long total;
|
||||
|
||||
/**
|
||||
* 获取范围长度
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.imyeyu.spring.entity;
|
||||
|
||||
import com.imyeyu.spring.annotation.table.DeleteColumn;
|
||||
import com.imyeyu.utils.Time;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -11,14 +12,9 @@ import java.io.Serializable;
|
||||
* @author 夜雨
|
||||
* @version 2021-11-20 17:45
|
||||
*/
|
||||
@Data
|
||||
public class BaseEntity implements Serializable, Creatable, Updatable, Deletable {
|
||||
|
||||
/**
|
||||
* 创建基础实体
|
||||
*/
|
||||
public BaseEntity() {
|
||||
}
|
||||
|
||||
/** 创建时间 */
|
||||
protected Long createdAt;
|
||||
|
||||
@@ -29,60 +25,6 @@ public class BaseEntity implements Serializable, Creatable, Updatable, Deletable
|
||||
@DeleteColumn
|
||||
protected Long deletedAt;
|
||||
|
||||
/**
|
||||
* 获取创建时间
|
||||
*
|
||||
* @return 创建时间
|
||||
*/
|
||||
public Long getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置创建时间
|
||||
*
|
||||
* @param createdAt 创建时间
|
||||
*/
|
||||
public void setCreatedAt(Long createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取更新时间
|
||||
*
|
||||
* @return 更新时间
|
||||
*/
|
||||
public Long getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置更新时间
|
||||
*
|
||||
* @param updatedAt 更新时间
|
||||
*/
|
||||
public void setUpdatedAt(Long updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取删除时间
|
||||
*
|
||||
* @return 删除时间
|
||||
*/
|
||||
public Long getDeletedAt() {
|
||||
return deletedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置删除时间
|
||||
*
|
||||
* @param deletedAt 删除时间
|
||||
*/
|
||||
public void setDeletedAt(Long deletedAt) {
|
||||
this.deletedAt = deletedAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleted() {
|
||||
return deletedAt != null && deletedAt < Time.now();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.imyeyu.spring.entity;
|
||||
|
||||
import com.imyeyu.spring.annotation.table.Id;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 基本长整型 ID 实体
|
||||
@@ -8,33 +10,11 @@ import com.imyeyu.spring.annotation.table.Id;
|
||||
* @author 夜雨
|
||||
* @since 2025-02-07 12:51
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Entity extends BaseEntity implements IDEntity<Long> {
|
||||
|
||||
/** ID */
|
||||
@Id
|
||||
protected Long id;
|
||||
|
||||
/**
|
||||
* 创建基础 ID 实体
|
||||
*/
|
||||
public Entity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ID
|
||||
*
|
||||
* @return ID
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 ID
|
||||
*
|
||||
* @param id ID
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.imyeyu.spring.entity;
|
||||
|
||||
import com.imyeyu.spring.annotation.table.AutoUUID;
|
||||
import com.imyeyu.spring.annotation.table.Id;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 基本 UUID 实体
|
||||
@@ -9,24 +11,12 @@ import com.imyeyu.spring.annotation.table.Id;
|
||||
* @author 夜雨
|
||||
* @since 2025-02-07 12:07
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UUIDEntity extends BaseEntity implements IDEntity<String> {
|
||||
|
||||
/** ID */
|
||||
@Id
|
||||
@AutoUUID
|
||||
protected String id;
|
||||
|
||||
/**
|
||||
* 创建 UUID 实体
|
||||
*/
|
||||
public UUIDEntity() {
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@ import java.sql.SQLException;
|
||||
*/
|
||||
public class GsonHandler extends BaseTypeHandler<JsonElement> {
|
||||
|
||||
/**
|
||||
* 创建 Gson 类型处理器
|
||||
*/
|
||||
public GsonHandler() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, JsonElement parameter, JdbcType jdbcType) throws SQLException {
|
||||
ps.setString(i, parameter.toString());
|
||||
|
||||
@@ -20,12 +20,6 @@ public abstract class AbstractEntityService<T, P> implements BaseService<T, P> {
|
||||
/** 基本 Mapper */
|
||||
protected BaseMapper<T, P> baseMapper;
|
||||
|
||||
/**
|
||||
* 创建实体服务
|
||||
*/
|
||||
protected AbstractEntityService() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Mapper 实例
|
||||
*
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.imyeyu.spring.util;
|
||||
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
@@ -16,12 +16,6 @@ import java.lang.annotation.Annotation;
|
||||
*/
|
||||
public abstract class AbstractValidator<A extends Annotation, T> implements ConstraintValidator<A, T> {
|
||||
|
||||
/**
|
||||
* 创建校验器
|
||||
*/
|
||||
protected AbstractValidator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证处理器,入参验证数据,返回错误消息语言映射,返回 null 时表示通过验证
|
||||
*
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.imyeyu.spring.entity.Updatable;
|
||||
import com.imyeyu.spring.mapper.BaseMapper;
|
||||
import com.imyeyu.utils.Text;
|
||||
import com.imyeyu.utils.Time;
|
||||
import lombok.Getter;
|
||||
import org.apache.ibatis.builder.annotation.ProviderContext;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -443,6 +444,7 @@ public abstract class BaseSQLProvider {
|
||||
* @author 夜雨
|
||||
* @since 2025-02-05 23:47
|
||||
*/
|
||||
@Getter
|
||||
protected static class EntityMeta {
|
||||
|
||||
/** 实体类 */
|
||||
@@ -541,51 +543,6 @@ public abstract class BaseSQLProvider {
|
||||
return sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体类型
|
||||
*
|
||||
* @return 实体类型
|
||||
*/
|
||||
public Class<?> getEntityClass() {
|
||||
return entityClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表名
|
||||
*
|
||||
* @return 表名
|
||||
*/
|
||||
public String getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询字段映射
|
||||
*
|
||||
* @return 查询字段映射
|
||||
*/
|
||||
public String getSelectAllClause() {
|
||||
return selectAllClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ID 字段映射
|
||||
*
|
||||
* @return ID 字段映射
|
||||
*/
|
||||
public FieldColumn getIdFieldColumn() {
|
||||
return idFieldColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段映射列表
|
||||
*
|
||||
* @return 字段映射列表
|
||||
*/
|
||||
public List<FieldColumn> getFieldColumnList() {
|
||||
return fieldColumnList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否可创建
|
||||
*
|
||||
@@ -629,6 +586,7 @@ public abstract class BaseSQLProvider {
|
||||
* @author 夜雨
|
||||
* @since 2025-02-07 09:54
|
||||
*/
|
||||
@Getter
|
||||
protected static class FieldColumn {
|
||||
|
||||
/** 字段 */
|
||||
@@ -745,42 +703,6 @@ public abstract class BaseSQLProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段
|
||||
*
|
||||
* @return 字段
|
||||
*/
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段名
|
||||
*
|
||||
* @return 字段名
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列名
|
||||
*
|
||||
* @return 列名
|
||||
*/
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 ID 字段
|
||||
*
|
||||
* @return true 为 ID 字段
|
||||
*/
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否非 ID 字段
|
||||
*
|
||||
@@ -789,23 +711,5 @@ public abstract class BaseSQLProvider {
|
||||
public boolean isNotId() {
|
||||
return !isId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否自动 UUID
|
||||
*
|
||||
* @return true 为自动 UUID
|
||||
*/
|
||||
public boolean isAutoUUID() {
|
||||
return isAutoUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否自动大写 UUID
|
||||
*
|
||||
* @return true 为自动大写 UUID
|
||||
*/
|
||||
public boolean isAutoUpperUUID() {
|
||||
return isAutoUpperUUID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
private static final String DEV_LANG_CONFIG = "dev.lang";
|
||||
|
||||
/**
|
||||
* 创建全局异常处理器
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.imyeyu.java.bean.timi.TimiResponse;
|
||||
import com.imyeyu.spring.TimiSpring;
|
||||
import com.imyeyu.spring.annotation.AOPLogInterceptor;
|
||||
import com.imyeyu.spring.annotation.IgnoreGlobalReturn;
|
||||
import lombok.Data;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
@@ -27,6 +28,7 @@ import java.util.Objects;
|
||||
* @author 夜雨
|
||||
* @version 2023-04-30 00:59
|
||||
*/
|
||||
@Data
|
||||
@RestControllerAdvice
|
||||
public class GlobalReturnHandler implements ResponseBodyAdvice<Object> {
|
||||
|
||||
@@ -77,22 +79,4 @@ public class GlobalReturnHandler implements ResponseBodyAdvice<Object> {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多语言头处理回调
|
||||
*
|
||||
* @return 处理回调
|
||||
*/
|
||||
public CallbackArgReturn<LanguageMsgMapping<?>, String> getMultilingualHeader() {
|
||||
return multilingualHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多语言头处理回调
|
||||
*
|
||||
* @param multilingualHeader 处理回调
|
||||
*/
|
||||
public void setMultilingualHeader(CallbackArgReturn<LanguageMsgMapping<?>, String> multilingualHeader) {
|
||||
this.multilingualHeader = multilingualHeader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.imyeyu.spring.util;
|
||||
|
||||
import com.imyeyu.spring.config.AbstractRedisConfig;
|
||||
import com.imyeyu.java.TimiJava;
|
||||
import com.imyeyu.java.bean.timi.TimiException;
|
||||
import com.imyeyu.spring.config.AbstractRedisConfig;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
@@ -27,30 +27,7 @@ import java.util.function.Consumer;
|
||||
* @author 夜雨
|
||||
* @version 2021-11-21 09:58
|
||||
*/
|
||||
public class Redis<K, V> {
|
||||
|
||||
private final RedisSerializer<K> serializer;
|
||||
private final RedisTemplate<K, V> redis;
|
||||
|
||||
/**
|
||||
* 创建 Redis 操作封装
|
||||
*
|
||||
* @param redis RedisTemplate 实例
|
||||
* @param serializer 键序列化器
|
||||
*/
|
||||
public Redis(RedisTemplate<K, V> redis, RedisSerializer<K> serializer) {
|
||||
this.redis = redis;
|
||||
this.serializer = serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Redis 模板对象
|
||||
*
|
||||
* @return Redis 模板对象
|
||||
*/
|
||||
public RedisTemplate<?, ?> getRedis() {
|
||||
return redis;
|
||||
}
|
||||
public record Redis<K, V>(RedisTemplate<K, V> redis, RedisSerializer<K> serializer) {
|
||||
|
||||
/**
|
||||
* 加锁
|
||||
@@ -101,8 +78,8 @@ public class Redis<K, V> {
|
||||
* @param value 值
|
||||
*/
|
||||
public void setAndKeepTTL(K key, V value) {
|
||||
Long expire = redis.getExpire(key, TimeUnit.MILLISECONDS);
|
||||
if (expire == null || expire <= 0) {
|
||||
long expire = redis.getExpire(key, TimeUnit.MILLISECONDS);
|
||||
if (expire <= 0) {
|
||||
// 判死
|
||||
destroy(key);
|
||||
} else {
|
||||
@@ -210,8 +187,8 @@ public class Redis<K, V> {
|
||||
public Map<K, List<V>> getAllList() {
|
||||
Map<K, List<V>> r = new HashMap<>();
|
||||
List<K> ks = keys("*");
|
||||
for (int i = 0; i < ks.size(); i++) {
|
||||
r.put(ks.get(i), getList(ks.get(i)));
|
||||
for (K k : ks) {
|
||||
r.put(k, getList(k));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -235,9 +212,9 @@ public class Redis<K, V> {
|
||||
*/
|
||||
public List<V> values() {
|
||||
List<V> r = new ArrayList<>();
|
||||
List<K> keys = keys("*");
|
||||
for (K key : keys) {
|
||||
r.add(get(key));
|
||||
List<K> ks = keys("*");
|
||||
for (K k : ks) {
|
||||
r.add(get(k));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -250,8 +227,8 @@ public class Redis<K, V> {
|
||||
public Map<K, V> map() {
|
||||
Map<K, V> r = new HashMap<>();
|
||||
List<K> ks = keys("*");
|
||||
for (int i = 0; i < ks.size(); i++) {
|
||||
r.put(ks.get(i), get(ks.get(i)));
|
||||
for (K k : ks) {
|
||||
r.put(k, get(k));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -280,8 +257,7 @@ public class Redis<K, V> {
|
||||
*/
|
||||
public boolean destroy(K key) {
|
||||
if (TimiJava.isNotEmpty(key) && has(key)) {
|
||||
Boolean isSucceed = redis.delete(key);
|
||||
return isSucceed != null && isSucceed;
|
||||
return redis.delete(key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ public class YamlPropertySourceFactory implements PropertySourceFactory {
|
||||
@Override
|
||||
public @org.springframework.lang.NonNull PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
|
||||
List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
|
||||
return sources.get(0);
|
||||
return sources.getFirst();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user