后端升级到2.4.3版本
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jero-boot-base-api</artifactId>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+7
-3
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -438,7 +439,10 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
@GetMapping("/sys/api/listSonDepartsByDepId")
|
||||
List<SysDepartTreeModel> listSonDepartsByDepId(@RequestParam("departId") String departId);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 41 获取公司下级部门和公司下所有用户id
|
||||
* @param orgCode
|
||||
*/
|
||||
@GetMapping("/sys/api/getDeptUserByOrgCode")
|
||||
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode);
|
||||
}
|
||||
|
||||
+6
@@ -9,6 +9,7 @@ import com.jero.common.system.api.ISysBaseAPI;
|
||||
import com.jero.common.system.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -269,6 +270,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map> getDeptUserByOrgCode(String orgCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> queryDepartsByOrgIds(String ids) {
|
||||
return null;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jero-boot-base-api</artifactId>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+6
@@ -7,6 +7,7 @@ import com.jero.common.api.dto.message.*;
|
||||
import com.jero.common.system.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -299,4 +300,9 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
*/
|
||||
List<SysDepartTreeModel> listSonDepartsByDepId(String departId);
|
||||
|
||||
/**
|
||||
* 43 获取公司下级部门和公司下所有用户信息
|
||||
* @param orgCode
|
||||
*/
|
||||
List<Map> getDeptUserByOrgCode(String orgCode);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jero-boot-base</artifactId>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<artifactId>jero-boot-base</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -156,16 +156,6 @@
|
||||
<artifactId>shiro-spring-boot-starter</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- shiro-redis -->
|
||||
<dependency>
|
||||
<groupId>org.crazycake</groupId>
|
||||
@@ -186,16 +176,6 @@
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- AutoPoi Excel工具类-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ public class PermissionDataAspect {
|
||||
String url = "";
|
||||
if(oConvertUtils.isNotEmpty(requestPath)){
|
||||
url = requestPath.replace("\\", "/");
|
||||
url = requestPath.replace("//", "/");
|
||||
url = url.replace("//", "/");
|
||||
if(url.indexOf("//")>=0){
|
||||
url = filterUrl(url);
|
||||
}
|
||||
|
||||
+2
-2
@@ -265,7 +265,7 @@ public interface CommonConstant {
|
||||
/**
|
||||
* 在线聊天 用户好友缓存前缀
|
||||
*/
|
||||
public static final String IM_PREFIX_USER_FRIEND_CACHE = "im_prefix_user_friend_";
|
||||
public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
|
||||
|
||||
/**
|
||||
* 考勤补卡业务状态 (1:同意 2:不同意)
|
||||
@@ -294,7 +294,7 @@ public interface CommonConstant {
|
||||
/**
|
||||
* 多租户 请求头
|
||||
*/
|
||||
public final static String TENANT_ID = "tenant_id";
|
||||
public final static String TENANT_ID = "tenant-id";
|
||||
|
||||
/**
|
||||
* 微服务读取配置文件属性 服务地址
|
||||
|
||||
+2
-1
@@ -13,7 +13,8 @@ public interface CommonSendStatus {
|
||||
|
||||
public static final String REVOKE_STATUS_2 = "2"; //撤销
|
||||
|
||||
|
||||
//app端推送会话标识后缀
|
||||
public static final String APP_SESSION_SUFFIX = "_app"; //app端推送会话标识后缀
|
||||
|
||||
/**流程催办——系统通知消息模板*/
|
||||
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ public interface DataBaseConstant {
|
||||
//*********数据库类型****************************************
|
||||
public static final String DB_TYPE_MYSQL = "MYSQL";
|
||||
public static final String DB_TYPE_ORACLE = "ORACLE";
|
||||
public static final String DB_TYPE_DM = "DM";//达梦数据库
|
||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||
|
||||
|
||||
+53
-4
@@ -1,6 +1,8 @@
|
||||
package com.jero.common.system.base.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
@@ -13,6 +15,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -23,11 +26,8 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: Controller基类
|
||||
* @Author: dangzhenghui@163.com
|
||||
@@ -77,6 +77,55 @@ public class JeroController<T, S extends IService<T>> {
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据每页sheet数量导出多sheet
|
||||
*
|
||||
* @param request
|
||||
* @param object 实体类
|
||||
* @param clazz 实体类class
|
||||
* @param title 标题
|
||||
* @param exportFields 导出字段自定义
|
||||
* @param pageNum 每个sheet的数据条数
|
||||
* @param request
|
||||
*/
|
||||
protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields,Integer pageNum) {
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// Step.2 计算分页sheet数据
|
||||
double total = service.count();
|
||||
int count = (int)Math.ceil(total/pageNum);
|
||||
// Step.3 多sheet处理
|
||||
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 1; i <=count ; i++) {
|
||||
Page<T> page = new Page<T>(i, pageNum);
|
||||
IPage<T> pageList = service.page(page, queryWrapper);
|
||||
List<T> records = pageList.getRecords();
|
||||
List<T> exportList = null;
|
||||
// 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
exportList = records.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
|
||||
} else {
|
||||
exportList = records;
|
||||
}
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath);
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
//map.put("title",exportParams);//表格Title
|
||||
map.put(NormalExcelConstants.PARAMS,exportParams);//表格Title
|
||||
map.put(NormalExcelConstants.CLASS,clazz);//表格对应实体
|
||||
map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
|
||||
listMap.add(map);
|
||||
}
|
||||
// Step.4 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
|
||||
mv.addObject(NormalExcelConstants.MAP_LIST, listMap);
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据权限导出excel,传入导出字段参数
|
||||
*
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Long转json精度丢失是配置
|
||||
* 添加Long转json精度丢失的配置
|
||||
* @Return: void
|
||||
*/
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -238,7 +238,7 @@ public class ShiroConfig {
|
||||
}
|
||||
manager = redisManager;
|
||||
}else{
|
||||
// redis 集群支持,优先使用集群配置 add by jzyadmin@163.com
|
||||
// redis 集群支持,优先使用集群配置
|
||||
RedisClusterManager redisManager = new RedisClusterManager();
|
||||
Set<HostAndPort> portSet = new HashSet<>();
|
||||
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jero-boot-base</artifactId>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<description>代码生成核心模块</description>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jero-boot-base</artifactId>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -17,10 +17,23 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<artifactId>jero-system-local-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<artifactId>jero-boot-base</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<description>公共模块</description>
|
||||
@@ -17,6 +17,15 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<!--加载hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.jero.common.modules.redis.client;
|
||||
|
||||
import com.jero.common.base.BaseMap;
|
||||
import com.jero.common.constant.GlobalConstants;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* redis客户端
|
||||
*/
|
||||
@Configuration
|
||||
public class JeroRedisClient {
|
||||
|
||||
@Resource(name = "starterRedisTemplate")
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param handlerName
|
||||
* @param params
|
||||
*/
|
||||
public void sendMessage(String handlerName, BaseMap params) {
|
||||
params.put(GlobalConstants.HANDLER_NAME, handlerName);
|
||||
redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key查询缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public <T> T get(String key) {
|
||||
return key == null ? null : (T) redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.jero.common.modules.redis.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jero.common.modules.redis.service.RedisReceiver;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.jero.common.modules.redis.prop.JeroRedisProperties;
|
||||
import com.jero.common.constant.GlobalConstants;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.listener.ChannelTopic;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* redis配置
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(JeroRedisProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.redis.enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class RedisConfiguration {
|
||||
|
||||
|
||||
/**
|
||||
* RedisTemplate配置
|
||||
*
|
||||
* @param lettuceConnectionFactory
|
||||
* @return
|
||||
*/
|
||||
@Bean("starterRedisTemplate")
|
||||
public RedisTemplate<String, Object> starterRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
||||
log.info(" --- redis config init --- ");
|
||||
// 设置序列化
|
||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||
// 配置redisTemplate
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
||||
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
|
||||
redisTemplate.setKeySerializer(stringSerializer);// key序列化
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
|
||||
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
|
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* redis 监听配置
|
||||
*
|
||||
* @param redisConnectionFactory redis 配置
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, RedisReceiver redisReceiver, MessageListenerAdapter commonListenerAdapter) {
|
||||
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
|
||||
container.setConnectionFactory(redisConnectionFactory);
|
||||
container.addMessageListener(commonListenerAdapter, new ChannelTopic(GlobalConstants.REDIS_TOPIC_NAME));
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
MessageListenerAdapter commonListenerAdapter(RedisReceiver redisReceiver) {
|
||||
MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(redisReceiver, "onMessage");
|
||||
messageListenerAdapter.setSerializer(jacksonSerializer());
|
||||
return messageListenerAdapter;
|
||||
}
|
||||
|
||||
private Jackson2JsonRedisSerializer jacksonSerializer() {
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
||||
return jackson2JsonRedisSerializer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.jero.common.modules.redis.listener;
|
||||
|
||||
import com.jero.common.base.BaseMap;
|
||||
|
||||
/**
|
||||
* 自定义消息监听
|
||||
*/
|
||||
public interface JeroRedisListerer {
|
||||
|
||||
void onMessage(BaseMap message);
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.jero.common.modules.redis.prop;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* redis配置
|
||||
*
|
||||
* @author pangu
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(JeroRedisProperties.PREFIX)
|
||||
public class JeroRedisProperties {
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
public static final String PREFIX = "spring.redis";
|
||||
/**
|
||||
* 是否开启Lettuce
|
||||
*/
|
||||
private Boolean enable = true;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.jero.common.modules.redis.service;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.jero.common.modules.redis.listener.JeroRedisListerer;
|
||||
import lombok.Data;
|
||||
import com.jero.common.base.BaseMap;
|
||||
import com.jero.common.constant.GlobalConstants;
|
||||
import com.jero.common.util.SpringContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
public class RedisReceiver {
|
||||
|
||||
|
||||
/**
|
||||
* 接受消息并调用业务逻辑处理器
|
||||
*
|
||||
* @param params
|
||||
*/
|
||||
public void onMessage(BaseMap params) {
|
||||
Object handlerName = params.get(GlobalConstants.HANDLER_NAME);
|
||||
JeroRedisListerer messageListener = SpringContextHolder.getHandler(handlerName.toString(), JeroRedisListerer.class);
|
||||
if (ObjectUtil.isNotEmpty(messageListener)) {
|
||||
messageListener.onMessage(params);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
package com.jero.common.modules.redis.write;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.dao.PessimisticLockingFailureException;
|
||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* 该类参照 DefaultRedisCacheWriter 重写了 remove 方法实现通配符*删除
|
||||
*/
|
||||
@Slf4j
|
||||
public class JeroRedisCacheWriter implements RedisCacheWriter {
|
||||
|
||||
private final RedisConnectionFactory connectionFactory;
|
||||
private final Duration sleepTime;
|
||||
|
||||
public JeroRedisCacheWriter(RedisConnectionFactory connectionFactory) {
|
||||
this(connectionFactory, Duration.ZERO);
|
||||
}
|
||||
|
||||
public JeroRedisCacheWriter(RedisConnectionFactory connectionFactory, Duration sleepTime) {
|
||||
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
|
||||
Assert.notNull(sleepTime, "SleepTime must not be null!");
|
||||
this.connectionFactory = connectionFactory;
|
||||
this.sleepTime = sleepTime;
|
||||
}
|
||||
|
||||
public void put(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
this.execute(name, (connection) -> {
|
||||
if (shouldExpireWithin(ttl)) {
|
||||
connection.set(key, value, Expiration.from(ttl.toMillis(), TimeUnit.MILLISECONDS), SetOption.upsert());
|
||||
} else {
|
||||
connection.set(key, value);
|
||||
}
|
||||
|
||||
return "OK";
|
||||
});
|
||||
}
|
||||
|
||||
public byte[] get(String name, byte[] key) {
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
return (byte[])this.execute(name, (connection) -> {
|
||||
return connection.get(key);
|
||||
});
|
||||
}
|
||||
|
||||
public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
return (byte[])this.execute(name, (connection) -> {
|
||||
if (this.isLockingCacheWriter()) {
|
||||
this.doLock(name, connection);
|
||||
}
|
||||
|
||||
Object var7;
|
||||
try {
|
||||
boolean put;
|
||||
if (shouldExpireWithin(ttl)) {
|
||||
put = connection.set(key, value, Expiration.from(ttl), SetOption.ifAbsent());
|
||||
} else {
|
||||
put = connection.setNX(key, value);
|
||||
}
|
||||
|
||||
if (!put) {
|
||||
byte[] var11 = connection.get(key);
|
||||
return var11;
|
||||
}
|
||||
|
||||
var7 = null;
|
||||
} finally {
|
||||
if (this.isLockingCacheWriter()) {
|
||||
this.doUnlock(name, connection);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (byte[])var7;
|
||||
});
|
||||
}
|
||||
|
||||
public void remove(String name, byte[] key) {
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
String keyString = new String(key);
|
||||
log.info("redis remove key:" + keyString);
|
||||
if(keyString!=null && keyString.endsWith("*")){
|
||||
execute(name, connection -> {
|
||||
// 获取某个前缀所拥有的所有的键,某个前缀开头,后面肯定是*
|
||||
Set<byte[]> keys = connection.keys(key);
|
||||
int delNum = 0;
|
||||
for (byte[] keyByte : keys) {
|
||||
delNum += connection.del(keyByte);
|
||||
}
|
||||
return delNum;
|
||||
});
|
||||
}else{
|
||||
this.execute(name, (connection) -> {
|
||||
return connection.del(new byte[][]{key});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void clean(String name, byte[] pattern) {
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
Assert.notNull(pattern, "Pattern must not be null!");
|
||||
this.execute(name, (connection) -> {
|
||||
boolean wasLocked = false;
|
||||
|
||||
try {
|
||||
if (this.isLockingCacheWriter()) {
|
||||
this.doLock(name, connection);
|
||||
wasLocked = true;
|
||||
}
|
||||
|
||||
byte[][] keys = (byte[][])((Set)Optional.ofNullable(connection.keys(pattern)).orElse(Collections.emptySet())).toArray(new byte[0][]);
|
||||
if (keys.length > 0) {
|
||||
connection.del(keys);
|
||||
}
|
||||
} finally {
|
||||
if (wasLocked && this.isLockingCacheWriter()) {
|
||||
this.doUnlock(name, connection);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return "OK";
|
||||
});
|
||||
}
|
||||
|
||||
void lock(String name) {
|
||||
this.execute(name, (connection) -> {
|
||||
return this.doLock(name, connection);
|
||||
});
|
||||
}
|
||||
|
||||
void unlock(String name) {
|
||||
this.executeLockFree((connection) -> {
|
||||
this.doUnlock(name, connection);
|
||||
});
|
||||
}
|
||||
|
||||
private Boolean doLock(String name, RedisConnection connection) {
|
||||
return connection.setNX(createCacheLockKey(name), new byte[0]);
|
||||
}
|
||||
|
||||
private Long doUnlock(String name, RedisConnection connection) {
|
||||
return connection.del(new byte[][]{createCacheLockKey(name)});
|
||||
}
|
||||
|
||||
boolean doCheckLock(String name, RedisConnection connection) {
|
||||
return connection.exists(createCacheLockKey(name));
|
||||
}
|
||||
|
||||
private boolean isLockingCacheWriter() {
|
||||
return !this.sleepTime.isZero() && !this.sleepTime.isNegative();
|
||||
}
|
||||
|
||||
private <T> T execute(String name, Function<RedisConnection, T> callback) {
|
||||
RedisConnection connection = this.connectionFactory.getConnection();
|
||||
|
||||
try {
|
||||
this.checkAndPotentiallyWaitUntilUnlocked(name, connection);
|
||||
return callback.apply(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void executeLockFree(Consumer<RedisConnection> callback) {
|
||||
RedisConnection connection = this.connectionFactory.getConnection();
|
||||
|
||||
try {
|
||||
callback.accept(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkAndPotentiallyWaitUntilUnlocked(String name, RedisConnection connection) {
|
||||
if (this.isLockingCacheWriter()) {
|
||||
try {
|
||||
while(this.doCheckLock(name, connection)) {
|
||||
Thread.sleep(this.sleepTime.toMillis());
|
||||
}
|
||||
|
||||
} catch (InterruptedException var4) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new PessimisticLockingFailureException(String.format("Interrupted while waiting to unlock cache %s", name), var4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldExpireWithin(@Nullable Duration ttl) {
|
||||
return ttl != null && !ttl.isZero() && !ttl.isNegative();
|
||||
}
|
||||
|
||||
private static byte[] createCacheLockKey(String name) {
|
||||
return (name + "~lock").getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
-1
@@ -6,7 +6,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.jero.common.exception.JeroBootException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.jero.boot</groupId>
|
||||
<artifactId>jero-boot</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<version>2.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user