This commit is contained in:
2025-10-17 10:11:04 +08:00
commit 9618d5cfa1
2012 changed files with 163764 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
<?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">
<parent>
<artifactId>jeelowcode-framework</artifactId>
<groupId>com.jeelowcode</groupId>
<version>${jeelowcode.version}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeelowcode-utils</artifactId>
<name>${project.artifactId}</name>
<version>${jeelowcode.version}</version>
<packaging>jar</packaging>
<description>JeeLowCode低代码平台 - 工具类</description>
<dependencies>
<dependency>
<groupId>com.jeelowcode</groupId>
<artifactId>tool-common</artifactId>
</dependency>
<dependency>
<groupId>com.jeelowcode</groupId>
<artifactId>jeelowcode-exception</artifactId>
</dependency>
<dependency>
<groupId>com.jeelowcode</groupId>
<artifactId>jeelowcode-global</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
</dependency>
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,82 @@
package com.jeelowcode.framework.utils.adapter;
import com.jeelowcode.framework.utils.model.JeeLowCodeDept;
import com.jeelowcode.framework.utils.model.JeeLowCodeDict;
import com.jeelowcode.framework.utils.model.JeeLowCodeRole;
import com.jeelowcode.framework.utils.model.JeeLowTenant;
import com.jeelowcode.framework.utils.params.JeeLowCodeDeptParam;
import com.jeelowcode.framework.utils.params.JeeLowCodeDictParam;
import com.jeelowcode.framework.utils.params.JeeLowCodeUserParam;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 适配器 相关接口
*/
public interface IJeeLowCodeAdapter {
//获取当前在线人id
Long getOnlineUserId();
//获取当前在线人账号
String getOnlineUserName();
String getOnlineUserName(Long userId);
//获取当前在线人名称
String getOnlineUserNickName();
//获取当前在线人部门id
Long getOnlineUserDeptId();
String getOnlineUserDeptName();
//获取当前在线人id
Long getTenantId();
//是否不用租户
boolean getTenantIsIgnore();
//获取所有租户列表
List<JeeLowTenant> getTenantList();
//获取字典列表
List<JeeLowCodeDict> getDictList(JeeLowCodeDictParam param);
//获取部门列表
List<JeeLowCodeDept> getDeptList(JeeLowCodeDeptParam param);
//获取所有角色列表
List<JeeLowCodeRole> getRoleList();
List<Map<String,Object>> getUserInfoList(List<Long> userIdList);
//回显用户
List<Map<String,Object>> getUserViewList(List<Long> userIdList);
//回显部门
List<Map<String,Object>> getDeptViewList(List<Long> deptIdList);
//获取用户分页列表
Object getUserPage(Integer pageNo, Integer pageSize, JeeLowCodeUserParam param);
Object getUserPageByUserIds(Integer pageNo, Integer pageSize, List<Long> userIdList);
//初始化-新增数据默认项
void initSaveDefaultData(Map<String, Object> map);
//初始化-修改数据默认项
void initUpdateDefaultData(Map<String, Object> map);
//获取不用租户的表
Set<String> getTenantIgnoreTable();
//不用租户的url
Set<String> getTenantIgnoreUrl();
//获取是否开启租户
boolean getTenantEnable();
}

View File

@@ -0,0 +1,19 @@
package com.jeelowcode.framework.utils.adapter;
import com.jeelowcode.framework.exception.JeeLowCodeException;
import javax.servlet.http.HttpServletRequest;
/*
自定义校验
*/
public interface IJeelowCodeValidate {
/**
* 自定义校验
* @param req
* @throws JeeLowCodeException
*/
void validate(HttpServletRequest req) throws JeeLowCodeException;
}

View File

@@ -0,0 +1,15 @@
package com.jeelowcode.framework.utils.annotation;
import java.lang.annotation.*;
/**
* Api
* Aes参数解密
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiDecryptAes {
}

View File

@@ -0,0 +1,15 @@
package com.jeelowcode.framework.utils.annotation;
import java.lang.annotation.*;
/**
* Api
* Aes 返回body 加密
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiEncryptAes {
}

View File

@@ -0,0 +1,15 @@
package com.jeelowcode.framework.utils.annotation;
import java.lang.annotation.*;
/**
* 不登录可以查看dbform配置
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JeeLowCodeNoLoginViewDbForm {
}

View File

@@ -0,0 +1,26 @@
package com.jeelowcode.framework.utils.annotation;
import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;
/**
* 接口缓存
*/
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface JeelowCodeCache {
String cacheNames() default "";
long expire() default 1800L;
boolean nullIsSave() default false;//空值是否存储
TimeUnit timeUnit() default TimeUnit.SECONDS;
Class reflexClass();
boolean alwaysEffective() default false;//总是有效 现在是开发环境不开启如果是true的话开发环境也开启
}

View File

@@ -0,0 +1,23 @@
package com.jeelowcode.framework.utils.annotation;
import com.jeelowcode.framework.utils.adapter.IJeelowCodeValidate;
import java.lang.annotation.*;
/**
* 自定义校验
*/
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface JeelowCodeValidate {
String title() default "";
/**
* 校验类
* @return
*/
Class<? extends IJeelowCodeValidate>[] validateClass() default {};
}

View File

@@ -0,0 +1,57 @@
package com.jeelowcode.framework.utils.component;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.jeelowcode.framework.utils.adapter.IJeeLowCodeAdapter;
import com.jeelowcode.framework.utils.component.cache.JeelowCodeCacheAspect;
import com.jeelowcode.framework.utils.component.crypto.ApiDecryptRequestBodyAdvice;
import com.jeelowcode.framework.utils.component.crypto.ApiDecryptResponseBodyAdvice;
import com.jeelowcode.framework.utils.component.defaultval.DefaultValAspect;
import com.jeelowcode.framework.utils.component.mybatis.MapWrapperFactory;
import com.jeelowcode.framework.utils.component.properties.JeeLowCodeProperties;
import com.jeelowcode.framework.utils.component.redis.JeeLowCodeRedisUtils;
import com.jeelowcode.framework.utils.component.validate.JeelowCodeValidateAspect;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@EnableConfigurationProperties(JeeLowCodeProperties.class)
@Component
public class JeeLowCodeAutoConfiguration {
// ========== AOP ==========
@Bean
public ApiDecryptRequestBodyAdvice apiDecryptRequestBodyAdvice() {
return new ApiDecryptRequestBodyAdvice();
}
@Bean
public ApiDecryptResponseBodyAdvice apiDecryptResponseBodyAdvice() {
return new ApiDecryptResponseBodyAdvice();
}
@Bean
public JeelowCodeValidateAspect jeelowCodeValidateAspect() {
return new JeelowCodeValidateAspect();
}
//缓存相关
@Bean
public JeelowCodeCacheAspect jeelowCodeCacheAspect(JeeLowCodeRedisUtils jeeLowCodeRedisUtils) {
return new JeelowCodeCacheAspect(jeeLowCodeRedisUtils);
}
//默认值处理相关
@Bean
public DefaultValAspect defaultValAspect(IJeeLowCodeAdapter proxyAdapter) {
return new DefaultValAspect(proxyAdapter);
}
//mybatis 返回值大写转小写
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setObjectWrapperFactory(new MapWrapperFactory());
}
}

View File

@@ -0,0 +1,124 @@
package com.jeelowcode.framework.utils.component.cache;
import com.jeelowcode.framework.utils.annotation.JeelowCodeCache;
import com.jeelowcode.framework.utils.component.properties.JeeLowCodeProperties;
import com.jeelowcode.framework.utils.component.redis.JeeLowCodeRedisUtils;
import com.jeelowcode.framework.utils.constant.JeeRedisConstants;
import com.jeelowcode.framework.utils.model.global.BaseWebResult;
import com.jeelowcode.framework.utils.utils.FuncBase;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.util.ArrayList;
import java.util.List;
/**
* JeeLowCode低代码
* 缓存相关
*/
@Aspect
public class JeelowCodeCacheAspect {
private ExpressionParser parser = new SpelExpressionParser();
private final JeeLowCodeRedisUtils jeeLowCodeRedisUtils;
public JeelowCodeCacheAspect(JeeLowCodeRedisUtils jeeLowCodeRedisUtils) {
this.jeeLowCodeRedisUtils=jeeLowCodeRedisUtils;
}
@Around("@annotation(jeelowCodeCache)")
public Object aroundMethod(ProceedingJoinPoint joinPoint,JeelowCodeCache jeelowCodeCache) throws Throwable {
if (!jeelowCodeCache.alwaysEffective() && JeeLowCodeProperties.getDebug()) {//开发环境,直接跳过
return joinPoint.proceed();
}
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
boolean nullIsSave = jeelowCodeCache.nullIsSave();
StandardEvaluationContext context = new StandardEvaluationContext();
// 获取缓存key
Object[] args = joinPoint.getArgs();
String[] parameterNames = signature.getParameterNames();
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
String redisKey = JeeRedisConstants.JEELOWCODE_PREFIX + "cache:" + parser.parseExpression(jeelowCodeCache.cacheNames()).getValue(context, String.class);
if (jeeLowCodeRedisUtils.hasKey(redisKey)) {
Object cachedResultObj = jeeLowCodeRedisUtils.get(redisKey);
Class reflexClass = jeelowCodeCache.reflexClass();
try {
String cachedResultStr = String.valueOf(cachedResultObj);
if(cachedResultStr==null){
return null;
}else if(FuncBase.equals(cachedResultStr,"")){
return "";
}else if(FuncBase.equals(cachedResultStr,"[]")){
return new ArrayList<>();
}
if (FuncBase.jsonIsArray(cachedResultStr)) {//当前是jsonarray则需要转换
List list = FuncBase.json2List(cachedResultStr, reflexClass);
return list;
} else if (FuncBase.jsonIsObject(cachedResultStr)) {//当前是json则需要转换
Object obj = FuncBase.json2Bean(cachedResultStr, reflexClass);
return obj;
} else {//基本数据类型
Class<?> longClass = Long.class;
if (longClass.isAssignableFrom(reflexClass)) {//因为redis存把long存进去识别为int
return FuncBase.toLong(FuncBase.toStr(cachedResultObj));
} else {
return cachedResultObj;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 如果缓存中没有数据,则继续执行目标方法
Object result = joinPoint.proceed();
if (!nullIsSave && FuncBase.isEmpty(result)) {//只存有值部分
return result;
}
if (FuncBase.isNotEmpty(result) && (result instanceof BaseWebResult)) {//这个类型,需要成功才做缓存
BaseWebResult baseWebResult = (BaseWebResult) result;
if (baseWebResult.isSuccess()) {
// 将结果缓存
jeeLowCodeRedisUtils.set(redisKey, FuncBase.json2Str(result), jeelowCodeCache.expire(), jeelowCodeCache.timeUnit());
}
} else if (FuncBase.isNotEmpty(result) && (result instanceof Throwable)) {//异常类不做
} else {
String resultStr = FuncBase.json2Str(result);
if (FuncBase.jsonIsJson(resultStr)) {//当前是json则需要转换
jeeLowCodeRedisUtils.set(redisKey, resultStr, jeelowCodeCache.expire(), jeelowCodeCache.timeUnit());
} else {//不是json则是基本数据类型转为字符串存储
jeeLowCodeRedisUtils.set(redisKey, result, jeelowCodeCache.expire(), jeelowCodeCache.timeUnit());
}
}
return result;
}
}

View File

@@ -0,0 +1,85 @@
package com.jeelowcode.framework.utils.component.crypto;
import com.jeelowcode.framework.utils.annotation.ApiDecryptAes;
import com.jeelowcode.framework.utils.tool.AesUtil;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.NonNull;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
/**
* 参数加密
*/
@ControllerAdvice
public class ApiDecryptRequestBodyAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, @NonNull Type targetType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
return methodParameter.hasMethodAnnotation(ApiDecryptAes.class);
}
@Override
public Object handleEmptyBody(Object body, @NonNull HttpInputMessage inputMessage, @NonNull MethodParameter parameter,
@NonNull Type targetType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
@NonNull
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, @NonNull MethodParameter parameter,
@NonNull Type targetType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
ApiDecryptAes apiDecryptAes = parameter.getMethodAnnotation(ApiDecryptAes.class);
if (apiDecryptAes == null) {
return inputMessage;
}
//key
String aesKey = AesUtil.secretKey;
// 判断 body 是否为空
InputStream messageBody = inputMessage.getBody();
if (messageBody.available() <= 0) {
return inputMessage;
}
//加密字符
String bodyStr = StreamUtils.copyToString(messageBody, Charset.defaultCharset());
bodyStr=bodyStr.replaceAll("\"","");
//解密字符
byte[] decrypt = AesUtil.decryptFormBase64(bodyStr, aesKey);
InputStream inputStream = new ByteArrayInputStream(decrypt);
return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
return inputStream; // 再将输入流返回
}
@Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
};
}
@NonNull
@Override
public Object afterBodyRead(@NonNull Object body, @NonNull HttpInputMessage inputMessage, @NonNull MethodParameter parameter, @NonNull Type targetType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
}

View File

@@ -0,0 +1,83 @@
package com.jeelowcode.framework.utils.component.crypto;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jeelowcode.framework.utils.annotation.ApiEncryptAes;
import com.jeelowcode.framework.utils.tool.AesUtil;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.Iterator;
import java.util.Map;
/**
* 返回结果解密
*/
@Order
@ControllerAdvice
public class ApiDecryptResponseBodyAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, @NonNull Class converterType) {
return methodParameter.hasMethodAnnotation(ApiEncryptAes.class) ;
}
@Nullable
@Override
public Object beforeBodyWrite(Object body, @NonNull MethodParameter parameter, @NonNull MediaType selectedContentType,
@NonNull Class selectedConverterType, @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
if (body == null) {
return null;
}
ApiEncryptAes apiEncryptAes = parameter.getMethodAnnotation(ApiEncryptAes.class);
if (apiEncryptAes == null) {
return body;
}
String secretKey = AesUtil.secretKey;
JSONObject jsonObject = JSONUtil.parseObj(body);
jsonObject =long2String(jsonObject);
// String bodyStr = JSONUtil.toJsonStr(body);
response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
String result = AesUtil.encryptToBase64(jsonObject.toString(), secretKey);
return result;
}
/**
* 将JSON的long,转成String,以防止精度丢失
*/
public JSONObject long2String(JSONObject jsonObject){
Iterator iter = jsonObject.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
if(entry.getValue() instanceof JSONObject){
long2String(jsonObject.getJSONObject(entry.getKey().toString()));
}
if(entry.getValue() instanceof JSONArray){
for (int i = 0; i < ((JSONArray) entry.getValue()).size(); i++) {
long2String(((JSONArray) entry.getValue()).getJSONObject(i));
}
}
if(entry.getValue() instanceof Long){
jsonObject.set(entry.getKey().toString(),String.valueOf(entry.getValue()));
}
}
return jsonObject;
}
}

View File

