mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-21 18:45:57 +08:00
Pre Merge pull request !373 from 守望/base
This commit is contained in:
commit
048567a5c3
@ -0,0 +1,128 @@
|
|||||||
|
package org.dromara.common.json.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class JacksonJsonUtil {
|
||||||
|
private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
static {
|
||||||
|
//对象的所有字段全部列入
|
||||||
|
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);
|
||||||
|
|
||||||
|
//取消默认转换timesstamps(时间戳)形式
|
||||||
|
OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
||||||
|
|
||||||
|
//忽略空bean转json错误
|
||||||
|
OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||||
|
|
||||||
|
//忽略在json字符串中存在,在java类中不存在字段,防止错误
|
||||||
|
OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String objToJson(T obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return obj instanceof String ? (String)obj : OBJECT_MAPPER.writeValueAsString(obj);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("obj To json is error" , e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回格式化好的json串
|
||||||
|
* @param obj
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> String objToJsonPretty(T obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return obj instanceof String ? (String)obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("obj To json pretty is error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T json2Object(String json, Class<T> clazz) {
|
||||||
|
if (StringUtils.isEmpty(json) || clazz == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return clazz.equals(String.class) ? (T)json : OBJECT_MAPPER.readValue(json, clazz);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("json To obj is error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 TypeReference 处理List<User>这类多泛型问题
|
||||||
|
* @param json
|
||||||
|
* @param typeReference
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> T json2Object(String json, TypeReference typeReference) {
|
||||||
|
if (StringUtils.isEmpty(json) || typeReference == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (T)(typeReference.getType().equals(String.class) ? json : OBJECT_MAPPER.readValue(json, typeReference));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("json To obj is error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过jackson 的javatype 来处理多泛型的转换
|
||||||
|
* @param json
|
||||||
|
* @param collectionClazz
|
||||||
|
* @param elements
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> T json2Object(String json, Class<?> collectionClazz, Class<?>...elements) {
|
||||||
|
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClazz, elements);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return OBJECT_MAPPER.readValue(json, javaType);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("json To obj is error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Map toLinkedHashMap(String jsonStr) {
|
||||||
|
|
||||||
|
Map<String, String> data = null;
|
||||||
|
try {
|
||||||
|
data = OBJECT_MAPPER.readValue(jsonStr, new TypeReference<LinkedHashMap<String, String>>() {});
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
import org.dromara.common.core.factory.YmlPropertySourceFactory;
|
import org.dromara.common.core.factory.YmlPropertySourceFactory;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.MySqlInjector;
|
||||||
import org.dromara.common.mybatis.handler.InjectionMetaObjectHandler;
|
import org.dromara.common.mybatis.handler.InjectionMetaObjectHandler;
|
||||||
import org.dromara.common.mybatis.interceptor.PlusDataPermissionInterceptor;
|
import org.dromara.common.mybatis.interceptor.PlusDataPermissionInterceptor;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
@ -82,6 +83,14 @@ public class MybatisPlusConfig {
|
|||||||
return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
|
return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全量更新
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public MySqlInjector sqlInjector() {
|
||||||
|
return new MySqlInjector();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* PaginationInnerInterceptor 分页插件,自动识别数据库类型
|
* PaginationInnerInterceptor 分页插件,自动识别数据库类型
|
||||||
* https://baomidou.com/pages/97710a/
|
* https://baomidou.com/pages/97710a/
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
|||||||
* @since 2021-05-13
|
* @since 2021-05-13
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public interface BaseMapperPlus<T, V> extends BaseMapper<T> {
|
public interface BaseMapperPlus<T, V> extends CommonMapper<T> {
|
||||||
|
|
||||||
Log log = LogFactory.getLog(BaseMapperPlus.class);
|
Log log = LogFactory.getLog(BaseMapperPlus.class);
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
package org.dromara.common.mybatis.core.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author warden
|
||||||
|
* @Date 2023/1/17 17:37
|
||||||
|
*/
|
||||||
|
public interface CommonMapper<T> extends BaseMapper<T> {
|
||||||
|
/**
|
||||||
|
* 全量插入,等价于insert
|
||||||
|
* {@link com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn}
|
||||||
|
*
|
||||||
|
* @param entityList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int insertBatchSomeColumn(List<T> entityList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全量更新,不忽略null字段,等价于update
|
||||||
|
* 解决mybatis-plus会自动忽略null字段不更新
|
||||||
|
* {@link com.baomidou.mybatisplus.extension.injector.methods.AlwaysUpdateSomeColumnById}
|
||||||
|
*
|
||||||
|
* @param entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package org.dromara.common.mybatis.core.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||||
|
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
|
import com.baomidou.mybatisplus.extension.injector.methods.AlwaysUpdateSomeColumnById;
|
||||||
|
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义Sql注入
|
||||||
|
*
|
||||||
|
* @author nieqiurong 2018/8/11 20:23.
|
||||||
|
*/
|
||||||
|
public class MySqlInjector extends DefaultSqlInjector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||||
|
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以下 3 个为内置选装件
|
||||||
|
* 头 2 个支持字段筛选函数
|
||||||
|
*/
|
||||||
|
// 例: 不要指定了 update 填充的字段
|
||||||
|
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
|
||||||
|
// 标识了INSERT的字段不更新(createTime 和 createBy)
|
||||||
|
methodList.add(new AlwaysUpdateSomeColumnById(i -> i.getFieldFill() != FieldFill.INSERT));
|
||||||
|
return methodList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
package org.dromara.common.mybatis.core.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author warden
|
||||||
|
* @Date 2022/12/8 14:56
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class BeanUtil {
|
||||||
|
public static final String ADD = "ADD";
|
||||||
|
public static final String REMOVE = "REMOVE";
|
||||||
|
public static final String NORMAL = "NORMAL";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比对两条记录数据库字段是否相同,相同返回true,不同返回false
|
||||||
|
*
|
||||||
|
* @param compare
|
||||||
|
* @param current
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean diffObject(Object compare, Object current) {
|
||||||
|
List<Field> fieldList = new ArrayList<>();
|
||||||
|
|
||||||
|
Field[] allFields = ReflectUtil.getFieldsDirectly(compare.getClass(), true);
|
||||||
|
|
||||||
|
String[] dontCompareFields = {"createBy", "createTime", "updateBy", "updateTime", "params", "searchValue", "serialVersionUID"};
|
||||||
|
List<String> dCList = new ArrayList<>();
|
||||||
|
dCList.addAll(Arrays.asList(dontCompareFields));
|
||||||
|
for (Field field : allFields) {
|
||||||
|
if (dCList.contains(field.getName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TableField tableField = field.getAnnotation(TableField.class);
|
||||||
|
if (tableField == null || tableField.exist()) {
|
||||||
|
fieldList.add(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Field field : fieldList) {
|
||||||
|
try {
|
||||||
|
//抑制Java对其的检查
|
||||||
|
field.setAccessible(true);
|
||||||
|
|
||||||
|
//获取 object 中 field 所代表的属性值
|
||||||
|
Object comp = field.get(compare);
|
||||||
|
Object curr = field.get(current);
|
||||||
|
if (comp != null && curr != null) {
|
||||||
|
if (!comp.toString().equals(curr.toString())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((comp == null && curr != null) || (comp != null && curr == null)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较原List与现List的差异,返回Map
|
||||||
|
* Map的三个KEY值:ADD(新增)\REMOVE(删除)\NORMAL(相同)
|
||||||
|
*
|
||||||
|
* @param compareList 需要比较的list(页面传过来的)
|
||||||
|
* @param currList 当前的list(当前数据库中的)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, Set<Long>> diffList(Set<Long> compareList, Set<Long> currList) {
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(compareList) && CollectionUtil.isEmpty(currList)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Set<Long>> result = new HashMap();
|
||||||
|
|
||||||
|
result.put(ADD, new HashSet<Long>());
|
||||||
|
result.put(REMOVE, new HashSet<Long>());
|
||||||
|
result.put(NORMAL, new HashSet<Long>());
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(compareList)) {
|
||||||
|
result.put(REMOVE, currList);
|
||||||
|
} else if (CollectionUtil.isEmpty(currList)) {
|
||||||
|
result.put(ADD, compareList);
|
||||||
|
} else {
|
||||||
|
for (Long comStr : compareList) {
|
||||||
|
if (currList.contains(comStr)) {
|
||||||
|
result.get(NORMAL).add(comStr);
|
||||||
|
} else {
|
||||||
|
result.get(ADD).add(comStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Long currStr : currList) {
|
||||||
|
if (compareList.contains(currStr)) {
|
||||||
|
result.get(NORMAL).add(currStr);
|
||||||
|
} else {
|
||||||
|
result.get(REMOVE).add(currStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map diffList(List<Long> compareList, List<Long> currList) {
|
||||||
|
Set<Long> compareSet = new HashSet<>();
|
||||||
|
Set<Long> currSet = new HashSet<>();
|
||||||
|
|
||||||
|
if (CollectionUtil.isNotEmpty(compareList)) {
|
||||||
|
for (Long val : compareList) {
|
||||||
|
compareSet.add(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtil.isNotEmpty(currList)) {
|
||||||
|
for (Long val : currList) {
|
||||||
|
currSet.add(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return diffList(compareSet, currSet);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void fillValue(Object object) {
|
||||||
|
if (object instanceof BaseEntity) {
|
||||||
|
BaseEntity baseEntity = (BaseEntity) object;
|
||||||
|
Date current = ObjectUtil.isNotNull(baseEntity.getCreateTime())
|
||||||
|
? baseEntity.getCreateTime() : new Date();
|
||||||
|
baseEntity.setCreateTime(current);
|
||||||
|
baseEntity.setUpdateTime(current);
|
||||||
|
Long userId = baseEntity.getCreateBy() != null
|
||||||
|
? baseEntity.getCreateBy() : getLoginUserId();
|
||||||
|
// 当前已登录 且 创建人为空 则填充
|
||||||
|
baseEntity.setCreateBy(userId);
|
||||||
|
// 当前已登录 且 更新人为空 则填充
|
||||||
|
baseEntity.setUpdateBy(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录用户名
|
||||||
|
*/
|
||||||
|
private static Long getLoginUserId() {
|
||||||
|
LoginUser loginUser;
|
||||||
|
try {
|
||||||
|
loginUser = LoginHelper.getLoginUser();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("自动注入警告 => 用户未登录");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return loginUser.getUserId();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,286 @@
|
|||||||
|
package org.dromara.common.mybatis.core.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
import org.dromara.common.mybatis.core.mapper.CommonMapper;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比对列表数据,用于判断差异并保存到数据库中
|
||||||
|
* 全量保存
|
||||||
|
*/
|
||||||
|
public class SaveDiffUtil {
|
||||||
|
// 获取mybatisplus 的ID生成器
|
||||||
|
private final static IdentifierGenerator IDENTIFIER_GENERATOR = SpringUtils.getBean("idGenerator");
|
||||||
|
|
||||||
|
public static Map<String, Set<Long>> saveFormDiff(List formList, List oriList, BaseMapper mapper) {
|
||||||
|
return saveFormDiff(formList, oriList, mapper, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Set<Long>> saveFormDiff(List formList, List oriList, BaseMapper mapper, Boolean exeUpdate) {
|
||||||
|
return saveFormDiff(formList, oriList, mapper, exeUpdate, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要处理手工修改的记录
|
||||||
|
*
|
||||||
|
* @param formList 表单提交的数据
|
||||||
|
* @param oriList 数据库数据
|
||||||
|
* @param mapper 处理实体的mapper
|
||||||
|
* @param exeUpdate 是否执行更新
|
||||||
|
* @param updateAll 更新操作是否全字段更新
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static Map<String, Set<Long>> saveFormDiff(List formList, List oriList, BaseMapper mapper,
|
||||||
|
Boolean exeUpdate, Boolean updateAll) {
|
||||||
|
if (exeUpdate == null) {
|
||||||
|
exeUpdate = false;
|
||||||
|
}
|
||||||
|
if (updateAll == null) {
|
||||||
|
updateAll = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (formList == null) {
|
||||||
|
formList = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Set<Long>> result = getFormDiff(formList, oriList);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
Set<Long> addList = result.get(BeanUtil.ADD);
|
||||||
|
Set<Long> removeList = result.get(BeanUtil.REMOVE);
|
||||||
|
Set<Long> updateList = result.get(BeanUtil.NORMAL);
|
||||||
|
|
||||||
|
// 添加的对象
|
||||||
|
if (addList != null && addList.size() > 0) {
|
||||||
|
List addObjList = new ArrayList();
|
||||||
|
for (Long id : addList) {
|
||||||
|
Iterator it = formList.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Object obj = it.next();
|
||||||
|
Long objId = (Long) ReflectUtil.getFieldValue(obj, "id");
|
||||||
|
if (id.equals(objId)) {
|
||||||
|
addObjList.add(obj);
|
||||||
|
// it.remove(); 不可删除,需要返回
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addObjList != null && addObjList.size() > 0) {
|
||||||
|
// List list = cn.hutool.core.bean.BeanUtil.copyToList(addObjList, clz);
|
||||||
|
((BaseMapperPlus) mapper).insertBatch(addObjList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeList != null && removeList.size() > 0) {
|
||||||
|
mapper.deleteBatchIds(removeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exeUpdate && updateList != null && updateList.size() > 0) {
|
||||||
|
List updateObjList = new ArrayList();
|
||||||
|
|
||||||
|
for (Long id : updateList) {
|
||||||
|
Object compareObj = findObj(formList, id);
|
||||||
|
Object currObj = findObj(oriList, id);
|
||||||
|
|
||||||
|
// 比对数据库字段是否有修改
|
||||||
|
boolean diff = BeanUtil.diffObject(compareObj, currObj);
|
||||||
|
if (!diff) {
|
||||||
|
updateObjList.add(compareObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateObjList.size() > 0) {
|
||||||
|
for (Object obj : updateObjList) {
|
||||||
|
if (updateAll) {
|
||||||
|
// 全量更新
|
||||||
|
((CommonMapper) mapper).alwaysUpdateSomeColumnById(obj);
|
||||||
|
} else {
|
||||||
|
// 更新不为空
|
||||||
|
mapper.updateById(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Set<Long>> getFormDiff(List formList, List oriList) {
|
||||||
|
// 需要比较的
|
||||||
|
List<Long> compareList = new ArrayList<>();
|
||||||
|
// 原始数据
|
||||||
|
List<Long> currList = new ArrayList<>();
|
||||||
|
|
||||||
|
updateObject(formList, compareList);
|
||||||
|
updateObject(oriList, currList);
|
||||||
|
|
||||||
|
Map<String, Set<Long>> result = BeanUtil.diffList(compareList, currList);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void updateObject(List objList, List targetList, String idFieldName) {
|
||||||
|
if (idFieldName == null) {
|
||||||
|
idFieldName = "id";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object obj : objList) {
|
||||||
|
Object val = ReflectUtil.getFieldValue(obj, idFieldName);
|
||||||
|
if (val != null) {
|
||||||
|
targetList.add(val);
|
||||||
|
} else {
|
||||||
|
Long uuid = IDENTIFIER_GENERATOR.nextId(obj).longValue();
|
||||||
|
targetList.add(uuid);
|
||||||
|
ReflectUtil.setFieldValue(obj, "id", uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateObject(List objList, List targetList) {
|
||||||
|
updateObject(objList, targetList, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据查询的属性找对象的key并赋值到目标列表中
|
||||||
|
*
|
||||||
|
* @param oriList
|
||||||
|
* @param targetList
|
||||||
|
* @param searchFieldName
|
||||||
|
* @param idFieldName
|
||||||
|
*/
|
||||||
|
public static void updateObject(List oriList, List targetList, String searchFieldName, String idFieldName) {
|
||||||
|
if (oriList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Object oriObj : oriList) {
|
||||||
|
Object searchStr = ReflectUtil.getFieldValue(oriObj, searchFieldName);
|
||||||
|
|
||||||
|
if (searchStr != null) {
|
||||||
|
for (Object tarObj : targetList) {
|
||||||
|
Object tarStr = ReflectUtil.getFieldValue(tarObj, searchFieldName);
|
||||||
|
if (searchStr.equals(tarStr)) {
|
||||||
|
Object idStr = ReflectUtil.getFieldValue(oriObj, idFieldName);
|
||||||
|
if (idStr != null) {
|
||||||
|
ReflectUtil.setFieldValue(tarObj, idFieldName, idStr);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据属性及属性值,从列表中查找对象
|
||||||
|
*
|
||||||
|
* @param objList
|
||||||
|
* @param idFieldName
|
||||||
|
* @param keyValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static Object findObj(List objList, String idFieldName, Object keyValue) {
|
||||||
|
|
||||||
|
if (idFieldName == null) {
|
||||||
|
idFieldName = "id";
|
||||||
|
}
|
||||||
|
|
||||||
|
Object result = null;
|
||||||
|
for (Object obj : objList) {
|
||||||
|
Object val = ReflectUtil.getFieldValue(obj, idFieldName);
|
||||||
|
if (keyValue.equals(val)) {
|
||||||
|
result = obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object findObj(List objList, Object keyValue) {
|
||||||
|
return findObj(objList, null, keyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 修改关系记录(根据linkID+pkId添加和删除)
|
||||||
|
// */
|
||||||
|
// /**
|
||||||
|
// * @param currentUser 当前用户
|
||||||
|
// * @param formList 表单提交的数据
|
||||||
|
// * @param oriList 数据库中的数据
|
||||||
|
// * @param clz 要插入表中的对象对应的类
|
||||||
|
// * @param findId 根据哪个属性查找传入的formList、oriList
|
||||||
|
// * @param pkIdName 根据哪个属性删除(添加)关系记录
|
||||||
|
// * @param linkIdName 外键字段名称
|
||||||
|
// * @param linkId 外键字段值
|
||||||
|
// * @param mapper
|
||||||
|
// * @throws Exception
|
||||||
|
// */
|
||||||
|
// public static void saveRelaDiff(
|
||||||
|
// List formList,
|
||||||
|
// List oriList,
|
||||||
|
// Class clz,
|
||||||
|
// String findId,
|
||||||
|
// String pkIdName,
|
||||||
|
// String linkIdName,
|
||||||
|
// String linkId,
|
||||||
|
// BaseMapper mapper) throws Exception {
|
||||||
|
// // 需要比较的
|
||||||
|
// List<String> compareList = new ArrayList<>();
|
||||||
|
// // 原始数据
|
||||||
|
// List<String> currList = new ArrayList<>();
|
||||||
|
//
|
||||||
|
// updateObject(formList, compareList, findId);
|
||||||
|
// updateObject(oriList, currList, findId);
|
||||||
|
//
|
||||||
|
// Map<String, Set<String>> result = BeanUtil.diffList(compareList, currList);
|
||||||
|
//
|
||||||
|
// if (result != null) {
|
||||||
|
// Set<String> addList = result.get(BeanUtil.ADD);
|
||||||
|
// Set<String> removeList = result.get(BeanUtil.REMOVE);
|
||||||
|
//
|
||||||
|
// //删除数据
|
||||||
|
// if (removeList != null && removeList.size() > 0) {
|
||||||
|
// for (String removeId : removeList) {
|
||||||
|
// Object obj = clz.newInstance();
|
||||||
|
// ReflectUtil.setFieldValue(obj, "delFlag", DelFlag.DELETE);
|
||||||
|
//
|
||||||
|
// Example remExample = new Example(clz);
|
||||||
|
// Example.Criteria remCriteria = remExample.createCriteria();
|
||||||
|
// //获取删除标记为正常的记录
|
||||||
|
// remCriteria.andEqualTo(linkIdName, linkId);
|
||||||
|
// remCriteria.andEqualTo(pkIdName, removeId);
|
||||||
|
// remCriteria.andNotEqualTo("delFlag", DelFlag.DELETE);
|
||||||
|
// mapper.updateByExampleSelective(obj, remExample);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //添加资源
|
||||||
|
// if (addList != null && addList.size() > 0) {
|
||||||
|
// List addObjList = new ArrayList();
|
||||||
|
// for (String addId : addList) {
|
||||||
|
// Object obj = clz.newInstance();
|
||||||
|
// ReflectUtil.setFieldValue(obj, linkIdName, linkId);
|
||||||
|
// ReflectUtil.setFieldValue(obj, pkIdName, addId);
|
||||||
|
//
|
||||||
|
// BeanUtil.setCreateUser(currentUser, obj);
|
||||||
|
// BeanUtil.setUpdateUser(currentUser, obj);
|
||||||
|
//
|
||||||
|
// addObjList.add(obj);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (addObjList.size() > 0) {
|
||||||
|
// mapper.batchInsert(addObjList);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
@ -12,6 +12,15 @@ import org.dromara.common.tenant.helper.TenantHelper;
|
|||||||
*/
|
*/
|
||||||
public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
||||||
|
|
||||||
|
// 用于获取指定租户下的缓存
|
||||||
|
private static final ThreadLocal<String> TENANT_ID = new ThreadLocal<>();
|
||||||
|
|
||||||
|
public static void setTenantId(String tenantId) {
|
||||||
|
if (StringUtils.isNotEmpty(tenantId)) {
|
||||||
|
TENANT_ID.set(tenantId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TenantKeyPrefixHandler(String keyPrefix) {
|
public TenantKeyPrefixHandler(String keyPrefix) {
|
||||||
super(keyPrefix);
|
super(keyPrefix);
|
||||||
}
|
}
|
||||||
@ -27,7 +36,12 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
|||||||
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
||||||
return super.map(name);
|
return super.map(name);
|
||||||
}
|
}
|
||||||
String tenantId = TenantHelper.getTenantId();
|
|
||||||
|
String tenantId = TENANT_ID.get();
|
||||||
|
TENANT_ID.remove();
|
||||||
|
if (tenantId == null) {
|
||||||
|
tenantId = TenantHelper.getTenantId();
|
||||||
|
}
|
||||||
if (StringUtils.startsWith(name, tenantId)) {
|
if (StringUtils.startsWith(name, tenantId)) {
|
||||||
// 如果存在则直接返回
|
// 如果存在则直接返回
|
||||||
return super.map(name);
|
return super.map(name);
|
||||||
|
|||||||
@ -4,22 +4,18 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
|||||||
import cn.dev33.satoken.exception.NotLoginException;
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import org.dromara.common.core.constant.CacheConstants;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.dromara.common.core.constant.GlobalConstants;
|
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
import org.dromara.common.core.utils.StreamUtils;
|
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
|
||||||
import org.dromara.common.log.annotation.Log;
|
import org.dromara.common.log.annotation.Log;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.redis.utils.RedisUtils;
|
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.system.domain.SysUserOnline;
|
import org.dromara.system.domain.SysUserOnline;
|
||||||
import lombok.RequiredArgsConstructor;
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
|
import org.dromara.system.service.ISysUserOnlineService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -33,6 +29,8 @@ import java.util.List;
|
|||||||
@RequestMapping("/monitor/online")
|
@RequestMapping("/monitor/online")
|
||||||
public class SysUserOnlineController extends BaseController {
|
public class SysUserOnlineController extends BaseController {
|
||||||
|
|
||||||
|
private final ISysUserOnlineService onlineService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取在线用户监控列表
|
* 获取在线用户监控列表
|
||||||
*
|
*
|
||||||
@ -42,33 +40,12 @@ public class SysUserOnlineController extends BaseController {
|
|||||||
@SaCheckPermission("monitor:online:list")
|
@SaCheckPermission("monitor:online:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
|
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
|
||||||
// 获取所有未过期的 token
|
SysOnlineUserBo userBo = new SysOnlineUserBo();
|
||||||
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
|
userBo.setIpaddr(ipaddr);
|
||||||
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
|
userBo.setUserName(userName);
|
||||||
for (String key : keys) {
|
List<UserOnlineDTO> userOnlineDTOList = this.onlineService.getOnlineUsers(null, userBo);
|
||||||
String token = StringUtils.substringAfterLast(key, ":");
|
// 倒序排序
|
||||||
// 如果已经过期则跳过
|
|
||||||
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
|
|
||||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
|
||||||
StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
|
|
||||||
StringUtils.equals(userName, userOnline.getUserName())
|
|
||||||
);
|
|
||||||
} else if (StringUtils.isNotEmpty(ipaddr)) {
|
|
||||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
|
||||||
StringUtils.equals(ipaddr, userOnline.getIpaddr())
|
|
||||||
);
|
|
||||||
} else if (StringUtils.isNotEmpty(userName)) {
|
|
||||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
|
||||||
StringUtils.equals(userName, userOnline.getUserName())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Collections.reverse(userOnlineDTOList);
|
Collections.reverse(userOnlineDTOList);
|
||||||
userOnlineDTOList.removeAll(Collections.singleton(null));
|
|
||||||
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
|
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
|
||||||
return TableDataInfo.build(userOnlineList);
|
return TableDataInfo.build(userOnlineList);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package org.dromara.system.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author warden
|
||||||
|
* @Date 2023/6/19 17:34
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysOnlineUserBo {
|
||||||
|
private String ipaddr;
|
||||||
|
private String userName;
|
||||||
|
// private String tenantId;
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package org.dromara.system.service;
|
||||||
|
|
||||||
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author warden
|
||||||
|
*/
|
||||||
|
public interface ISysUserOnlineService {
|
||||||
|
List<UserOnlineDTO> getOnlineUsers(String tenantId, SysOnlineUserBo userBo);
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package org.dromara.system.service.impl;
|
package org.dromara.system.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
import cn.dev33.satoken.secure.BCrypt;
|
import cn.dev33.satoken.secure.BCrypt;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
@ -11,6 +13,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.dromara.common.core.constant.CacheNames;
|
import org.dromara.common.core.constant.CacheNames;
|
||||||
import org.dromara.common.core.constant.Constants;
|
import org.dromara.common.core.constant.Constants;
|
||||||
import org.dromara.common.core.constant.TenantConstants;
|
import org.dromara.common.core.constant.TenantConstants;
|
||||||
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.MapstructUtils;
|
import org.dromara.common.core.utils.MapstructUtils;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
@ -18,10 +21,12 @@ import org.dromara.common.core.utils.StringUtils;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.system.domain.*;
|
import org.dromara.system.domain.*;
|
||||||
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
import org.dromara.system.domain.bo.SysTenantBo;
|
import org.dromara.system.domain.bo.SysTenantBo;
|
||||||
import org.dromara.system.domain.vo.SysTenantVo;
|
import org.dromara.system.domain.vo.SysTenantVo;
|
||||||
import org.dromara.system.mapper.*;
|
import org.dromara.system.mapper.*;
|
||||||
import org.dromara.system.service.ISysTenantService;
|
import org.dromara.system.service.ISysTenantService;
|
||||||
|
import org.dromara.system.service.ISysUserOnlineService;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -52,6 +57,7 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
private final SysDictTypeMapper dictTypeMapper;
|
private final SysDictTypeMapper dictTypeMapper;
|
||||||
private final SysDictDataMapper dictDataMapper;
|
private final SysDictDataMapper dictDataMapper;
|
||||||
private final SysConfigMapper configMapper;
|
private final SysConfigMapper configMapper;
|
||||||
|
private final ISysUserOnlineService onlineService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询租户
|
* 查询租户
|
||||||
@ -261,6 +267,17 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
@CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
|
@CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
|
||||||
@Override
|
@Override
|
||||||
public int updateTenantStatus(SysTenantBo bo) {
|
public int updateTenantStatus(SysTenantBo bo) {
|
||||||
|
// 停用租户时,要将租户下的所有在线用户全部剔除,避免依然有权限操作
|
||||||
|
if (Constants.FAIL.equals(bo.getStatus())) {
|
||||||
|
List<UserOnlineDTO> userOnlineDTOList = this.onlineService.getOnlineUsers(bo.getTenantId(), null);
|
||||||
|
for (UserOnlineDTO online : userOnlineDTOList) {
|
||||||
|
try {
|
||||||
|
StpUtil.kickoutByTokenValue(online.getTokenId());
|
||||||
|
} catch (NotLoginException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
|
SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
|
||||||
return baseMapper.updateById(tenant);
|
return baseMapper.updateById(tenant);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,61 @@
|
|||||||
|
package org.dromara.system.service.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import org.dromara.common.core.constant.CacheConstants;
|
||||||
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
|
import org.dromara.common.core.utils.StreamUtils;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
|
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
|
||||||
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
|
import org.dromara.system.service.ISysUserOnlineService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SysUserOnlineServiceImpl implements ISysUserOnlineService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserOnlineDTO> getOnlineUsers(String tenantId, SysOnlineUserBo userBo) {
|
||||||
|
String ipaddr = userBo == null ? null : userBo.getIpaddr();
|
||||||
|
String userName = userBo == null ? null : userBo.getUserName();
|
||||||
|
// 获取所有未过期的 token
|
||||||
|
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
|
||||||
|
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
|
||||||
|
for (String key : keys) {
|
||||||
|
String token = StringUtils.substringAfterLast(key, ":");
|
||||||
|
// 如果已经过期则跳过
|
||||||
|
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TenantKeyPrefixHandler.setTenantId(tenantId);
|
||||||
|
UserOnlineDTO online = RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token);
|
||||||
|
|
||||||
|
if (online != null) {
|
||||||
|
userOnlineDTOList.add(online);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// // 清空为空的数据
|
||||||
|
// userOnlineDTOList.removeAll(Collections.singleton(null));
|
||||||
|
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
|
||||||
|
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
||||||
|
StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
|
||||||
|
StringUtils.equals(userName, userOnline.getUserName())
|
||||||
|
);
|
||||||
|
} else if (StringUtils.isNotEmpty(ipaddr)) {
|
||||||
|
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
||||||
|
StringUtils.equals(ipaddr, userOnline.getIpaddr())
|
||||||
|
);
|
||||||
|
} else if (StringUtils.isNotEmpty(userName)) {
|
||||||
|
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
||||||
|
StringUtils.equals(userName, userOnline.getUserName())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userOnlineDTOList;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user