@@ -0,0 +1,390 @@
package com.jeelowcode.framework.utils.component.defaultval;
import com.jeelowcode.framework.global.JeeLowCodeBaseConstant;
import com.jeelowcode.framework.utils.adapter.IJeeLowCodeAdapter;
import com.jeelowcode.framework.utils.model.global.BaseEntity;
import com.jeelowcode.framework.utils.model.global.BaseTenantEntity;
import com.jeelowcode.framework.utils.utils.FuncBase;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
/**
* 默认值切面
*/
/**
* 默认值切面
*/
@Order(value = 0)
@Component
@Aspect
public class DefaultValAspect {
private final IJeeLowCodeAdapter proxyAdapter;
public final static String MYBATIS_EXPRESSION = "execution(* "+JeeLowCodeBaseConstant.BASE_PACKAGES_CODE+"..mapper..*.*(..))";
public final static String SERVICE_EXPRESSION = "execution(* "+ JeeLowCodeBaseConstant.BASE_PACKAGES_CODE+"..service..*.*(..))";
public final static String MODULE_SERVICE_EXPRESSION = "execution(* "+ JeeLowCodeBaseConstant.BASE_PACKAGES_MODULE+"..service..*.*(..))";
public final static String MODULE_MYBATIS_EXPRESSION = "execution(* "+JeeLowCodeBaseConstant.BASE_PACKAGES_MODULE+"..mapper..*.*(..))";
//需要拦截的方法名称
private static Map<String, String> aspectMethodNameMapp = new HashMap<>();
private static String savePublicData="savePublicData";
private static String editPublicData="editPublicData";
private static String baseUpdateDataById="baseUpdateDataById";
private static String baseUpdateDataByField="baseUpdateDataByField";
private static String saveImportData="saveImportData";
private static String insert="insert";
private static String updateById="updateById";
private static String update = "update";
private static String saveBatch = "saveBatch";
private static String saveOrUpdate = "saveOrUpdate";
private static String saveOrUpdateBatch = "saveOrUpdateBatch";
static {
aspectMethodNameMapp.put(savePublicData, "新增");
aspectMethodNameMapp.put(editPublicData, "编辑数据");
aspectMethodNameMapp.put(baseUpdateDataById, "根据id编辑");
aspectMethodNameMapp.put(baseUpdateDataByField, "根据字段编辑");
aspectMethodNameMapp.put(insert, "mybatis-plus 自带新增");
aspectMethodNameMapp.put(updateById, "mybatis-plus 自带编辑");
aspectMethodNameMapp.put(update, "mybatis-plus 自带编辑");
aspectMethodNameMapp.put(saveBatch, "mybatis-plus 自带批量新增");
aspectMethodNameMapp.put(saveOrUpdate, "mybatis-plus 自带新增修改");
aspectMethodNameMapp.put(saveOrUpdateBatch, "mybatis-plus 自带批量新增修改");
}
public DefaultValAspect(IJeeLowCodeAdapter proxyAdapter) {
this.proxyAdapter = proxyAdapter;
}
@Pointcut(value = SERVICE_EXPRESSION)
private void aspectServicePlus() {
}
@Pointcut(value = MYBATIS_EXPRESSION)
private void aspectPlus() {
}
@Pointcut(value = MODULE_SERVICE_EXPRESSION)
private void aspectModelServicePlus() {
}
@Pointcut(value = MODULE_MYBATIS_EXPRESSION)
private void aspectModelMapperPlus() {
}
@Around("aspectPlus() || aspectServicePlus() || aspectModelServicePlus() || aspectModelMapperPlus()")
public Object all(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取方法名称
String methodName = methodSignature.getName();
if (!aspectMethodNameMapp.containsKey(methodName)) {//不在拦截范围内
return joinPoint.proceed();
}
Object[] args = joinPoint.getArgs();
if(FuncBase.equals(methodName,savePublicData)){
this.savePublicData(args);
}else if(FuncBase.equals(methodName,editPublicData)){
this.editPublicData(args);
}else if(FuncBase.equals(methodName,baseUpdateDataById)){
this.baseUpdateDataById(args);
}else if(FuncBase.equals(methodName,baseUpdateDataByField)){
this.baseUpdateDataByField(args);
}else if(FuncBase.equals(methodName,insert)){
this.insertPlus(args);
}else if(FuncBase.equals(methodName,updateById) || FuncBase.equals(methodName, update)){
this.updateByIdPlus(args);
} else if(FuncBase.equals(methodName, saveBatch)){
this.saveBatchPlus(args);
} else if (FuncBase.equals(methodName, saveOrUpdate)){
this.saveOrUpdatePlus(args);
} else if (FuncBase.equals(methodName, saveOrUpdateBatch)){
this.saveOrUpdateBatchPlus(args);
}
return joinPoint.proceed();
}
//新增
private void savePublicData(Object[] args) throws Throwable {
Map<String, Object> addDataMap = (Map<String, Object>) args[1];
//处理默认值
this.initAddMap(addDataMap);
}
//plus新增
private void insertPlus(Object[] args) throws Throwable {
Object obj = (Object) args[0];
if (!(obj instanceof BaseEntity || obj instanceof BaseTenantEntity)) {//不属于我们的类型
return;
}
LocalDateTime current = LocalDateTime.now();
Long userId = proxyAdapter.getOnlineUserId();
Long tenantId = proxyAdapter.getTenantId();
Long deptId = proxyAdapter.getOnlineUserDeptId();
//基本类
if (obj instanceof BaseEntity) {//我们自定义的实体
BaseEntity baseEntity = (BaseEntity) obj;
Long createUser = baseEntity.getCreateUser();
Long createDept = baseEntity.getCreateDept();
if (FuncBase.isNotEmpty(current)) {
baseEntity.setCreateTime(current);
}
if (FuncBase.isNotEmpty(userId) && FuncBase.isEmpty(createUser)) {
baseEntity.setCreateUser(userId);
}
if (FuncBase.isNotEmpty(deptId) && FuncBase.isEmpty(createDept)) {
baseEntity.setCreateDept(deptId);
}
}
if (obj instanceof BaseTenantEntity) {//我们自定义的实体
BaseTenantEntity baseEntity = (BaseTenantEntity) obj;
Long selectTenantId = baseEntity.getTenantId();
if (FuncBase.isEmpty(selectTenantId) && FuncBase.isNotEmpty(tenantId)) {
baseEntity.setTenantId(tenantId);
}
}
}
// plus批量新增
private void saveBatchPlus(Object[] args) {
List list = (List) args[0];
Object o = list.get(0);
if (!(o instanceof BaseEntity || o instanceof BaseTenantEntity)) {//不属于我们的类型
return;
}
LocalDateTime current = LocalDateTime.now();
Long userId = proxyAdapter.getOnlineUserId();
Long tenantId = proxyAdapter.getTenantId();
Long deptId = proxyAdapter.getOnlineUserDeptId();
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> list.parallelStream().forEach(obj -> {
//基本类
if (obj instanceof BaseEntity) {//我们自定义的实体
BaseEntity baseEntity = (BaseEntity) obj;
Long createUser = baseEntity.getCreateUser();
Long createDept = baseEntity.getCreateDept();
if (FuncBase.isNotEmpty(current)) {
baseEntity.setCreateTime(current);
}
if (FuncBase.isNotEmpty(userId) && FuncBase.isEmpty(createUser)) {
baseEntity.setCreateUser(userId);
}
if (FuncBase.isNotEmpty(deptId) && FuncBase.isEmpty(createDept)) {
baseEntity.setCreateDept(deptId);
}
}
if (obj instanceof BaseTenantEntity) {//我们自定义的实体
BaseTenantEntity baseEntity = (BaseTenantEntity) obj;
Long selectTenantId = baseEntity.getTenantId();
if (FuncBase.isEmpty(selectTenantId) && FuncBase.isNotEmpty(tenantId)) {
baseEntity.setTenantId(tenantId);
}
}
})).get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (pool != null) {
pool.shutdown();
}
}
}
// plus新增修改
private void saveOrUpdatePlus(Object[] args) throws Throwable {
Object obj = (Object) args[0];
if (!(obj instanceof BaseEntity || obj instanceof BaseTenantEntity)) {//不属于我们的类型
return;
}
LocalDateTime current = LocalDateTime.now();
Long userId = proxyAdapter.getOnlineUserId();
Long tenantId = proxyAdapter.getTenantId();
Long deptId = proxyAdapter.getOnlineUserDeptId();
//基本类
if (obj instanceof BaseEntity) {//我们自定义的实体
BaseEntity baseEntity = (BaseEntity) obj;
if (FuncBase.isEmpty(baseEntity.getId())) {
Long createUser = baseEntity.getCreateUser();
Long createDept = baseEntity.getCreateDept();
if (FuncBase.isNotEmpty(current)) {
baseEntity.setCreateTime(current);
}
if (FuncBase.isNotEmpty(userId) && FuncBase.isEmpty(createUser)) {
baseEntity.setCreateUser(userId);
}
if (FuncBase.isNotEmpty(deptId) && FuncBase.isEmpty(createDept)) {
baseEntity.setCreateDept(deptId);
}
} else {
baseEntity.setUpdateTime(current);
if (FuncBase.isEmpty(baseEntity.getUpdateUser()) && FuncBase.isNotEmpty(userId)) {
baseEntity.setUpdateUser(userId);
}
}
}
if (obj instanceof BaseTenantEntity) {//我们自定义的实体
BaseTenantEntity baseEntity = (BaseTenantEntity) obj;
if (FuncBase.isNotEmpty(baseEntity.getId())){
return;
}
Long selectTenantId = baseEntity.getTenantId();
if (FuncBase.isEmpty(selectTenantId) && FuncBase.isNotEmpty(tenantId)) {
baseEntity.setTenantId(tenantId);
}
}
}
// plus批量新增修改
private void saveOrUpdateBatchPlus(Object[] args) {
List list = (List) args[0];
Object o = list.get(0);
if (!(o instanceof BaseEntity || o instanceof BaseTenantEntity)) {//不属于我们的类型
return;
}
LocalDateTime current = LocalDateTime.now();
Long userId = proxyAdapter.getOnlineUserId();
Long tenantId = proxyAdapter.getTenantId();
Long deptId = proxyAdapter.getOnlineUserDeptId();
ForkJoinPool pool = null;
try {
pool = FuncBase.jeelowcodeForkJoinPool();
pool.submit(() -> list.parallelStream().forEach(obj -> {
//基本类
if (obj instanceof BaseEntity) {//我们自定义的实体
BaseEntity baseEntity = (BaseEntity) obj;
if (FuncBase.isEmpty(baseEntity.getId())) {
Long createUser = baseEntity.getCreateUser();
Long createDept = baseEntity.getCreateDept();
if (FuncBase.isNotEmpty(current)) {
baseEntity.setCreateTime(current);
}
if (FuncBase.isNotEmpty(userId) && FuncBase.isEmpty(createUser)) {
baseEntity.setCreateUser(userId);
}
if (FuncBase.isNotEmpty(deptId) && FuncBase.isEmpty(createDept)) {
baseEntity.setCreateDept(deptId);
}
} else {
baseEntity.setUpdateTime(current);
if (FuncBase.isEmpty(baseEntity.getUpdateUser()) && FuncBase.isNotEmpty(userId)) {
baseEntity.setUpdateUser(userId);
}
}
}
if (obj instanceof BaseTenantEntity) {//我们自定义的实体
BaseTenantEntity baseEntity = (BaseTenantEntity) obj;
if (FuncBase.isNotEmpty(baseEntity.getId())){
return;
}
Long selectTenantId = baseEntity.getTenantId();
if (FuncBase.isEmpty(selectTenantId) && FuncBase.isNotEmpty(tenantId)) {
baseEntity.setTenantId(tenantId);
}
}
})).get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (pool != null) {
pool.shutdown();
}
}
}
//编辑
private void editPublicData(Object[] args) throws Throwable {
Map<String, Object> updateDataMap = (Map<String, Object>) args[2];
this.initUpdateMap(updateDataMap);//初始化默认值
}
//编辑
private void baseUpdateDataById(Object[] args) throws Throwable {
Map<String, Object> updateDataMap = (Map<String, Object>) args[1];
this.initUpdateMap(updateDataMap);//初始化默认值
}
//编辑
private void baseUpdateDataByField(Object[] args) throws Throwable {
Map<String, Object> updateDataMap = (Map<String, Object>) args[1];
this.initUpdateMap(updateDataMap);//初始化默认值
}
private void initAddMap(Map<String, Object> updateDataMap) {
if (FuncBase.isEmpty(updateDataMap)) {
updateDataMap = new HashMap<>();
}
proxyAdapter.initSaveDefaultData(updateDataMap);
}
private void initUpdateMap(Map<String, Object> updateDataMap) {
if (FuncBase.isEmpty(updateDataMap)) {
updateDataMap = new HashMap<>();
}
proxyAdapter.initUpdateDefaultData(updateDataMap);
}
//plus 根据id来修改
private void updateByIdPlus(Object[] args) throws Throwable {
LocalDateTime current = LocalDateTime.now();
Object obj = (Object) args[0];
if (!(obj instanceof BaseEntity)) {//不属于我们的
return;
}
Long userId = proxyAdapter.getOnlineUserId();
BaseEntity baseEntity = (BaseEntity) obj;
Long updateUser = baseEntity.getUpdateUser();
baseEntity.setUpdateTime(current);
if (FuncBase.isEmpty(updateUser) && FuncBase.isNotEmpty(userId)) {
baseEntity.setUpdateUser(userId);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.jeelowcode.framework.utils.component.mybatis;
import com.jeelowcode.framework.utils.utils.FuncBase;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;
import java.util.Map;
public class CustomWrapper extends MapWrapper {
public CustomWrapper(MetaObject metaObject, Map<String, Object> map) {
super(metaObject, map);
}
@Override
public String findProperty(String name, boolean useCamelCaseMapping) {
if(FuncBase.isEmpty(name)){
return name;
}
String nameUpper = name.toUpperCase();
if(FuncBase.equals(name,nameUpper)){//将全大写转为小写
return name.toLowerCase();
}
return name;
}
}

View File

@@ -0,0 +1,23 @@
package com.jeelowcode.framework.utils.component.mybatis;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import java.util.Map;
public class MapWrapperFactory implements ObjectWrapperFactory {
@Override
public boolean hasWrapperFor(Object object) {
return object instanceof Map;
}
@Override
public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
return new CustomWrapper(metaObject, (Map) object);
}
}

View File

@@ -0,0 +1,36 @@
package com.jeelowcode.framework.utils.component.pool;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class SyncPoolConfiguration {
@Bean(name = "asyncPoolTaskExecutor")
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//核心线程数
taskExecutor.setCorePoolSize(5);
//异步方法内部线程名称
taskExecutor.setThreadNamePrefix("jeelowcode-async-");
/**
* 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize如果还有任务到来就会采取任务拒绝策略
* 通常有以下四种策略:
* ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
* ThreadPoolExecutor.DiscardPolicy也是丢弃任务但是不抛出异常。
* ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务然后重新尝试执行任务重复此过程
* ThreadPoolExecutor.CallerRunsPolicy重试添加当前的任务自动重复调用 execute() 方法,直到成功
*/
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.initialize();
return taskExecutor;
}
}

View File

@@ -0,0 +1,63 @@
package com.jeelowcode.framework.utils.component.properties;
import com.jeelowcode.framework.utils.tool.AesUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 低代码参数
*/
@ConfigurationProperties(prefix = "jeelowcode")
public class JeeLowCodeProperties {
//排除表名
private static List<String> excludeTableNames;
private static boolean debug;
//aes加解密key
private static String aesKey;
//JAVA增强生成文件地址
private static String enhancePath="jeelowcode-module\\jeelowcode-module-biz\\src\\main\\java\\com\\jeelowcode\\module\\biz\\enhance";
//---------------------------------------------------------------------------
public static List<String> getExcludeTableNames() {
return excludeTableNames;
}
public void setExcludeTableNames(List<String> excludeTableNames) {
JeeLowCodeProperties.excludeTableNames = excludeTableNames;
}
public static boolean getDebug() {
return debug;
}
public void setDebug(boolean debug) {
JeeLowCodeProperties.debug = debug;
}
public static String getAesKey() {
return aesKey;
}
public void setAesKey(String aesKey) {
AesUtil.secretKey=aesKey;//赋值
JeeLowCodeProperties.aesKey = aesKey;
}
public static String getEnhancePath() {
return enhancePath;
}
public void setEnhancePath(String enhancePath) {
JeeLowCodeProperties.enhancePath = enhancePath;
}
}

View File

@@ -0,0 +1,74 @@
package com.jeelowcode.framework.utils.component.redis;
/**
* @author JX
* @create 2024-03-05 11:29
* @dedescription:
*/
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.text.SimpleDateFormat;
/**
* @author vinjcent
* 配置redis序列化json
*/
@Configuration
public class JeeLowCodeRedisConfiguration {
@Bean
/**
* 若有相同类型的Bean时,优先使用此注解标注的Bean
*/
@Primary
public RedisTemplate<String, Object> jeeLowCodeRedisTemplatessss(RedisConnectionFactory redisConnectionFactory) {
// 为了开发方便,一般直接使用<String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 配置具体的序列化方式
// JSON解析任意对象
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会抛出异常
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
// 设置日期格式
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
jackson2JsonRedisSerializer.setObjectMapper(om);
// String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化
template.setHashKeySerializer(stringRedisSerializer);
// value的序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
// 设置所有配置
template.afterPropertiesSet();
return template;
}
}

View File

@@ -0,0 +1,156 @@
package com.jeelowcode.framework.utils.component.redis;
/**
* @author JX
* @create 2024-03-05 11:42
* @dedescription:
*/
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Map;
public class JeeLowCodeRedisJsonUtils {
public static final ObjectMapper OBJ_MAPPER = new ObjectMapper();
/**
* 普通对象之间类型的转化
*
* @param source 原对象
* @param target 目标类型
* @param <T> 目标参数类型
* @return object after transformation
*/
public static <T> T objParse(Object source, Class<T> target) {
try {
if (source.getClass().equals(target)) {
return OBJ_MAPPER.convertValue(source, target);
}
} catch (Exception ignored) {
}
return null;
}
/**
* 普通列表之间类型的转化
*
* @param source 原列表
* @param target 目标列表类型
* @param <T> 目标列表参数类型
* @return list after transformation
*/
public static <S, T> List<T> listParse(List<S> source, Class<T> target) {
try {
return OBJ_MAPPER.convertValue(source, OBJ_MAPPER.getTypeFactory().constructCollectionType(List.class, target));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 普通哈希列表之间类型的转化
*
* @param source 原哈希列表
* @param keyType 键类型
* @param valueType 值类型
* @param <SK> 原键类型
* @param <SV> 原值类型
* @param <TK> 目标键类型
* @param <TV> 目标值类型
* @return map after transformation
*/
public static <SK, SV, TK, TV> Map<TK, TV> mapParse(Map<SK, SV> source, Class<TK> keyType, Class<TV> valueType) {
try {
return OBJ_MAPPER.convertValue(source, OBJ_MAPPER.getTypeFactory().constructMapType(Map.class, keyType, valueType));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将对象转换成json字符串(序列化)
*
* @param obj 原对象
* @return string after serialized object
*/
public static String objToJson(Object obj) {
if (obj == null) {
return null;
}
try {
return OBJ_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return "";
}
/**
* 将json转化为对象(反序列化)
*
* @param source 原对象json
* @param target 目标类型
* @param <T> 目标类参数类型
* @return deserialized object
*/
public static <T> T jsonToObj(String source, Class<T> target) {
OBJ_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
return OBJ_MAPPER.readValue(source, target);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将列表json转化为对象集合
*
* @param source 原对象json
* @param target 目标类型
* @param <T> 目标类参数类型
* @return deserialized object collection
*/
public static <T> List<T> jsonToList(String source, Class<T> target) {
try {
return OBJ_MAPPER.readValue(source, OBJ_MAPPER.getTypeFactory().constructCollectionType(List.class, target));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将哈希表json转化为对象集合
*
* @param source 原对象json
* @param keyType 键类型
* @param valueType 值类型
* @param <K> 键参数类型
* @param <V> 值参数类型
* @return deserialized map collection
*/
public static <K, V> Map<K, V> jsonToMap(String source, Class<K> keyType, Class<V> valueType) {
try {
return OBJ_MAPPER.readValue(source, OBJ_MAPPER.getTypeFactory().constructMapType(Map.class, keyType, valueType));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,806 @@
package com.jeelowcode.framework.utils.component.redis;
/**
* @author JX
* @create 2024-03-05 11:38
* @dedescription:
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public final class JeeLowCodeRedisUtils {
private final RedisTemplate<String, Object> jeeLowCodeRedisTemplate;
/**
* 可按自己需求生成"起始时间戳"
*/
private static final long BEGIN_TIMESTAMP = 1640995200L;
/**
* 用于时间戳左移32位
*/
public static final int MOVE_BITS = 32;
@Autowired
public JeeLowCodeRedisUtils(RedisTemplate<String, Object> jeeLowCodeRedisTemplate) {
this.jeeLowCodeRedisTemplate = jeeLowCodeRedisTemplate;
}
//=============================common===================================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return whether the key has expired
*/
public boolean expire(String key, long time){
try {
if(time > 0){
jeeLowCodeRedisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 指定缓存失效时间(自定义时间单位)
* @param key 键
* @param time 时间(秒)
* @return whether the key has expired
*/
public boolean expire(String key, long time, TimeUnit unit){
try {
if(time > 0){
jeeLowCodeRedisTemplate.expire(key, time, unit);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key获取过期时间(默认获取的是秒单位)
* @param key 键(不能为null)
* @return the remaining time, "0" means never expire
*/
public long getExpire(String key){
Long time = jeeLowCodeRedisTemplate.getExpire(key, TimeUnit.SECONDS);
if (time != null) {
return time;
}
return -1L;
}
/**
* 根据key获取过期时间(自定义时间单位)
* @param key 键(不能为null)
* @return the remaining time, "0" means never expire
*/
public long getExpire(String key, TimeUnit unit){
Long time = jeeLowCodeRedisTemplate.getExpire(key, unit);
if (time != null) {
return time;
}
return -1L;
}
/**
* 判断key是否存在
* @param key 键
* @return whether the key exist
*/
public boolean hasKey(String key) {
Boolean flag = jeeLowCodeRedisTemplate.hasKey(key);
try {
return Boolean.TRUE.equals(flag);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 键,可以传递一个值或多个
*/
public void del(String... key) {
if(key != null && key.length > 0){
if (key.length == 1){
jeeLowCodeRedisTemplate.delete(key[0]);
}else {
jeeLowCodeRedisTemplate.delete(Arrays.asList(key));
}
}
}
/**
* 删除缓存
* @param keyList 键,可以传递一个值或多个
*/
public void delList(Set<String> keyList) {
jeeLowCodeRedisTemplate.delete(keyList);
}
//=============================String===================================
/**
* 普通缓存获取(泛型)
* @param key key键
* @return the value corresponding the key
*/
public Object get(String key){ return key == null ? null : jeeLowCodeRedisTemplate.opsForValue().get(key);}
/**
* 普通缓存获取(泛型)
* @param key key键
* @return the value corresponding the key
* @param targetType 目标类型
* @param <T> 目标类型参数
* @return the generic value corresponding the key
*/
public <T> T get(String key, Class<T> targetType){ return key == null ? null : JeeLowCodeRedisJsonUtils.objParse(jeeLowCodeRedisTemplate.opsForValue().get(key), targetType);}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return whether true or false
*/
public boolean set(String key, Object value){
try {
jeeLowCodeRedisTemplate.opsForValue().set(key,value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) --- time要大于0,如果time小于0,将设置为无期限
* @return whether true or false
*/
public boolean set(String key, Object value, long time){
try {
if(time > 0){
TimeUnit seconds = TimeUnit.SECONDS;
jeeLowCodeRedisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
}else {
set(key,value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间和时间单位
* @param key 键
* @param value 值
* @param time 时间(秒) --- time要大于0,如果time小于0,将设置为无期限
* @param timeUnit 时间单位
* @return whether true or false
*/
public boolean set(String key, Object value, long time, TimeUnit timeUnit){
try {
if(time > 0){
jeeLowCodeRedisTemplate.opsForValue().set(key, value, time, timeUnit);
}else {
set(key,value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
* @return the value after increment
*/
public long incr(String key, long delta){
if(delta < 0){
throw new RuntimeException("递增因子必须大于0");
}
Long increment = jeeLowCodeRedisTemplate.opsForValue().increment(key, delta);
return increment != null ? increment : 0L;
}
/**
* 递减
* @param key 键
* @param delta 要增加几(小于0)
* @return the value after decrement
*/
public long decr(String key, long delta){
if(delta < 0){
throw new RuntimeException("递减因子必须大于0");
}
Long increment = jeeLowCodeRedisTemplate.opsForValue().increment(key, delta);
return increment != null ? increment : 0L; }
//=============================Map===================================
/**
* 根据hashKey获取hash列表有多少元素
* @param key 键(hashKey)
* @return the size of map
*/
public long hsize(String key) {
try {
return jeeLowCodeRedisTemplate.opsForHash().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* HashGet 根据"项 中的 键 获取列表"
* @param key 键(hashKey)能为null
* @param item 项不能为null
* @return the value of the corresponding key
*/
public Object hget(String key, String item){ return jeeLowCodeRedisTemplate.opsForHash().get(key, item);}
/**
* 获取HashKey对应的所有键值
* @param key 键(hashKey)
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) { return jeeLowCodeRedisTemplate.opsForHash().entries(key);}
/**
* 获取HashKey对应的所有键值
* @param key 键(hashKey)
* @param keyType 键类型
* @param valueType 值类型
* @param <K> 键类型参数
* @param <V> 值类型参数
* @return a map
*/
public <K, V> Map<K, V> hmget(String key, Class<K> keyType, Class<V> valueType) {
return JeeLowCodeRedisJsonUtils.mapParse(jeeLowCodeRedisTemplate.opsForHash().entries(key), keyType, valueType);}
/**
* HashSet 存入多个键值对
* @param key 键(hashKey)
* @param map map 对应多个键值对
*/
public void hmset(String key, Map<String, Object> map) {
try {
jeeLowCodeRedisTemplate.opsForHash().putAll(key,map);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* HashSet存入并设置时间
* @param key 键(hashKey)
* @param map 对应多个键值
* @param time 时间(秒)
* @return whether true or false
*/
public boolean hmset(String key, Map<String, Object> map, long time){
try {
jeeLowCodeRedisTemplate.opsForHash().putAll(key,map);
if (time > 0){
expire(key,time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键(hashKey)
* @param item 项
* @param value 值
* @return whether true or false
*/
public boolean hset(String key, String item, Object value){
try {
jeeLowCodeRedisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建,并设置有效时间
* @param key 键(hashKey)
* @param item 项
* @param value 值
* @param time 时间(秒) 注意: 如果已经在hash表有时间,这里将会替换所有的时间
* @return whether true or false
*/
public boolean hset(String key, String item, Object value, long time){
try {
jeeLowCodeRedisTemplate.opsForHash().put(key, item, value);
if (time > 0){
expire(key,time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 放入map集合数据,如果不存在将创建
* @param key 键(hashKey)
* @param value map集合
* @param <K> map集合键参数类型
* @param <V> map集合值参数类型
* @return whether true or false
*/
public <K, V> boolean hsetMap(String key, Map<K, V> value) {
try {
jeeLowCodeRedisTemplate.opsForHash().putAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取key对应的所有map键值对
* @param key 键(hashKey)
* @return the Map
*/
public Map<Object, Object> hgetMap(String key) {
try {
return jeeLowCodeRedisTemplate.opsForHash().entries(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取key对应的所有map键值对(泛型)
* @param key 键(hashKey)
* @param keyType 键类型
* @param valueType 值类型
* @param <K> 键类型参数
* @param <V> 值类型参数
* @return the Map
*/
public <K, V> Map<K, V> hgetMap(String key, Class<K> keyType, Class<V> valueType) {
try {
return JeeLowCodeRedisJsonUtils.mapParse(jeeLowCodeRedisTemplate.opsForHash().entries(key), keyType, valueType);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 删除hash表中的值
* @param key 键(hashKey) 不能为null
* @param item 项可以是多个 不能为null
*/
public void hdel(String key, Object... item){
jeeLowCodeRedisTemplate.opsForHash().delete(key,item);
}
/**
* 判断hash表是否有该项的值
* @param key 键(hashKey)不能为null
* @param item 项不能为null
* @return whether true or false
*/
public boolean hHasKey(String key, String item){
return jeeLowCodeRedisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增,如果不存在,就会创建一个,并把新增后的值返回
* @param key 键(hashKey)
* @param item 项
* @param by 要增加几(大于0)
* @return the value of the corresponding key after increment in one Map
*/
public double hincr(String key, String item, double by){
return jeeLowCodeRedisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
* @param key 键(hashKey)
* @param item 项
* @param by 要减少几(小于0)
* @return the value of the corresponding key after decrement in one Map
*/
public double hdecr(String key, String item, double by){
return jeeLowCodeRedisTemplate.opsForHash().increment(key, item, -by);
}
//=============================Set===================================
/**
* 根据key获取Set中的所有值
* @param key 键
* @return all values in one Set
*/
public Set<Object> sGet(String key){
try {
return jeeLowCodeRedisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个Set集合中查询一个值,是否存在
* @param key 键
* @param value 值
* @return whether true or false
*/
public boolean sHasKey(String key, Object value){
try {
Boolean flag = jeeLowCodeRedisTemplate.opsForSet().isMember(key, value);
return Boolean.TRUE.equals(flag);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
* @param key 键
* @param values 值
* @return the number of adding successfully
*/
public long sSet(String key, Object... values){
try {
Long nums = jeeLowCodeRedisTemplate.opsForSet().add(key, values);
return nums != null ? nums : 0L;
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 将set数据放入缓存,并设置有效时间
* @param key 键
* @param time 时间(秒)
* @param values 值,可以是多个
* @return the number of adding successfully
*/
public long sSetAndTime(String key, long time, Object... values){
try {
Long count = jeeLowCodeRedisTemplate.opsForSet().add(key, values);
if(time > 0){
expire(key, time);
}
return count != null ? count : 0L;
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 获取set缓存的长度
* @param key 键
* @return the size of the Set
*/
public long sGetSetSize(String key){
try {
Long size = jeeLowCodeRedisTemplate.opsForSet().size(key);
return size != null ? size : 0L;
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 移除值为values的
* @param key 键
* @param values 值(可以是多个)
* @return the number of removal
*/
public long setRemove(String key, Object... values){
try {
Long nums = jeeLowCodeRedisTemplate.opsForSet().remove(key, values);
return nums != null ? nums : 0L;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//=============================List===================================
/**
* 获取list列表数据
* @param key 键
* @return all values of one List
*/
public List<Object> lget(String key) {
try {
return jeeLowCodeRedisTemplate.opsForList().range(key, 0, -1);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
/**
* 获取list列表数据(泛型)
* @param key 键
* @param targetType 目标类型
* @param <T> 目标类型参数
* @return all values of one List
*/
public <T> List<T> lget(String key, Class<T> targetType) {
try {
return JeeLowCodeRedisJsonUtils.listParse(jeeLowCodeRedisTemplate.opsForList().range(key, 0, -1), targetType);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
* @param key 键
* @return the length of the List
*/
public long lGetListSize(String key){
try {
Long size = jeeLowCodeRedisTemplate.opsForList().size(key);
return size != null ? size : 0L;
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
/**
* 通过索引获取list中的值
* @param key 键
* @param index 索引 index >= 0 时, 0:表头, 1:第二个元素,以此类推... index < 0 时, -1:表尾, -2:倒数第二个元素,以此类推
* @return the value of the specified index in one List
*/
public Object lgetIndex(String key, long index){
try {
return jeeLowCodeRedisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 通过索引获取list中的值(泛型)
* @param key 键
* @param index 索引 index >= 0 时, 0:表头, 1:第二个元素,以此类推... index < 0 时, -1:表尾, -2:倒数第二个元素,以此类推
* @return the value of the specified index in one List
* @param targetType 目标类型
* @param <T> 目标类型参数
* @return the generic value of the specified index in one List
*/
public <T> T lgetIndex(String key, long index, Class<T> targetType) {
try {
return JeeLowCodeRedisJsonUtils.objParse(jeeLowCodeRedisTemplate.opsForList().index(key, index), targetType);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return whether true or false
*/
public boolean lSet(String key, Object value){
try {
jeeLowCodeRedisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return whether true or false
*/
public boolean lSet(String key, Object value, long time){
try {
jeeLowCodeRedisTemplate.opsForList().rightPush(key, value);
if (time > 0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list集合放入缓存
* @param key 键
* @param values 值
* @return whether true or false
*/
public <T> boolean lSet(String key, List<T> values){
try {
Long nums = jeeLowCodeRedisTemplate.opsForList().rightPushAll(key, values);
return nums != null;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list集合放入缓存,并设置有效时间
* @param key 键
* @param values 值
* @param time 时间(秒)
* @return whether true or false
*/
public boolean lSet(String key, List<Object> values, long time){
try {
jeeLowCodeRedisTemplate.opsForList().rightPushAll(key, values);
if (time > 0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
* @param key 键
* @param value 值
* @param index 索引
* @return whether true or false
*/
public boolean lUpdateIndex(String key, Object value, long index){
try {
jeeLowCodeRedisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
* @param key 键
* @param value 值
* @param number 移除多少个
* @return 返回移除的个数
*/
public long lRemove(String key, Object value, long number){
try {
Long count = jeeLowCodeRedisTemplate.opsForList().remove(key, number, value);
return count != null ? count : 0L;
} catch (Exception e) {
e.printStackTrace();
return 0L;
}
}
//=============================Lock===================================
/**
* 解决缓存加锁问题
* @param key 锁名称
* @param value 锁值
* @param timeout 超时时间
* @param unit 时间单位
* @param <T> 锁值的数据类型
* @return 返回加锁成功状态
*/
public <T> boolean tryLock(String key, T value, long timeout, TimeUnit unit) {
Boolean flag = jeeLowCodeRedisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
return Boolean.TRUE.equals(flag);
}
/**
* 解决缓存解锁操作
* @param key 锁名称
* @return 返回解锁成功状态
*/
public boolean unLock(String key) {
Boolean flag = jeeLowCodeRedisTemplate.delete(key);
return Boolean.TRUE.equals(flag);
}
/**
* 全局生成唯一ID策略
* 设计: 符号位(1位) - 时间戳(32位) - 序列号(31位)
* @param keyPrefix key的前缀
* @return 返回唯一ID
*/
public long globalUniqueKey(String keyPrefix) {
// 1. 生成时间戳
LocalDateTime now = LocalDateTime.now();
// 东八区时间
long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
// 相减获取时间戳
long timestamp = nowSecond - BEGIN_TIMESTAMP;
// 2. 生成序列号(使用日期作为redis自增长超2^64限制,灵活使用年、月、日来存储)
// 获取当天日期
String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
// 自增长
Long increment = jeeLowCodeRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
long count = increment != null ? increment : 0L;
// 3. 拼接并返回(使用二进制或运算)
return timestamp << MOVE_BITS | count;
}
public Set<String> keys(String prefix){
return jeeLowCodeRedisTemplate.opsForValue().getOperations().keys(prefix + "*");
}
}

View File

@@ -0,0 +1,37 @@
package com.jeelowcode.framework.utils.component.validate;
import com.jeelowcode.framework.utils.adapter.IJeelowCodeValidate;
import com.jeelowcode.framework.utils.annotation.JeelowCodeValidate;
import com.jeelowcode.framework.utils.tool.spring.SpringUtils;
import com.jeelowcode.framework.utils.utils.FuncWebBase;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.http.HttpServletRequest;
/**
* 自定义校验
*/
@Aspect
@Component
public class JeelowCodeValidateAspect {
@Around("@annotation(jeelowCodeValidate)")
public Object aroundMethod(ProceedingJoinPoint joinPoint,JeelowCodeValidate jeelowCodeValidate) throws Throwable {
HttpServletRequest request = FuncWebBase.getRequest();
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
Class<? extends IJeelowCodeValidate>[] validateClassList = jeelowCodeValidate.validateClass();
for (Class<? extends IJeelowCodeValidate> myclass : validateClassList) {
IJeelowCodeValidate bean = SpringUtils.getBean(myclass);
bean.validate(requestWrapper);
}
return joinPoint.proceed();
}
}

View File

@@ -0,0 +1,29 @@
package com.jeelowcode.framework.utils.constant;
/**
* 增强相关
*/
public interface EnhanceConstant {
String ENHANCE_ADD = "add";//新增
String ENHANCE_EDIT = "edit";//修改
String ENHANCE_DELETE = "delete";//删除
String ENHANCE_IMPORT = "import";//导入
String ENHANCE_EXPORT = "export";//导出
String ENHANCE_LIST = "list";//查询
String ENHANCE_DETAIL = "detail";//详情
String ENHANCE_SUMMARY = "summary";//统计
String ENHANCE_PAGE = "page"; //分页
String ENHANCE_TYPE_SPRING = "spring";
String ENHANCE_TYPE_CLASS = "class";
String ENHANCE_TYPE_HTTP = "http";
String ENHANCE_TYPE_ONLINE_EDIT = "online_edit";
String ENHANCE_EVENT_START = "start";//开始
String ENHANCE_EVENT_END = "end";//结束
}

View File

@@ -0,0 +1,58 @@
package com.jeelowcode.framework.utils.constant;
/**
* 系统常量
*/
public interface JeeLowCodeConstant {
String JEELOWCODE_SUMMARY_TABLE="#{jeelowcode_summary_table}";
//强制同步数据库
String SYNC_DB_FORCE = "force";
String IMPORT_DUPLICATE_TYPE="jeelowcode_import_duplicate_type";//导入去重类型
String IMPORT_DUPLICATE_FIELD="jeelowcode_import_duplicate_field";//导入去重字段列表
//历史数据类型
String HISTORY_DESFORM="desform";
String HISTORY_JS="js";
String HISTORY_SQL="sql";
String HISTORY_JAVA="java";
//Postgresql数据库 模式
String POSTGRESQL_SCHEMA=".public";
//默认别名
String TABLE_ALIAS="tbl";
//Excel导入序号
String EXCEL_IMPORT_STEP="jeelowcode_excel_import_step";
String EXCEL_IMPORT_ID="jeelowcode_excel_import_id";
String BACK_SLASH = "\\";
String DOT = ".";
String SPACE = " ";
String EMPTY = "";
// \src\main\java\
String PROGRAM_DIR = "\\src\\main\\java\\";
// \target\classes
String CLASSES_DIR = "\\target\\classes";
// .java
String JAVA_SUFFIX = ".java";
String USER_DIR = System.getProperty("user.dir");
//不分页
Integer NOT_PAGE=-999;
// 本地开发环境
String APPLICATION_LOCAL = "local";
}

View File

@@ -0,0 +1,26 @@
package com.jeelowcode.framework.utils.constant;
/**
* @author JX
* @create 2024-03-06 10:20
* @dedescription:
*/
public interface JeeRedisConstants {
//低代码
String JEELOWCODE_PREFIX = "JEE_LOW_CODE:";
String JEELOWCODE_DBFORM=JEELOWCODE_PREFIX+":DBFORM";
//js增强加锁
String ENHANCE_JS_LOCK = "LOCK_JS:%s";
//js增强加锁
String ENHANCE_TAB_JS_LOCK = "LOCK_TAB_JS:%s";
//表单设计加锁
String ENHANCE_DESFORM_LOCK = "LOCK_DESSORM:%s";
String I18N_HISTORY=JEELOWCODE_PREFIX+":I18N";
}

View File

@@ -0,0 +1,48 @@
package com.jeelowcode.framework.utils.enums;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.Arrays;
import java.util.Optional;
/**
* 表单开发-认证类型
*/
public enum AuthTypeEnum {
authOpen("authOpen", "不登录可查询"),
authFalse("authFalse", "需要登录"),
authTrue("authTrue", "需要登录和鉴权")
;
private final String type;
private final String name;
public String getType() {
return type;
}
public String getName() {
return name;
}
AuthTypeEnum(String type, String name) {
this.type = type;
this.name = name;
}
public static AuthTypeEnum getByType(String type) {
// 使用流来查找匹配的
Optional<AuthTypeEnum> matchingEnum = Arrays.stream(AuthTypeEnum.values())
.filter(dbFormTypeEnum -> FuncBase.equals(dbFormTypeEnum.getType(), type))
.findFirst(); // findFirst()会返回第一个匹配的元素或者如果找不到则返回一个空的Optional
// 检查是否找到了匹配的枚举项
if (matchingEnum.isPresent()) {
return matchingEnum.get();
}
return null;
}
}

View File

@@ -0,0 +1,46 @@
package com.jeelowcode.framework.utils.enums;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.Arrays;
import java.util.Optional;
/**
* 表单开发-认证类型
*/
public enum DataConfigEnum {
DATA_AUTH("dataAuth", "数据权限"),
;
private final String type;
private final String name;
public String getType() {
return type;
}
public String getName() {
return name;
}
DataConfigEnum(String type, String name) {
this.type = type;
this.name = name;
}
public static DataConfigEnum getByType(String type) {
// 使用流来查找匹配的
Optional<DataConfigEnum> matchingEnum = Arrays.stream(DataConfigEnum.values())
.filter(dbFormTypeEnum -> FuncBase.equals(dbFormTypeEnum.getType(), type))
.findFirst(); // findFirst()会返回第一个匹配的元素或者如果找不到则返回一个空的Optional
// 检查是否找到了匹配的枚举项
if (matchingEnum.isPresent()) {
return matchingEnum.get();
}
return null;
}
}

View File

@@ -0,0 +1,69 @@
package com.jeelowcode.framework.utils.enums;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
/**
* 表单开发-属性类型
*/
public enum DbFormTypeEnum {
ALL("all", "所有"),
DICT("dict", "字典"),
EXPORT("export", "导出"),
FOREIGNKEY("foreignkey", "外键"),
WEB("web", "页面"),
QUERY("query", "查询"),
SUMMARY("summary", "统计配置"),
INDEX("index", "索引");
private final String type;
private final String name;
public String getType() {
return type;
}
public String getName() {
return name;
}
DbFormTypeEnum(String type, String name) {
this.type = type;
this.name = name;
}
public static DbFormTypeEnum getByType(String type) {
// 使用流来查找匹配的
Optional<DbFormTypeEnum> matchingEnum = Arrays.stream(DbFormTypeEnum.values())
.filter(dbFormTypeEnum -> FuncBase.equals(dbFormTypeEnum.getType(), type))
.findFirst(); // findFirst()会返回第一个匹配的元素或者如果找不到则返回一个空的Optional
// 检查是否找到了匹配的枚举项
if (matchingEnum.isPresent()) {
return matchingEnum.get();
}
return null;
}
public static List<DbFormTypeEnum> getAllEnum(){
return Arrays.asList(DbFormTypeEnum.values());
}
public static List<DbFormTypeEnum> getBaseEnum(){
List<DbFormTypeEnum> typeList = new ArrayList<>();
typeList.add(DbFormTypeEnum.WEB);
typeList.add(DbFormTypeEnum.DICT);
typeList.add(DbFormTypeEnum.QUERY);
typeList.add(DbFormTypeEnum.EXPORT);
typeList.add(DbFormTypeEnum.SUMMARY);
return typeList;
}
}

View File

@@ -0,0 +1,55 @@
package com.jeelowcode.framework.utils.enums;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.Arrays;
import java.util.Optional;
/**
* 数据库默认字段
*/
public enum DefaultDbFieldEnum {
ID("id", "id"),
P_ID("pid", "pid"),
CREATE_USER("create_user", "创建人"),
CREATE_TIME("create_time", "创建时间"),
CREATE_DEPT("create_dept", "创建部门"),
IS_DELETED("is_deleted", "是否删除"),
TENANT_ID("tenant_id", "租户id"),
UPDATE_USER("update_user", "更新人"),
UPDATE_TIME("update_time", "更新时间"),
;
private final String fieldCode;
private final String fieldName;
public String getFieldCode() {
return fieldCode;
}
public String getFieldName() {
return fieldName;
}
DefaultDbFieldEnum(String fieldCode, String fieldName) {
this.fieldCode = fieldCode;
this.fieldName = fieldName;
}
public static DefaultDbFieldEnum getByFieldCode(String fieldCode) {
Optional<DefaultDbFieldEnum> matchingEnum = Arrays.stream(DefaultDbFieldEnum.values())
.filter(DefaultDbFieldEnum -> FuncBase.equals(DefaultDbFieldEnum.getFieldCode(), fieldCode))
.findFirst(); // findFirst()会返回第一个匹配的元素或者如果找不到则返回一个空的Optional
// 检查是否找到了匹配的枚举项
if (matchingEnum.isPresent()) {
return matchingEnum.get();
}
return null;
}
}

View File

@@ -0,0 +1,30 @@
package com.jeelowcode.framework.utils.enums;
/**
* 字典类型类型
*/
public enum DictTypeEnum {
DICT("dict", "字典"),
TABLE("table", "表格");
private final String type;
private final String name;
public String getType() {
return type;
}
public String getName() {
return name;
}
DictTypeEnum(String type, String name) {
this.type = type;
this.name = name;
}
}

View File

@@ -0,0 +1,63 @@
package com.jeelowcode.framework.utils.enums;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.Arrays;
import java.util.Optional;
/**
* 数据库类型-和前端对应
*/
public enum JeeLowCodeFieldTypeEnum {
STRING("String", "字符串"),
INTEGER("Integer", "整数"),
DATE("Date", "日期"),
DATETIME("DateTime", "日期时间"),
TIME("Time", "时间"),
BIGINT("BigInt", "大整数"),
BIGDECIMAL("BigDecimal", "小数"),
TEXT("Text", "文本"),
LONGTEXT("LongText", "大文本"),
BLOB("Blob", "二进制");
/**
* Field类型
*/
private final String fieldType;
/**
* 数据名称
*/
private final String name;
public String getFieldType() {
return fieldType;
}
public String getName() {
return name;
}
JeeLowCodeFieldTypeEnum(String fieldType, String name) {
this.fieldType = fieldType;
this.name = name;
}
public static JeeLowCodeFieldTypeEnum getByFieldType(String fieldType) {
// 使用流来查找匹配的DbProductEnum
Optional<JeeLowCodeFieldTypeEnum> matchingEnum = Arrays.stream(JeeLowCodeFieldTypeEnum.values())
.filter(fieldTypeEnum -> FuncBase.equals(fieldTypeEnum.getFieldType(), fieldType))
.findFirst(); // findFirst()会返回第一个匹配的元素或者如果找不到则返回一个空的Optional
// 检查是否找到了匹配的枚举项
if (matchingEnum.isPresent()) {
return matchingEnum.get();
}
return null;
}
}

View File

@@ -0,0 +1,47 @@
package com.jeelowcode.framework.utils.enums;
/**
* 请求参数-特定参数名
*/
public enum ParamEnum {
//分页相关
PAGE_NO("pageNo", "当前页面"),
PAGE_SIZE("pageSize", "页面条数"),
COLUMN("column", "字典"),
ORDER("order", "排序类 desc asc"),
DICT_TABLE_FIELD("jeeLowCode_dictTableField", "字典表自定义列"),
DICT_LABEL("jeeLowCode_dictLabel", "字典表回显列"),
TREE_PARENT("jeeLowCode_treeParent", "获取指定列的所有上级"),
REQUEST_PARAM_BODY("requestParamBody", "body参数"),
MORE_SELECT_FIELD("more_select_field", "body参数"),
REQUEST_REPORT_CODES("jeeLowCode_report_codes", "报表code 多个通过,隔开"),
JEELOWCODE_EXPORT_IDS("jeeLowCode_export_ids", "excel导出选中id情况"),
ALL_QUERY_FIELD("jeeLowCode_all_query_field", "所有字段都可以查询"),
;
/**
* code类型
*/
private final String code;
/**
* 数据名称
*/
private final String name;
public String getCode() {
return code;
}
public String getName() {
return name;
}
ParamEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@@ -0,0 +1,31 @@
package com.jeelowcode.framework.utils.enums;
/**
* 查询模式
*/
public enum QueryModelEnum {
EQ("EQ", "精确查询"),
LIKE("LIKE", "模糊查询"),
RANGE("RANGE", "范围查询"),
IN("IN", "包含查询"),
NE("NE", "不等于");
private final String code;
private final String name;
QueryModelEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,61 @@
package com.jeelowcode.framework.utils.enums;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.Arrays;
import java.util.Optional;
/**
* sql默认参数
*/
public enum SqlParamEnum {
JEELOWCODE_ID("jeelowcode_id", "id"),
JEELOWCODE_DATE_TIME("jeelowcode_date_time", "日期时间"),
JEELOWCODE_DATE("jeelowcode_date", "日期"),
JEELOWCODE_TIME("jeelowcode_time", "时间"),
JEELOWCODE_IS_DELETED("jeelowcode_is_deleted", "是否删除"),
JEELOWCODE_TENANT_ID("jeelowcode_tenant_id", "当前登录人租户"),
JEELOWCODE_USER_ID("jeelowcode_user_id", "当前登录人id"),
JEELOWCODE_USER_NAME("jeelowcode_user_name", "当前登录人账号"),
JEELOWCODE_USER_NICKNAME("jeelowcode_user_nickname", "当前登录人名称"),
JEELOWCODE_USER_DEPT("jeelowcode_user_dept", "当前登录人部门"),
JEELOWCODE_USER_ALL_DEPT("jeelowcode_user_all_dept", "当前登录人所有部门(包括本部门)"),
JEELOWCODE_MAIN_ID("jeelowcode_main_id", "主数据id"),
JEELOWCODE_AUTO_WHERE("jeelowcode_auto_where", "自定义随机where");
/**
*/
private final String code;
/**
*/
private final String title;
public String getCode() {
return code;
}
public String getTitle() {
return title;
}
SqlParamEnum(String code, String title) {
this.code = code;
this.title = title;
}
public static SqlParamEnum getByCode(String code) {
Optional<SqlParamEnum> matchingEnum = Arrays.stream(SqlParamEnum.values())
.filter(sqlParamEnum -> FuncBase.equals(sqlParamEnum.getCode(), code))
.findFirst(); // findFirst()会返回第一个匹配的元素或者如果找不到则返回一个空的Optional
// 检查是否找到了匹配的枚举项
if (matchingEnum.isPresent()) {
return matchingEnum.get();
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
package com.jeelowcode.framework.utils.enums;
/**
* 表分类
*/
public enum TableClassifyEnum {
SERVICE(1, "业务表"),
VIEW(2, "表视图");
private final Integer type;
private final String name;
public Integer getType() {
return type;
}
public String getName() {
return name;
}
TableClassifyEnum(Integer type, String name) {
this.type = type;
this.name = name;
}
}

View File

@@ -0,0 +1,30 @@
package com.jeelowcode.framework.utils.enums;
/**
* 表类型 <br/>
* report 报表<br/>
* dbform 表单
*/
public enum TableType2Enum {
REPORT("report", "报表"),
DBFORM("dbform", "表单");
private final String type;
private final String name;
public String getType() {
return type;
}
public String getName() {
return name;
}
TableType2Enum(String type, String name) {
this.type = type;
this.name = name;
}
}

View File

@@ -0,0 +1,30 @@
package com.jeelowcode.framework.utils.enums;
/**
* 表类型 表类型;1单表、2树表、3主表、4附表
*/
public enum TableTypeEnum {
SINGLE(1, "单表"),
TREE(2, "树表"),
MAIN(3, "主表"),
SUB(4, "附表");
private final Integer type;
private final String name;
public Integer getType() {
return type;
}
public String getName() {
return name;
}
TableTypeEnum(Integer type, String name) {
this.type = type;
this.name = name;
}
}

View File

@@ -0,0 +1,31 @@
package com.jeelowcode.framework.utils.enums;
/**
* 表主题模版
*/
public enum ThemeTemplateEnum {
NORMAL("normal", "默认主题"),
ERP("erp", "ERP主题(一对多)"),
INNERTABLE("innerTable", "内嵌子表主题(一对多)");
private final String type;
private final String name;
public String getType() {
return type;
}
public String getName() {
return name;
}
ThemeTemplateEnum(String type, String name) {
this.type = type;
this.name = name;
}
}

View File

@@ -0,0 +1,29 @@
package com.jeelowcode.framework.utils.enums;
/**
* 是否
*/
public enum YNEnum {
Y("Y", ""),
N("N", "");
private final String code;
private final String name;
public String getCode() {
return code;
}
public String getName() {
return name;
}
YNEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@@ -0,0 +1,81 @@
package com.jeelowcode.framework.utils.global.body;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.jeelowcode.framework.utils.model.global.BaseWebResult;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* 返回拦截
*/
@ControllerAdvice
public class GlobalJeeLowCodeResponseBodyHandler implements ResponseBodyAdvice {
private static ObjectMapper objectMapper = new ObjectMapper();
static {
SimpleModule simpleModule = new SimpleModule();
simpleModule
// 新增 Long 类型序列化规则,数值超过 2^53-1在 JS 会出现精度丢失问题,因此 Long 自动序列化为字符串类型
.addSerializer(Long.class, NumberSerializer.INSTANCE)
.addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)
.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
// 新增 LocalDateTime 序列化、反序列化规则
.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值
objectMapper.registerModules(simpleModule); // 序列化
}
@Override
@SuppressWarnings("NullableProblems") // 避免 IDEA 警告
public boolean supports(MethodParameter returnType, Class converterType) {
if (returnType.getMethod() == null) {
return false;
}
// 只拦截返回结果为 BaseWebResult 类型
return returnType.getMethod().getReturnType() == BaseWebResult.class;
}
@Override
@SuppressWarnings("NullableProblems") // 避免 IDEA 警告
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
if(body instanceof BaseWebResult){
try {
String jsonStr = objectMapper.writeValueAsString(body);
BaseWebResult baseWebResult = JSONUtil.toBean(jsonStr, BaseWebResult.class);
return baseWebResult;
} catch (Exception e) {
e.printStackTrace();
}
}
return body;
}
}

View File

@@ -0,0 +1,26 @@
package com.jeelowcode.framework.utils.global.body;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* LocalDateTime反序列化规则
* <p>
* 会将毫秒级时间戳反序列化为LocalDateTime
*/
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer();
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
}
}

View File

@@ -0,0 +1,25 @@
package com.jeelowcode.framework.utils.global.body;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* LocalDateTime序列化规则
* <p>
* 会将LocalDateTime序列化为毫秒级时间戳
*/
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer();
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
}

View File

@@ -0,0 +1,38 @@
package com.jeelowcode.framework.utils.global.body;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import java.io.IOException;
/**
* Long 序列化规则
*
* 会将超长 long 值转换为 string解决前端 JavaScript 最大安全整数是 2^53-1 的问题
*
* @author 星语
*/
@JacksonStdImpl
public class NumberSerializer extends com.fasterxml.jackson.databind.ser.std.NumberSerializer {
private static final long MAX_SAFE_INTEGER = 9007199254740991L;
private static final long MIN_SAFE_INTEGER = -9007199254740991L;
public static final NumberSerializer INSTANCE = new NumberSerializer(Number.class);
public NumberSerializer(Class<? extends Number> rawType) {
super(rawType);
}
@Override
public void serialize(Number value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// 超出范围 序列化位字符串
if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
super.serialize(value, gen, serializers);
} else {
gen.writeString(value.toString());
}
}
}

View File

@@ -0,0 +1,58 @@
package com.jeelowcode.framework.utils.global.exeption;
/**
* 全局异常
*
*/
public class JeeLowCodeGlobalException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public JeeLowCodeGlobalException()
{
}
public JeeLowCodeGlobalException(String message)
{
this.message = message;
}
public String getDetailMessage()
{
return detailMessage;
}
public JeeLowCodeGlobalException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
@Override
public String getMessage()
{
return message;
}
public JeeLowCodeGlobalException setMessage(String message)
{
this.message = message;
return this;
}
}

View File

@@ -0,0 +1,142 @@
package com.jeelowcode.framework.utils.global.exeption;
import com.jeelowcode.framework.code.JeeLowCodeErrorCode;
import com.jeelowcode.framework.constants.FrameErrorCodeConstants;
import com.jeelowcode.framework.exception.JeeLowCodeException;
import com.jeelowcode.framework.exception.JeeLowCodeMoreException;
import com.jeelowcode.framework.global.JeeLowCodeBaseConstant;
import com.jeelowcode.framework.utils.model.global.BaseWebResult;
import com.jeelowcode.framework.utils.utils.FuncBase;
import com.jeelowcode.tool.framework.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 全局异常处理器
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice(basePackages = JeeLowCodeBaseConstant.BASE_PACKAGES)//扫码我们的包
public class JeeLowCodeGlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(JeeLowCodeGlobalExceptionHandler.class);
/**
* 拦截业务的运行时异常
*/
@ExceptionHandler(ServiceException.class)
public BaseWebResult handleServiceException(ServiceException e) {
Integer code = e.getCode();
String message = e.getMessage();
e.printStackTrace();
return BaseWebResult.error(code, message);
}
/**
* 拦截校验异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public BaseWebResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String message = e.getMessage();
e.printStackTrace();
try{
message =message.split("arguments \\[\\]; default message \\[")[1];
Pattern pattern = Pattern.compile("default message \\[(.*?)\\]");
Matcher matcher = pattern.matcher(message);
if (matcher.find()) {
String defaultMessage = matcher.group(1);
return BaseWebResult.error(FrameErrorCodeConstants.FRAM_SELF_ERROR.getCode(), defaultMessage);
}
}catch (Exception e2){
}
return BaseWebResult.error(FrameErrorCodeConstants.FRAME_PARAM_ERROR);
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler(RuntimeException.class)
public BaseWebResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
e.printStackTrace();
return BaseWebResult.error(FrameErrorCodeConstants.FRAME_PARAM_ERROR);
}
/**
* 系统异常
*/
@ExceptionHandler(Exception.class)
public BaseWebResult handleException(Exception e) {
e.printStackTrace();
String message = e.getMessage();
return BaseWebResult.error(FrameErrorCodeConstants.FRAME_PARAM_ERROR);
}
/**
* 自定义异常
*
* @param e
* @return
*/
@ExceptionHandler(JeeLowCodeException.class)
public BaseWebResult handleJeeLowCodeExceptionException(RuntimeException e) {
String message = e.getMessage();
if (FuncBase.isNotEmpty(message) && FuncBase.jsonIsJson(message)) {
//判断是否是 BaseWebResult如果是BaseWebResult 则直接弹出
if (message.contains("code") && message.contains("msg")) {
try {
BaseWebResult baseWebResult = FuncBase.json2Bean(message, BaseWebResult.class);
if (FuncBase.isNotEmpty(baseWebResult)) {
return baseWebResult;
}
} catch (Exception e1) {
}
}
}
return BaseWebResult.error(FrameErrorCodeConstants.FRAM_SELF_ERROR.getCode(), e.getMessage());
}
/**
* 自定义异常-更多详情
*
* @param e
* @return
*/
@ExceptionHandler(JeeLowCodeMoreException.class)
public BaseWebResult handleJeeLowCodeMoreExceptionException(RuntimeException e) {
String messageJsonStr = e.getMessage();
Map<String, String> map = FuncBase.json2Bean(messageJsonStr, Map.class);
String title = map.get("title");
String e1 = map.get("e");
//封装map
JeeLowCodeErrorCode jeeLowCodeErrorCode = new JeeLowCodeErrorCode(FrameErrorCodeConstants.FRAME_OP_ERROR.getCode(), title);
return BaseWebResult.error(jeeLowCodeErrorCode, e1);
}
}

View File

@@ -0,0 +1,40 @@
package com.jeelowcode.framework.utils.model;
/**
* @author JX
* @create 2024-06-20 15:06
* @dedescription:
*/
public class ExecFormReqBody<T> {
private Long dbFormId;
private T data;
private String tableName;
public Long getDbFormId() {
return dbFormId;
}
public void setDbFormId(Long dbFormId) {
this.dbFormId = dbFormId;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
}

View File

@@ -0,0 +1,45 @@
package com.jeelowcode.framework.utils.model;
/**
* @author JX
* @create 2024-06-20 9:03
* @dedescription:
*/
public class ExecFormRespBody {
private int status;
private ExecuteEnhanceModel data;
private String message;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public ExecuteEnhanceModel getData() {
return data;
}
public void setData(ExecuteEnhanceModel data) {
this.data = data;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public boolean checkStatus(){
return this.status == 200;
}
}

View File

@@ -0,0 +1,53 @@
package com.jeelowcode.framework.utils.model;
import java.util.List;
import java.util.Map;
/**
* @author JX
* @create 2024-06-20 15:20
* @dedescription:
*/
public class ExecListReqBody {
private Long dbFormId;
private Map<String, Object> params;
private List<Map<String, Object>> dataList;
private String tableName;
public Long getDbFormId() {
return dbFormId;
}
public void setDbFormId(Long dbFormId) {
this.dbFormId = dbFormId;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public Map<String, Object> getParams() {
return params;
}
public void setParams(Map<String, Object> params) {
this.params = params;
}
public List<Map<String, Object>> getDataList() {
return dataList;
}
public void setDataList(List<Map<String, Object>> dataList) {
this.dataList = dataList;
}
}

View File

@@ -0,0 +1,45 @@
package com.jeelowcode.framework.utils.model;
/**
* @author JX
* @create 2024-06-20 9:22
* @dedescription:
*/
public class ExecListRespBody {
private int status;
private ResultDataModel data;
private String message;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public ResultDataModel getData() {
return data;
}
public void setData(ResultDataModel data) {
this.data = data;
}
public boolean checkStatus(){
return this.status == 200;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,32 @@
package com.jeelowcode.framework.utils.model;
import com.jeelowcode.framework.utils.utils.FuncBase;
public class ExecuteEnhanceModel {
private boolean exitFlag=false;//是否退出
private String id;//id
public boolean isExitFlag() {
return exitFlag;
}
public void setExitFlag(boolean exitFlag) {
this.exitFlag = exitFlag;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ExecuteEnhanceModel fomat(Object id, boolean exitFlag){
ExecuteEnhanceModel model=new ExecuteEnhanceModel();
model.setId(FuncBase.toStr(id));
model.setExitFlag(exitFlag);
return model;
}
}

View File

@@ -0,0 +1,32 @@
package com.jeelowcode.framework.utils.model;
public class JeeLowCodeDept {
private String deptId;
private String deptPid;
private String deptName;
public String getDeptId() {
return deptId;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
public String getDeptPid() {
return deptPid;
}
public void setDeptPid(String deptPid) {
this.deptPid = deptPid;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}

View File

@@ -0,0 +1,52 @@
package com.jeelowcode.framework.utils.model;
import java.util.List;
/**
* 字典
*/
public class JeeLowCodeDict {
private String dictCode;
private List<DictData> dataList;
public static class DictData{
private String val;
private String label;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
public String getDictCode() {
return dictCode;
}
public void setDictCode(String dictCode) {
this.dictCode = dictCode;
}
public List<DictData> getDataList() {
return dataList;
}
public void setDataList(List<DictData> dataList) {
this.dataList = dataList;
}
}

View File

@@ -0,0 +1,51 @@
package com.jeelowcode.framework.utils.model;
import java.util.List;
/**
* 字典-表
*/
public class JeeLowCodeDictTable {
private String tableCode;
private List<DictTableData> dataTableList;
public static class DictTableData{
private String val;
private String key;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
public String getTableCode() {
return tableCode;
}
public void setTableCode(String tableCode) {
this.tableCode = tableCode;
}
public List<DictTableData> getDataTableList() {
return dataTableList;
}
public void setDataTableList(List<DictTableData> dataTableList) {
this.dataTableList = dataTableList;
}
}

View File

@@ -0,0 +1,23 @@
package com.jeelowcode.framework.utils.model;
public class JeeLowCodeRole {
private String roleId;
private String roleName;
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}

View File

@@ -0,0 +1,85 @@
package com.jeelowcode.framework.utils.model;
public class JeeLowCodeUser {
private String userId;//用户id
private String nickName;//用户昵称
private String mobile;//手机号
private String email;//邮箱
private String sex;//性别
private String post;//职位
private String avatar;//头像
private String deptName;//部门名称
private String deptId;//部门名称
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public String getDeptName() {
return deptName;
}
public String getDeptId() {
return deptId;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
}

View File

@@ -0,0 +1,29 @@
package com.jeelowcode.framework.utils.model;
/**
* 租户
*/
public class JeeLowTenant {
private String tenantId;
private String tenantName;
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getTenantName() {
return tenantName;
}
public void setTenantName(String tenantName) {
this.tenantName = tenantName;
}
}

View File

@@ -0,0 +1,111 @@
package com.jeelowcode.framework.utils.model;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class ResultDataModel {
private boolean exitFlag=false;//是否退出
private Long total;
private List<Map<String,Object>> records;//列表
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List<Map<String, Object>> getRecords() {
return records;
}
public void setRecords(List<Map<String, Object>> records) {
this.records = records;
}
public boolean isExitFlag() {
return exitFlag;
}
public void setExitFlag(boolean exitFlag) {
this.exitFlag = exitFlag;
}
public ResultDataModel(){
this.total=0L;
this.setRecords(new ArrayList<>());
}
/**
* 取一条
* @param list
* @return
*/
public static ResultDataModel fomatOne(List<Map<String, Object>> list){
if(FuncBase.isEmpty(list)){
ResultDataModel resultDataModel = new ResultDataModel();
resultDataModel.setTotal(0L);
resultDataModel.setRecords(new ArrayList<>());
return resultDataModel;
}
Map<String, Object> tmpMap = list.get(0);
list.clear();
list.add(tmpMap);
ResultDataModel model=new ResultDataModel();
model.setTotal(FuncBase.toLong(list.size()));
model.setRecords(list);
return model;
}
/**
* 只处理数据,不改变总数的情况下
* @param list
* @return
*/
public static ResultDataModel fomatList(List<Map<String, Object>> list){
if(FuncBase.isEmpty(list)){
ResultDataModel resultDataModel = new ResultDataModel();
resultDataModel.setTotal(0L);
resultDataModel.setRecords(new ArrayList<>());
return resultDataModel;
}
ResultDataModel model=new ResultDataModel();
model.setRecords(list);
return model;
}
/**
* 只处理数据,不改变总数的情况下
* @param dataMap
* @return
*/
public static ResultDataModel fomatMap(Map<String, Object> dataMap){
List<Map<String, Object>> list = Collections.singletonList(dataMap);
ResultDataModel model=new ResultDataModel();
model.setRecords(list);
return model;
}
/**
* 处理数据和改变总数的情况下
* @param total
* @param list
* @return
*/
public static ResultDataModel fomat(long total,List<Map<String, Object>> list){
ResultDataModel model=new ResultDataModel();
model.setTotal(total);
model.setRecords(list);
return model;
}
}

View File

@@ -0,0 +1,72 @@
package com.jeelowcode.framework.utils.model.global;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.ibatis.type.JdbcType;
import java.io.Serializable;
import java.sql.Date;
import java.time.LocalDateTime;
/**
* 公共实体对象
*/
@Data
@EqualsAndHashCode
public class BaseEntity implements Serializable {
@JsonSerialize(
using = ToStringSerializer.class
)
@TableId(
value = "id",
type = IdType.ASSIGN_ID
)
private Long id;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT,jdbcType = JdbcType.DATE)
private LocalDateTime createTime;
/**
* 创建者
*
*/
@TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.BIGINT)
private Long createUser;
/**
* 创建部门
*
*/
@TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.BIGINT)
private Long createDept;
/**
* 更新者
*
*/
@TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.BIGINT)
private Long updateUser;
/**
* 最后更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE,jdbcType = JdbcType.DATE)
private LocalDateTime updateTime;
/**
* 是否删除
*/
@TableLogic
private Integer isDeleted;
}

View File

@@ -0,0 +1,19 @@
package com.jeelowcode.framework.utils.model.global;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 公共实体对象-租户
*/
@Data
@EqualsAndHashCode
public abstract class BaseTenantEntity extends BaseEntity {
/**
* 租户id
*/
private Long tenantId;
}

View File

@@ -0,0 +1,125 @@
package com.jeelowcode.framework.utils.model.global;
import com.jeelowcode.framework.code.JeeLowCodeErrorCode;
import com.jeelowcode.framework.constants.FrameErrorCodeConstants;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 通用返回
*
*/
public class BaseWebResult<T> implements Serializable {
/**
* 错误码
*/
private Integer code;
/**
* 返回数据
*/
private T data;
/**
* 错误提示,用户可阅读
*/
private String msg;
/**
* 将传入的 result 对象,转换成另外一个泛型结果的对象
*
* 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。
*
* @param result 传入的 result 对象
* @param <T> 返回的泛型
* @return 新的 CommonResult 对象
*/
public static <T> BaseWebResult<T> error(BaseWebResult<?> result) {
return error(result.getCode(), result.getMsg());
}
public static <T> BaseWebResult<T> error(Integer code, String message) {
Assert.isTrue(!FrameErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
BaseWebResult<T> result = new BaseWebResult();
result.code = code;
result.msg = message;
return result;
}
public static <T> BaseWebResult<T> error(JeeLowCodeErrorCode errorCode) {
return error(errorCode.getCode(), errorCode.getMsg());
}
public static <T> BaseWebResult<T> error(JeeLowCodeErrorCode errorCode,T data) {
BaseWebResult<T> result = new BaseWebResult();
result.code = errorCode.getCode();
result.msg = errorCode.getMsg();
result.data=data;
return result;
}
public static BaseWebResult successNull() {
Map<String, Object> dataMap = new HashMap<>();
BaseWebResult result = new BaseWebResult();
result.code = FrameErrorCodeConstants.SUCCESS.getCode();
result.data = dataMap;
result.msg = "";
return result;
}
public static <T> BaseWebResult<T> success(T data) {
BaseWebResult<T> result = new BaseWebResult();
result.code = FrameErrorCodeConstants.SUCCESS.getCode();
result.data = data;
result.msg = "";
return result;
}
public static boolean isSuccess(Integer code) {
return Objects.equals(code, FrameErrorCodeConstants.SUCCESS.getCode());
}
@JsonIgnore // 避免 jackson 序列化
public boolean isSuccess() {
return isSuccess(code);
}
@JsonIgnore // 避免 jackson 序列化
public boolean isError() {
return !isSuccess();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@@ -0,0 +1,25 @@
package com.jeelowcode.framework.utils.params;
public class JeeLowCodeDeptParam {
String deptName;//部门名称搜索
String type;//all=所有 now=当前级 sub=本级及下级
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@@ -0,0 +1,55 @@
package com.jeelowcode.framework.utils.params;
import java.util.List;
import java.util.Map;
public class JeeLowCodeDictParam {
//字典编码
List<String> dictCodeList;
private Map<String,DictCodeDataParam> paramMap;
public static class DictCodeDataParam{
//字段数据key
List<String> dictDataLabelList;
//字段数据value
List<String> dictDataValueList;
public List<String> getDictDataLabelList() {
return dictDataLabelList;
}
public void setDictDataLabelList(List<String> dictDataLabelList) {
this.dictDataLabelList = dictDataLabelList;
}
public List<String> getDictDataValueList() {
return dictDataValueList;
}
public void setDictDataValueList(List<String> dictDataValueList) {
this.dictDataValueList = dictDataValueList;
}
}
public List<String> getDictCodeList() {
return dictCodeList;
}
public void setDictCodeList(List<String> dictCodeList) {
this.dictCodeList = dictCodeList;
}
public Map<String, DictCodeDataParam> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, DictCodeDataParam> paramMap) {
this.paramMap = paramMap;
}
}

View File

@@ -0,0 +1,71 @@
package com.jeelowcode.framework.utils.params;
import java.util.List;
import java.util.Map;
public class JeeLowCodeDictTableParam {
//字典编码
List<DictCodeDataParam> paramList;
public static class DictCodeDataParam{
private String tableName;//表名称
private String fieldKey;//字段键
private String fieldValue;//字段值
private String whereField;//id
private String whereValue;//1
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getFieldKey() {
return fieldKey;
}
public void setFieldKey(String fieldKey) {
this.fieldKey = fieldKey;
}
public String getFieldValue() {
return fieldValue;
}
public void setFieldValue(String fieldValue) {
this.fieldValue = fieldValue;
}
public String getWhereField() {
return whereField;
}
public void setWhereField(String whereField) {
this.whereField = whereField;
}
public String getWhereValue() {
return whereValue;
}
public void setWhereValue(String whereValue) {
this.whereValue = whereValue;
}
}
public List<DictCodeDataParam> getParamList() {
return paramList;
}
public void setParamList(List<DictCodeDataParam> paramList) {
this.paramList = paramList;
}
}

View File

@@ -0,0 +1,94 @@
package com.jeelowcode.framework.utils.params;
import java.util.List;
/***
* 用户查询参数
*/
public class JeeLowCodeUserParam {
Integer pageNo;
Integer pageSize;
//角色id
private Long roleId;
//部门id
private Long deptId;
//用户昵称
private String nickName;
//手机号
private String mobile;
private String type;//all now sub
//自定义列 userId,nickName,mobile,email,sex,post,deptName
private List<String> fieldList;
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public List<String> getFieldList() {
return fieldList;
}
public void setFieldList(List<String> fieldList) {
this.fieldList = fieldList;
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@@ -0,0 +1,238 @@
package com.jeelowcode.framework.utils.tool;
import cn.hutool.core.util.CharsetUtil;
import com.jeelowcode.framework.exception.JeeLowCodeException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Objects;
/**
* 完全兼容微信所使用的AES加密工具类
* aes的key必须是256byte长比如32个字符可以使用AesKit.genAesKey()来生成一组key
*
*/
public class AesUtil {
public static final Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8;
//密钥
public static String secretKey="";
/**
* 获取密钥
*
* @return {String}
*/
public static String genAesKey() {
return StringUtil.random(32);
}
/**
* 加密
*
* @param content 文本内容
* @param aesTextKey 文本密钥
* @return byte[]
*/
public static byte[] encrypt(String content, String aesTextKey) {
return encrypt(content.getBytes(DEFAULT_CHARSET), aesTextKey);
}
/**
* 加密
*
* @param content 文本内容
* @param charset 编码
* @param aesTextKey 文本密钥
* @return byte[]
*/
public static byte[] encrypt(String content, Charset charset, String aesTextKey) {
return encrypt(content.getBytes(charset), aesTextKey);
}
/**
* 加密
*
* @param content 内容
* @param aesTextKey 文本密钥
* @return byte[]
*/
public static byte[] encrypt(byte[] content, String aesTextKey) {
return encrypt(content, Objects.requireNonNull(aesTextKey).getBytes(DEFAULT_CHARSET));
}
/**
* Base64加密
*
* @param content 文本内容
* @param aesTextKey 文本密钥
* @return {String}
*/
public static String encryptToBase64(String content, String aesTextKey) {
return Base64Util.encodeToString(encrypt(content, aesTextKey));
}
/**
* Base64加密
*
* @param content 内容
* @param aesTextKey 文本密钥
* @return {String}
*/
public static String encryptToBase64(byte[] content, String aesTextKey) {
return Base64Util.encodeToString(encrypt(content, aesTextKey));
}
/**
* Base64解密
*
* @param content 文本内容
* @param aesTextKey 文本密钥
* @return {String}
*/
@Nullable
public static String decryptFormBase64ToString(@Nullable String content, String aesTextKey) {
byte[] hexBytes = decryptFormBase64(content, aesTextKey);
if (hexBytes == null) {
return null;
}
return new String(hexBytes, DEFAULT_CHARSET);
}
/**
* Base64解密
*
* @param content 文本内容
* @param aesTextKey 文本密钥
* @return byte[]
*/
@Nullable
public static byte[] decryptFormBase64(@Nullable String content, String aesTextKey) {
if (StringUtil.isBlank(content)) {
return null;
}
return decryptFormBase64(content.getBytes(DEFAULT_CHARSET), aesTextKey);
}
/**
* Base64解密
*
* @param content 内容
* @param aesTextKey 文本密钥
* @return byte[]
*/
public static byte[] decryptFormBase64(byte[] content, String aesTextKey) {
return decrypt(Base64Util.decode(content), aesTextKey);
}
/**
* 解密
*
* @param content 内容
* @param aesTextKey 文本密钥
* @return {String}
*/
public static String decryptToString(byte[] content, String aesTextKey) {
return new String(decrypt(content, aesTextKey), DEFAULT_CHARSET);
}
/**
* 解密
*
* @param content 内容
* @param aesTextKey 文本密钥
* @return byte[]
*/
public static byte[] decrypt(byte[] content, String aesTextKey) {
return decrypt(content, Objects.requireNonNull(aesTextKey).getBytes(DEFAULT_CHARSET));
}
/**
* 解密
*
* @param content 内容
* @param aesKey 密钥
* @return byte[]
*/
public static byte[] encrypt(byte[] content, byte[] aesKey) {
return aes(Pkcs7Encoder.encode(content), aesKey, Cipher.ENCRYPT_MODE);
}
/**
* 加密
*
* @param encrypted 内容
* @param aesKey 密钥
* @return byte[]
*/
public static byte[] decrypt(byte[] encrypted, byte[] aesKey) {
return Pkcs7Encoder.decode(aes(encrypted, aesKey, Cipher.DECRYPT_MODE));
}
/**
* ase加密
*
* @param encrypted 内容
* @param aesKey 密钥
* @param mode 模式
* @return byte[]
*/
private static byte[] aes(byte[] encrypted, byte[] aesKey, int mode) {
Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32");
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(mode, keySpec, iv);
return cipher.doFinal(encrypted);
} catch (Exception e) {
throw new JeeLowCodeException(e.getMessage());
}
}
/**
* 提供基于PKCS7算法的加解密接口.
*/
private static class Pkcs7Encoder {
private static final int BLOCK_SIZE = 32;
private static byte[] encode(byte[] src) {
int count = src.length;
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
// 获得补位所用的字符
byte pad = (byte) (amountToPad & 0xFF);
byte[] pads = new byte[amountToPad];
for (int index = 0; index < amountToPad; index++) {
pads[index] = pad;
}
int length = count + amountToPad;
byte[] dest = new byte[length];
System.arraycopy(src, 0, dest, 0, count);
System.arraycopy(pads, 0, dest, count, amountToPad);
return dest;
}
private static byte[] decode(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > BLOCK_SIZE) {
pad = 0;
}
if (pad > 0) {
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
return decrypted;
}
}
}

View File

@@ -0,0 +1,100 @@
package com.jeelowcode.framework.utils.tool;
import cn.hutool.core.util.CharsetUtil;
/**
* Base64工具
*/
public class Base64Util extends org.springframework.util.Base64Utils {
/**
* 编码
*
* @param value 字符串
* @return {String}
*/
public static String encode(String value) {
return Base64Util.encode(value, CharsetUtil.CHARSET_UTF_8);
}
/**
* 编码
*
* @param value 字符串
* @param charset 字符集
* @return {String}
*/
public static String encode(String value, java.nio.charset.Charset charset) {
byte[] val = value.getBytes(charset);
return new String(Base64Util.encode(val), charset);
}
/**
* 编码URL安全
*
* @param value 字符串
* @return {String}
*/
public static String encodeUrlSafe(String value) {
return Base64Util.encodeUrlSafe(value, CharsetUtil.CHARSET_UTF_8);
}
/**
* 编码URL安全
*
* @param value 字符串
* @param charset 字符集
* @return {String}
*/
public static String encodeUrlSafe(String value, java.nio.charset.Charset charset) {
byte[] val = value.getBytes(charset);
return new String(Base64Util.encodeUrlSafe(val), charset);
}
/**
* 解码
*
* @param value 字符串
* @return {String}
*/
public static String decode(String value) {
return Base64Util.decode(value, CharsetUtil.CHARSET_UTF_8);
}
/**
* 解码
*
* @param value 字符串
* @param charset 字符集
* @return {String}
*/
public static String decode(String value, java.nio.charset.Charset charset) {
byte[] val = value.getBytes(charset);
byte[] decodedValue = Base64Util.decode(val);
return new String(decodedValue, charset);
}
/**
* 解码URL安全
*
* @param value 字符串
* @return {String}
*/
public static String decodeUrlSafe(String value) {
return Base64Util.decodeUrlSafe(value, CharsetUtil.CHARSET_UTF_8);
}
/**
* 解码URL安全
*
* @param value 字符串
* @param charset 字符集
* @return {String}
*/
public static String decodeUrlSafe(String value, java.nio.charset.Charset charset) {
byte[] val = value.getBytes(charset);
byte[] decodedValue = Base64Util.decodeUrlSafe(val);
return new String(decodedValue, charset);
}
}

View File

@@ -0,0 +1,57 @@
package com.jeelowcode.framework.utils.tool;
/**
* char 常量池
*/
public interface CharPool {
// @formatter:off
char UPPER_A = 'A';
char LOWER_A = 'a';
char UPPER_Z = 'Z';
char LOWER_Z = 'z';
char DOT = '.';
char AT = '@';
char LEFT_BRACE = '{';
char RIGHT_BRACE = '}';
char LEFT_BRACKET = '(';
char RIGHT_BRACKET = ')';
char DASH = '-';
char PERCENT = '%';
char PIPE = '|';
char PLUS = '+';
char QUESTION_MARK = '?';
char EXCLAMATION_MARK = '!';
char EQUALS = '=';
char AMPERSAND = '&';
char ASTERISK = '*';
char STAR = ASTERISK;
char BACK_SLASH = '\\';
char COLON = ':';
char COMMA = ',';
char DOLLAR = '$';
char SLASH = '/';
char HASH = '#';
char HAT = '^';
char LEFT_CHEV = '<';
char NEWLINE = '\n';
char N = 'n';
char Y = 'y';
char QUOTE = '\"';
char RETURN = '\r';
char TAB = '\t';
char RIGHT_CHEV = '>';
char SEMICOLON = ';';
char SINGLE_QUOTE = '\'';
char BACKTICK = '`';
char SPACE = ' ';
char TILDA = '~';
char LEFT_SQ_BRACKET = '[';
char RIGHT_SQ_BRACKET = ']';
char UNDERSCORE = '_';
char ONE = '1';
char ZERO = '0';
// @formatter:on
}

View File

@@ -0,0 +1,162 @@
package com.jeelowcode.framework.utils.tool;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;
/**
* 集合工具类
*/
public class CollectionUtil extends CollectionUtils {
/**
* Return {@code true} if the supplied Collection is not {@code null} or empty.
* Otherwise, return {@code false}.
*
* @param collection the Collection to check
* @return whether the given Collection is not empty
*/
public static boolean isNotEmpty(@Nullable Collection<?> collection) {
return !CollectionUtil.isEmpty(collection);
}
/**
* Return {@code true} if the supplied Map is not {@code null} or empty.
* Otherwise, return {@code false}.
*
* @param map the Map to check
* @return whether the given Map is not empty
*/
public static boolean isNotEmpty(@Nullable Map<?, ?> map) {
return !CollectionUtil.isEmpty(map);
}
/**
* Check whether the given Array contains the given element.
*
* @param array the Array to check
* @param element the element to look for
* @param <T> The generic tag
* @return {@code true} if found, {@code false} else
*/
public static <T> boolean contains(@Nullable T[] array, final T element) {
if (array == null) {
return false;
}
return Arrays.stream(array).anyMatch(x -> ObjectUtils.nullSafeEquals(x, element));
}
/**
* Concatenates 2 arrays
*
* @param one 数组1
* @param other 数组2
* @return 新数组
*/
public static String[] concat(String[] one, String[] other) {
return concat(one, other, String.class);
}
/**
* Concatenates 2 arrays
*
* @param one 数组1
* @param other 数组2
* @param clazz 数组类
* @return 新数组
*/
public static <T> T[] concat(T[] one, T[] other, Class<T> clazz) {
T[] target = (T[]) Array.newInstance(clazz, one.length + other.length);
System.arraycopy(one, 0, target, 0, one.length);
System.arraycopy(other, 0, target, one.length, other.length);
return target;
}
/**
* 对象是否为数组对象
*
* @param obj 对象
* @return 是否为数组对象,如果为{@code null} 返回false
*/
public static boolean isArray(Object obj) {
if (null == obj) {
return false;
}
return obj.getClass().isArray();
}
/**
* 不可变 Set
*
* @param es 对象
* @param <E> 泛型
* @return 集合
*/
@SafeVarargs
public static <E> Set<E> ofImmutableSet(E... es) {
Objects.requireNonNull(es, "args es is null.");
return Arrays.stream(es).collect(Collectors.toSet());
}
/**
* 不可变 List
*
* @param es 对象
* @param <E> 泛型
* @return 集合
*/
@SafeVarargs
public static <E> List<E> ofImmutableList(E... es) {
Objects.requireNonNull(es, "args es is null.");
return Arrays.stream(es).collect(Collectors.toList());
}
/**
* Iterable 转换为List集合
*
* @param elements Iterable
* @param <E> 泛型
* @return 集合
*/
public static <E> List<E> toList(Iterable<E> elements) {
Objects.requireNonNull(elements, "elements es is null.");
if (elements instanceof Collection) {
return new ArrayList((Collection) elements);
}
Iterator<E> iterator = elements.iterator();
List<E> list = new ArrayList<>();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
/**
* 将key value 数组转为 map
*
* @param keysValues key value 数组
* @param <K> key
* @param <V> value
* @return map 集合
*/
public static <K, V> Map<K, V> toMap(Object... keysValues) {
int kvLength = keysValues.length;
if (kvLength % 2 != 0) {
throw new IllegalArgumentException("wrong number of arguments for met, keysValues length can not be odd");
}
Map<K, V> keyValueMap = new HashMap<>(kvLength);
for (int i = kvLength - 2; i >= 0; i -= 2) {
Object key = keysValues[i];
Object value = keysValues[i + 1];
keyValueMap.put((K) key, (V) value);
}
return keyValueMap;
}
}

View File

@@ -0,0 +1,22 @@
package com.jeelowcode.framework.utils.tool;
import java.security.SecureRandom;
import java.util.Random;
/**
* 一些常用的单利对象
*
*/
public class Holder {
/**
* RANDOM
*/
public final static Random RANDOM = new Random();
/**
* SECURE_RANDOM
*/
public final static SecureRandom SECURE_RANDOM = new SecureRandom();
}

View File

@@ -0,0 +1,380 @@
package com.jeelowcode.framework.utils.tool;
import com.jeelowcode.framework.utils.utils.FuncBase;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 获取IP方法
*
* @author ruoyi
*/
public class IpUtils
{
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
// 匹配 ip
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
// 匹配网段
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
/**
* 获取客户端IP
*
* @param request 请求对象
* @return IP地址
*/
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
}
/**
* 检查是否为内部IP地址
*
* @param ip IP地址
* @return 结果
*/
public static boolean internalIp(String ip)
{
byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip);
}
/**
* 检查是否为内部IP地址
*
* @param addr byte地址
* @return 结果
*/
private static boolean internalIp(byte[] addr)
{
if (FuncBase.isEmpty(addr) || addr.length < 2)
{
return true;
}
final byte b0 = addr[0];
final byte b1 = addr[1];
// 10.x.x.x/8
final byte SECTION_1 = 0x0A;
// 172.16.x.x/12
final byte SECTION_2 = (byte) 0xAC;
final byte SECTION_3 = (byte) 0x10;
final byte SECTION_4 = (byte) 0x1F;
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
switch (b0)
{
case SECTION_1:
return true;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4)
{
return true;
}
case SECTION_5:
switch (b1)
{
case SECTION_6:
return true;
}
default:
return false;
}
}
/**
* 将IPv4地址转换成字节
*
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text)
{
if (text.length() == 0)
{
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try
{
long l;
int i;
switch (elements.length)
{
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L))
{
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L))
{
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L))
{
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
}
catch (NumberFormatException e)
{
return null;
}
return bytes;
}
/**
* 获取IP地址
*
* @return 本地IP地址
*/
public static String getHostIp()
{
try
{
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException e)
{
}
return "127.0.0.1";
}
/**
* 获取主机名
*
* @return 本地主机名
*/
public static String getHostName()
{
try
{
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
}
return "未知";
}
/**
* 从多级反向代理中获得第一个非unknown IP地址
*
* @param ip 获得的IP地址
* @return 第一个非unknown IP地址
*/
public static String getMultistageReverseProxyIp(String ip)
{
// 多级反向代理检测
if (ip != null && ip.indexOf(",") > 0)
{
final String[] ips = ip.trim().split(",");
for (String subIp : ips)
{
if (false == isUnknown(subIp))
{
ip = subIp;
break;
}
}
}
return ip.substring(0, 255);
}
/**
* 检测给定字符串是否为未知多用于检测HTTP请求相关
*
* @param checkString 被检测的字符串
* @return 是否未知
*/
public static boolean isUnknown(String checkString)
{
return FuncBase.isEmpty(checkString) || "unknown".equalsIgnoreCase(checkString);
}
/**
* 是否为IP
*/
public static boolean isIP(String ip)
{
return FuncBase.isNotBlank(ip) && ip.matches(REGX_IP);
}
/**
* 是否为IP或 *为间隔的通配符地址
*/
public static boolean isIpWildCard(String ip)
{
return FuncBase.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
}
/**
* 检测参数是否在ip通配符里
*/
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
{
String[] s1 = ipWildCard.split("\\.");
String[] s2 = ip.split("\\.");
boolean isMatchedSeg = true;
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
{
if (!s1[i].equals(s2[i]))
{
isMatchedSeg = false;
break;
}
}
return isMatchedSeg;
}
/**
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
*/
public static boolean isIPSegment(String ipSeg)
{
return FuncBase.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
}
/**
* 判断ip是否在指定网段中
*/
public static boolean ipIsInNetNoCheck(String iparea, String ip)
{
int idx = iparea.indexOf('-');
String[] sips = iparea.substring(0, idx).split("\\.");
String[] sipe = iparea.substring(idx + 1).split("\\.");
String[] sipt = ip.split("\\.");
long ips = 0L, ipe = 0L, ipt = 0L;
for (int i = 0; i < 4; ++i)
{
ips = ips << 8 | Integer.parseInt(sips[i]);
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
}
if (ips > ipe)
{
long t = ips;
ips = ipe;
ipe = t;
}
return ips <= ipt && ipt <= ipe;
}
/**
* 校验ip是否符合过滤串规则
*
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
* @param ip 校验IP地址
* @return boolean 结果
*/
public static boolean isMatchedIp(String filter, String ip)
{
if (FuncBase.isEmpty(filter) || FuncBase.isEmpty(ip))
{
return false;
}
String[] ips = filter.split(";");
for (String iStr : ips)
{
if (isIP(iStr) && iStr.equals(ip))
{
return true;
}
else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
{
return true;
}
else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,194 @@
package com.jeelowcode.framework.utils.tool;
import org.springframework.lang.Nullable;
import org.springframework.util.NumberUtils;
/**
* 数字类型工具类
*/
public class NumberUtil extends NumberUtils {
//-----------------------------------------------------------------------
/**
* <p>Convert a <code>String</code> to an <code>int</code>, returning
* <code>zero</code> if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
*
* <pre>
* NumberUtil.toInt(null) = 0
* NumberUtil.toInt("") = 0
* NumberUtil.toInt("1") = 1
* </pre>
*
* @param str the string to convert, may be null
* @return the int represented by the string, or <code>zero</code> if
* conversion fails
*/
public static int toInt(final String str) {
return toInt(str, -1);
}
/**
* <p>Convert a <code>String</code> to an <code>int</code>, returning a
* default value if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, the default value is returned.</p>
*
* <pre>
* NumberUtil.toInt(null, 1) = 1
* NumberUtil.toInt("", 1) = 1
* NumberUtil.toInt("1", 0) = 1
* </pre>
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the int represented by the string, or the default if conversion fails
*/
public static int toInt(@Nullable final String str, final int defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Integer.valueOf(str);
} catch (final NumberFormatException nfe) {
return defaultValue;
}
}
/**
* <p>Convert a <code>String</code> to a <code>long</code>, returning
* <code>zero</code> if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, <code>zero</code> is returned.</p>
*
* <pre>
* NumberUtil.toLong(null) = 0L
* NumberUtil.toLong("") = 0L
* NumberUtil.toLong("1") = 1L
* </pre>
*
* @param str the string to convert, may be null
* @return the long represented by the string, or <code>0</code> if
* conversion fails
*/
public static long toLong(final String str) {
return toLong(str, 0L);
}
/**
* <p>Convert a <code>String</code> to a <code>long</code>, returning a
* default value if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, the default value is returned.</p>
*
* <pre>
* NumberUtil.toLong(null, 1L) = 1L
* NumberUtil.toLong("", 1L) = 1L
* NumberUtil.toLong("1", 0L) = 1L
* </pre>
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the long represented by the string, or the default if conversion fails
*/
public static long toLong(@Nullable final String str, final long defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Long.valueOf(str);
} catch (final NumberFormatException nfe) {
return defaultValue;
}
}
/**
* <p>Convert a <code>String</code> to a <code>Double</code>
*
* @param value value
* @return double value
*/
public static Double toDouble(String value) {
return toDouble(value, null);
}
/**
* <p>Convert a <code>String</code> to a <code>Double</code>
*
* @param value value
* @param defaultValue 默认值
* @return double value
*/
public static Double toDouble(@Nullable String value, Double defaultValue) {
if (value != null) {
return Double.valueOf(value.trim());
}
return defaultValue;
}
/**
* <p>Convert a <code>String</code> to a <code>Double</code>
*
* @param value value
* @return double value
*/
public static Float toFloat(String value) {
return toFloat(value, null);
}
/**
* <p>Convert a <code>String</code> to a <code>Double</code>
*
* @param value value
* @param defaultValue 默认值
* @return double value
*/
public static Float toFloat(@Nullable String value, Float defaultValue) {
if (value != null) {
return Float.valueOf(value.trim());
}
return defaultValue;
}
/**
* All possible chars for representing a number as a String
*/
private final static char[] DIGITS = {
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z'
};
/**
* 将 long 转短字符串 为 62 进制
*
* @param i 数字
* @return 短字符串
*/
public static String to62String(long i) {
int radix = DIGITS.length;
char[] buf = new char[65];
int charPos = 64;
i = -i;
while (i <= -radix) {
buf[charPos--] = DIGITS[(int) (-(i % radix))];
i = i / radix;
}
buf[charPos] = DIGITS[(int) (-i)];
return new String(buf, charPos, (65 - charPos));
}
}

View File

@@ -0,0 +1,32 @@
package com.jeelowcode.framework.utils.tool;
/**
* 生成的随机数类型
*
*/
public enum RandomType {
/**
* INT STRING ALL
*/
INT(RandomType.INT_STR),
STRING(RandomType.STR_STR),
ALL(RandomType.ALL_STR);
private final String factor;
/**
* 随机字符串因子
*/
private static final String INT_STR = "0123456789";
private static final String STR_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static final String ALL_STR = INT_STR + STR_STR;
public String getFactor() {
return factor;
}
RandomType(String factor) {
this.factor = factor;
}
}

View File

@@ -0,0 +1,498 @@
package com.jeelowcode.framework.utils.tool;
import com.jeelowcode.framework.utils.utils.FuncBase;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串切分器
*/
public class StrSpliter {
//---------------------------------------------------------------------------------------------- Split by char
/**
* 切分字符串路径仅支持Unix分界符/
*
* @param str 被切分的字符串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> splitPath(String str) {
return splitPath(str, 0);
}
/**
* 切分字符串路径仅支持Unix分界符/
*
* @param str 被切分的字符串
* @return 切分后的集合
* @since 3.0.8
*/
public static String[] splitPathToArray(String str) {
return toArray(splitPath(str));
}
/**
* 切分字符串路径仅支持Unix分界符/
*
* @param str 被切分的字符串
* @param limit 限制分片数
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> splitPath(String str, int limit) {
return split(str, StringPool.SLASH, limit, true, true);
}
/**
* 切分字符串路径仅支持Unix分界符/
*
* @param str 被切分的字符串
* @param limit 限制分片数
* @return 切分后的集合
* @since 3.0.8
*/
public static String[] splitPathToArray(String str, int limit) {
return toArray(splitPath(str, limit));
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> splitTrim(String str, char separator, boolean ignoreEmpty) {
return split(str, separator, 0, true, ignoreEmpty);
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> split(String str, char separator, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, 0, isTrim, ignoreEmpty);
}
/**
* 切分字符串,大小写敏感,去除每个元素两边空白符
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数,-1不限制
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> splitTrim(String str, char separator, int limit, boolean ignoreEmpty) {
return split(str, separator, limit, true, ignoreEmpty, false);
}
/**
* 切分字符串,大小写敏感
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数,-1不限制
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, limit, isTrim, ignoreEmpty, false);
}
/**
* 切分字符串,忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数,-1不限制
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> splitIgnoreCase(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, limit, isTrim, ignoreEmpty, true);
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数,-1不限制
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @param ignoreCase 是否忽略大小写
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
if (StringUtil.isEmpty(str)) {
return new ArrayList<String>(0);
}
if (limit == 1) {
return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
}
final ArrayList<String> list = new ArrayList<>(limit > 0 ? limit : 16);
int len = str.length();
int start = 0;
for (int i = 0; i < len; i++) {
if (FuncBase.equals(separator, str.charAt(i))) {
addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
start = i + 1;
//检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串
if (limit > 0 && list.size() > limit - 2) {
break;
}
}
}
return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
}
/**
* 切分字符串为字符串数组
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static String[] splitToArray(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
}
//---------------------------------------------------------------------------------------------- Split by String
/**
* 切分字符串,不忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> split(String str, String separator, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, -1, isTrim, ignoreEmpty, false);
}
/**
* 切分字符串,去除每个元素两边空格,忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> splitTrim(String str, String separator, boolean ignoreEmpty) {
return split(str, separator, true, ignoreEmpty);
}
/**
* 切分字符串,不忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, limit, isTrim, ignoreEmpty, false);
}
/**
* 切分字符串,去除每个元素两边空格,忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param limit 限制分片数
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> splitTrim(String str, String separator, int limit, boolean ignoreEmpty) {
return split(str, separator, limit, true, ignoreEmpty);
}
/**
* 切分字符串,忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> splitIgnoreCase(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, limit, isTrim, ignoreEmpty, true);
}
/**
* 切分字符串,去除每个元素两边空格,忽略大小写
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param limit 限制分片数
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> splitTrimIgnoreCase(String str, String separator, int limit, boolean ignoreEmpty) {
return split(str, separator, limit, true, ignoreEmpty, true);
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符串
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @param ignoreCase 是否忽略大小写
* @return 切分后的集合
* @since 3.2.1
*/
public static List<String> split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
if (StringUtil.isEmpty(str)) {
return new ArrayList<String>(0);
}
if (limit == 1) {
return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
}
if (StringUtil.isEmpty(separator)) {
return split(str, limit);
} else if (separator.length() == 1) {
return split(str, separator.charAt(0), limit, isTrim, ignoreEmpty, ignoreCase);
}
final ArrayList<String> list = new ArrayList<>();
int len = str.length();
int separatorLen = separator.length();
int start = 0;
int i = 0;
while (i < len) {
i = StringUtil.indexOf(str, separator, start, ignoreCase);
if (i > -1) {
addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
start = i + separatorLen;
//检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串
if (limit > 0 && list.size() > limit - 2) {
break;
}
} else {
break;
}
}
return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
}
/**
* 切分字符串为字符串数组
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static String[] splitToArray(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
}
//---------------------------------------------------------------------------------------------- Split by Whitespace
/**
* 使用空白符切分字符串<br>
* 切分后的字符串两边不包含空白符,空串或空白符串并不做为元素之一
*
* @param str 被切分的字符串
* @param limit 限制分片数
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> split(String str, int limit) {
if (StringUtil.isEmpty(str)) {
return new ArrayList<String>(0);
}
if (limit == 1) {
return addToList(new ArrayList<String>(1), str, true, true);
}
final ArrayList<String> list = new ArrayList<>();
int len = str.length();
int start = 0;
for (int i = 0; i < len; i++) {
if (FuncBase.isEmpty(str.charAt(i))) {
addToList(list, str.substring(start, i), true, true);
start = i + 1;
if (limit > 0 && list.size() > limit - 2) {
break;
}
}
}
return addToList(list, str.substring(start, len), true, true);
}
/**
* 切分字符串为字符串数组
*
* @param str 被切分的字符串
* @param limit 限制分片数
* @return 切分后的集合
* @since 3.0.8
*/
public static String[] splitToArray(String str, int limit) {
return toArray(split(str, limit));
}
//---------------------------------------------------------------------------------------------- Split by regex
/**
* 通过正则切分字符串
*
* @param str 字符串
* @param separatorPattern 分隔符正则{@link Pattern}
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static List<String> split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
if (StringUtil.isEmpty(str)) {
return new ArrayList<String>(0);
}
if (limit == 1) {
return addToList(new ArrayList<String>(1), str, isTrim, ignoreEmpty);
}
if (null == separatorPattern) {
return split(str, limit);
}
final Matcher matcher = separatorPattern.matcher(str);
final ArrayList<String> list = new ArrayList<>();
int len = str.length();
int start = 0;
while (matcher.find()) {
addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty);
start = matcher.end();
if (limit > 0 && list.size() > limit - 2) {
break;
}
}
return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
}
/**
* 通过正则切分字符串为字符串数组
*
* @param str 被切分的字符串
* @param separatorPattern 分隔符正则{@link Pattern}
* @param limit 限制分片数
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @return 切分后的集合
* @since 3.0.8
*/
public static String[] splitToArray(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty) {
return toArray(split(str, separatorPattern, limit, isTrim, ignoreEmpty));
}
//---------------------------------------------------------------------------------------------- Split by length
/**
* 根据给定长度,将给定字符串截取为多个部分
*
* @param str 字符串
* @param len 每一个小节的长度
* @return 截取后的字符串数组
*/
public static String[] splitByLength(String str, int len) {
int partCount = str.length() / len;
int lastPartCount = str.length() % len;
int fixPart = 0;
if (lastPartCount != 0) {
fixPart = 1;
}
final String[] strs = new String[partCount + fixPart];
for (int i = 0; i < partCount + fixPart; i++) {
if (i == partCount + fixPart - 1 && lastPartCount != 0) {
strs[i] = str.substring(i * len, i * len + lastPartCount);
} else {
strs[i] = str.substring(i * len, i * len + len);
}
}
return strs;
}
//---------------------------------------------------------------------------------------------------------- Private method start
/**
* 将字符串加入List中
*
* @param list 列表
* @param part 被加入的部分
* @param isTrim 是否去除两端空白符
* @param ignoreEmpty 是否略过空字符串(空字符串不做为一个元素)
* @return 列表
*/
private static List<String> addToList(List<String> list, String part, boolean isTrim, boolean ignoreEmpty) {
part = part.toString();
if (isTrim) {
part = part.trim();
}
if (false == ignoreEmpty || false == part.isEmpty()) {
list.add(part);
}
return list;
}
/**
* List转Array
*
* @param list List
* @return Array
*/
private static String[] toArray(List<String> list) {
return list.toArray(new String[list.size()]);
}
//---------------------------------------------------------------------------------------------------------- Private method end
}

View File

@@ -0,0 +1,70 @@
package com.jeelowcode.framework.utils.tool;
/**
* 静态 String 池
*/
public interface StringPool {
String AMPERSAND = "&";
String AND = "and";
String AT = "@";
String ASTERISK = "*";
String STAR = ASTERISK;
String SLASH = "/";
String BACK_SLASH = "\\";
String DOUBLE_SLASH = "#//";
String COLON = ":";
String COMMA = ",";
String DASH = "-";
String DOLLAR = "$";
String DOT = ".";
String EMPTY = "";
String EMPTY_JSON = "{}";
String EQUALS = "=";
String FALSE = "false";
String HASH = "#";
String HAT = "^";
String LEFT_BRACE = "{";
String LEFT_BRACKET = "(";
String LEFT_CHEV = "<";
String NEWLINE = "\n";
String N = "n";
String NO = "no";
String NULL = "null";
String OFF = "off";
String ON = "on";
String PERCENT = "%";
String PIPE = "|";
String PLUS = "+";
String QUESTION_MARK = "?";
String EXCLAMATION_MARK = "!";
String QUOTE = "\"";
String RETURN = "\r";
String TAB = "\t";
String RIGHT_BRACE = "}";
String RIGHT_BRACKET = ")";
String RIGHT_CHEV = ">";
String SEMICOLON = ";";
String SINGLE_QUOTE = "'";
String BACKTICK = "`";
String SPACE = " ";
String TILDA = "~";
String LEFT_SQ_BRACKET = "[";
String RIGHT_SQ_BRACKET = "]";
String TRUE = "true";
String UNDERSCORE = "_";
String UTF_8 = "UTF-8";
String GBK = "GBK";
String ISO_8859_1 = "ISO-8859-1";
String Y = "y";
String YES = "yes";
String ONE = "1";
String ZERO = "0";
String MINUS_ONE = "-1";
String DOLLAR_LEFT_BRACE= "${";
String UNKNOWN = "unknown";
String GET = "GET";
String POST = "POST";
}

View File

@@ -0,0 +1,164 @@
package com.jeelowcode.framework.utils.tool.spring;
import com.jeelowcode.framework.utils.utils.FuncBase;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* spring工具类 方便在非spring管理环境中获取bean
*
* @author ruoyi
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware
{
/** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext applicationContext;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
SpringUtils.applicationContext = applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException
{
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name)
{
return beanFactory.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到将会抛出一个异常NoSuchBeanDefinitionException
*
* @param name
* @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名则返回这些别名
*
* @param name
* @return
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getAliases(name);
}
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker)
{
return (T) AopContext.currentProxy();
}
/**
* 获取当前的环境配置无配置返回null
*
* @return 当前的环境配置
*/
public static String[] getActiveProfiles()
{
return applicationContext.getEnvironment().getActiveProfiles();
}
/**
* 获取当前的环境配置,当有多个环境配置时,只获取第一个
*
* @return 当前的环境配置
*/
public static String getActiveProfile()
{
final String[] activeProfiles = getActiveProfiles();
return FuncBase.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
}
/**
* 获取配置文件中的值
*
* @param key 配置文件的key
* @return 当前的配置文件的值
*
*/
public static String getRequiredProperty(String key)
{
return applicationContext.getEnvironment().getRequiredProperty(key);
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}

View File

@@ -0,0 +1,132 @@
package com.jeelowcode.framework.utils.utils;
import cn.hutool.core.util.CharsetUtil;
import com.jeelowcode.framework.utils.tool.IpUtils;
import com.jeelowcode.framework.utils.tool.StringUtil;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 网络工具包集合,工具类快捷方式
*
*/
public class FuncWebBase {
public static HttpServletRequest getRequest() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return requestAttributes == null ? null : ((ServletRequestAttributes)requestAttributes).getRequest();
}
//获取ip
public static String getIp(ContentCachingRequestWrapper request) {
try{
String ipAddr = IpUtils.getIpAddr(request);
return ipAddr;
}catch (Exception e){
}
return "";
}
//获取请求地址
public static String getPath(String uriStr) {
URI uri;
try {
uri = new URI(uriStr);
} catch (URISyntaxException var3) {
throw new RuntimeException(var3);
}
return uri.getPath();
}
//获取参数
public static String getRequestParams(ContentCachingRequestWrapper request) {
try {
String queryString = request.getQueryString();
if (StringUtil.isNotBlank(queryString)) {
return (new String(queryString.getBytes(CharsetUtil.ISO_8859_1), CharsetUtil.UTF_8)).replaceAll("&amp;", "&").replaceAll("%22", "\"");
} else {
String charEncoding = request.getCharacterEncoding();
if (charEncoding == null) {
charEncoding = "UTF-8";
}
byte[] buffer = getRequestBody(request.getInputStream()).getBytes();
String str = (new String(buffer, charEncoding)).trim();
if (StringUtil.isBlank(str)) {
StringBuilder sb = new StringBuilder();
Enumeration parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()) {
String key = (String)parameterNames.nextElement();
String value = request.getParameter(key);
StringUtil.appendBuilder(sb, new CharSequence[]{key, "=", value, "&"});
}
str = StringUtil.removeSuffix(sb.toString(), "&");
}
return str.replaceAll("&amp;", "&");
}
} catch (Exception var9) {
var9.printStackTrace();
return "";
}
}
//获取body参数 转为字符串
public static String getRequestBody(ServletInputStream servletInputStream) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(servletInputStream, StandardCharsets.UTF_8));
String line;
while((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException var16) {
var16.printStackTrace();
} finally {
if (servletInputStream != null) {
try {
servletInputStream.close();
} catch (IOException var15) {
var15.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException var14) {
var14.printStackTrace();
}
}
}
return sb.toString();
}
//-------------------------------
}

View File

@@ -0,0 +1,167 @@
package com.jeelowcode.framework.utils.utils;
import cn.hutool.core.date.DateUtil;
import java.sql.Time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JeeLowCodeUtils {
/**
* 使用正则获取所有的key
* 获取sql中的#{key} 这个key组成的set
*/
public static Set<String> getSqlRuleParams(String sql) {
if (FuncBase.isEmpty(sql)) {
return null;
}
Set<String> varParams = new HashSet<String>();
String regex = "\\#\\{\\w+\\}";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(sql);
while (m.find()) {
String group = m.group();
varParams.add(group.substring(group.indexOf("{") + 1, group.indexOf("}")));
}
return varParams;
}
/**
* 获取map值
* (map的value是单个的数据时使用)
*
* @param map 查询封装的一条数据
* @param key 高查条件的key
* @return
*/
public static String getMap2Str(Map<String, Object> map, String key) {
// 参数校验:
if (FuncBase.isEmpty(key) || FuncBase.isEmpty(map)) {
return "";
}
// 根据高查条件的key获取value
Object o = map.get(key);
if (FuncBase.isEmpty(o)) {
return "";
}
// object -> String
String value = FuncBase.toStr(o);
// 返回
return value;
}
public static List<String> getMap2List(Map<String, Object> map, String key) {
// 参数校验:
if (FuncBase.isEmpty(key) || FuncBase.isEmpty(map)) {
return null;
}
// 根据高查条件的key获取value
Object o = map.get(key);
return (List<String>)o;
}
/**
* 获取map值
*
* @param map
* @param key
* @return
*/
public static Integer getMap2Integer(Map<String, Object> map, String key) {
String str = getMap2Str(map, key);
if (FuncBase.isEmpty(str)) {
return -1;
}
return FuncBase.toInt(str);
}
/**
* 获取map值
*
* @param map
* @param key
* @return
*/
public static Long getMap2Long(Map<String, Object> map, String key) {
String str = getMap2Str(map, key);
if (FuncBase.isEmpty(str)) {
return -1L;
}
return FuncBase.toLong(str);
}
/**
* 获取map值
* (map的value是单个的数据时使用)
*
* @param map 查询封装的一条数据
* @param key 高查条件的key
* @return
*/
public static Date getMap2DateTime(Map<String, Object> map, String key) {
// 参数校验:
if (FuncBase.isEmpty(key) || FuncBase.isEmpty(map)) {
return null;
}
// 根据高查条件的key获取value
Object o = map.get(key);
if (FuncBase.isEmpty(o)) {
return null;
}
if (o instanceof Date) {
if (o instanceof java.sql.Date || o instanceof Time) {
return new Date(((Date) o).getTime());
}
return (Date) o;
}
// object -> String
String value = FuncBase.toStr(o);
return DateUtil.parseDateTime(value);
}
/**
* 获取map值
*
* @param map
* @param key
* @return
*/
public static Map<String, Object> getMap2Map(Map<String, Object> map, String key) {
if (FuncBase.isEmpty(key) || FuncBase.isEmpty(map)) {
return null;
}
return (Map<String, Object>)map.get(key);
}
// 提取日期时间格式化逻辑到单独的方法
public static String formatDate(Object value) {
if (value instanceof LocalDateTime) {
return ((LocalDateTime) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} else if (value instanceof LocalDate) {
return ((LocalDate) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
} else if (value instanceof LocalTime) {
return ((LocalTime) value).format(DateTimeFormatter.ofPattern("HH:mm:ss"));
} else if (value instanceof java.sql.Time) {
return ((java.sql.Time) value).toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
} else if (value instanceof java.sql.Timestamp) {
return ((java.sql.Timestamp) value).toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} else if (value instanceof Date) {
return DateUtil.formatDate((Date)value);
} else {
return FuncBase.toStr(value);
}
}
}

View File

@@ -0,0 +1,6 @@
com.jeelowcode.framework.utils.component.JeeLowCodeAutoConfiguration
com.jeelowcode.framework.utils.component.redis.JeeLowCodeRedisConfiguration
com.jeelowcode.framework.utils.component.redis.JeeLowCodeRedisUtils
com.jeelowcode.framework.utils.component.pool.SyncPoolConfiguration
com.jeelowcode.framework.utils.global.exeption.JeeLowCodeGlobalExceptionHandler
com.jeelowcode.framework.utils.global.body.GlobalJeeLowCodeResponseBodyHandler