sync: 同步 RuoYi-Vue-Plus(v4.4.0) 更新

重大更新
    [重大更新] 优化支持 oss 私有库功能(数据库字段改动) #cd9c3c3f
    [重大更新] 连接池由 druid 修改为 hikari 更新相关配置(原因可看文档) #1f42bd3d
    [重大更新] 移除 tlog(不支持UI界面 使用的人太少)建议使用 skywalking
    [重大更新] 增加 skywalking 集成 默认注释不开启(使用看文档)

依赖升级
    update springboot 2.7.5 => 2.7.6
    update springboot-admin 2.7.6 => 2.7.7
    update satoken 1.31.0 => 1.33.0
    update spring-doc 1.6.12 => 1.6.13
    update easyexcel 3.1.1 => 3.1.3
    update hutool 5.8.8 => 5.8.10
    update redisson 3.17.7 => 3.18.0
    update lock4j 2.2.2 => 2.2.3
    update s3-adk 1.12.324 => 1.12.349
    update mysql-docker 8.0.29 => 8.0.31 功能更新
    update 优化 oss 云厂商增加 华为obs关键字
    update 优化 冗余的三元表达式
    update 优化 重置时取消部门选中
    update 优化 新增返回警告消息提示
    update 优化 hikari 参数顺序 最常用的放上面 删除无用 druid 监控页面
    update 优化 p6spy 排除健康检查 sql 执行记录
    update 优化 Dockerfile 创建目录命令
    update 优化 将空‘catch’块形参重命名为‘ignored’
    update 优化 使用本地缓存优化 excel 导出 数据量大字典转换慢问题
    update 优化 字典转换实现去除字符串查找拼接优化效率
    update 优化 减小腾讯短信引入jar包的体积
    update 消除Vue3控制台出现的警告信息
    update 忽略不必要的属性数据返回
    update 替换 mysql-jdbc 最新坐标

新增功能
    add 新增 junit5 单元测试案例 #6e8ef308
    add 增加 sys_oss_config access_policy 桶权限类型字段
    add 增加 4.3-4.4 更新 sql 文件
    add 新增 字典数据映射注解 #da94e898
    add 增加 RedisUtils 获取缓存Map的key列表

问题修复
    fix 修复 上传png透明图片 生成头像透明部分变成黑色
    fix 修复 sqlserver sql文件 重复主键数据问题
    fix 修复 sqlserver 特定情况下报 ssl 证书问题 默认关闭 ssl 认证
    fix 修复 table中更多按钮切换主题色未生效修复问题
    fix 修复 菜单激活无法修改其填充颜色去除某些svg图标的fill="#bfbfbf"属性
    fix 修复 使用缓冲流 导致上传异常问题
    fix 修复 过滤器链使用IoUtil.read方法导致request流关闭
    fix 修复 Log注解GET请求记录不到参数问题
    fix 修复 某些特性的环境生成代码变乱码TXT文件问题
    fix 修复 开启TopNav没有子菜单隐藏侧边栏
    fix 修复 回显数据字典数组异常问题

移除功能
    remove 移除过期 Anonymous 注解与其实现代码
    remove 移除 tlog(不支持UI界面 使用的人太少) 建议使用 skywalking
This commit is contained in:
konbai
2023-01-07 16:51:51 +08:00
parent 03af383da9
commit 3fd2d9681d
85 changed files with 1352 additions and 691 deletions

View File

@@ -82,4 +82,8 @@ public class SysOssConfig extends BaseEntity {
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@@ -98,4 +98,10 @@ public class SysOssConfigBo extends BaseEntity {
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
@NotBlank(message = "桶权限类型不能为空", groups = {AddGroup.class, EditGroup.class})
private String accessPolicy;
}

View File

@@ -82,4 +82,9 @@ public class SysOssConfigVo {
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@@ -2,11 +2,12 @@ package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
@@ -23,7 +24,9 @@ public interface ISysOssService {
SysOssVo getById(Long ossId);
SysOss upload(MultipartFile file);
SysOssVo upload(MultipartFile file);
void download(Long ossId, HttpServletResponse response) throws IOException;
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);

View File

@@ -128,7 +128,7 @@ public class SysLoginService {
LoginUser loginUser = LoginHelper.getLoginUser();
StpUtil.logout();
asyncService.recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"), ServletUtils.getRequest());
} catch (NotLoginException e) {
} catch (NotLoginException ignored) {
}
}

View File

@@ -1,10 +1,12 @@
package com.ruoyi.system.service.impl;
import cn.dev33.satoken.context.SaHolder;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
@@ -27,6 +29,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* 字典 业务层处理
@@ -231,28 +234,24 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
* @param separator 分隔符
* @return 字典标签
*/
@SuppressWarnings("unchecked cast")
@Override
public String getDictLabel(String dictType, String dictValue, String separator) {
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
if (StringUtils.containsAny(dictValue, separator) && CollUtil.isNotEmpty(datas)) {
for (SysDictData dict : datas) {
for (String value : dictValue.split(separator)) {
if (value.equals(dict.getDictValue())) {
propertyString.append(dict.getDictLabel() + separator);
break;
}
}
}
} else {
for (SysDictData dict : datas) {
if (dictValue.equals(dict.getDictValue())) {
return dict.getDictLabel();
}
}
// 优先从本地缓存获取
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
if (ObjectUtil.isNull(datas)) {
datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
}
Map<String, String> map = StreamUtils.toMap(datas, SysDictData::getDictValue, SysDictData::getDictLabel);
if (StringUtils.containsAny(dictValue, separator)) {
return Arrays.stream(dictValue.split(separator))
.map(v -> map.getOrDefault(v, StringUtils.EMPTY))
.collect(Collectors.joining(separator));
} else {
return map.getOrDefault(dictValue, StringUtils.EMPTY);
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
@@ -263,28 +262,24 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
* @param separator 分隔符
* @return 字典值
*/
@SuppressWarnings("unchecked cast")
@Override
public String getDictValue(String dictType, String dictLabel, String separator) {
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
if (StringUtils.containsAny(dictLabel, separator) && CollUtil.isNotEmpty(datas)) {
for (SysDictData dict : datas) {
for (String label : dictLabel.split(separator)) {
if (label.equals(dict.getDictLabel())) {
propertyString.append(dict.getDictValue() + separator);
break;
}
}
}
} else {
for (SysDictData dict : datas) {
if (dictLabel.equals(dict.getDictLabel())) {
return dict.getDictValue();
}
}
// 优先从本地缓存获取
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
if (ObjectUtil.isNull(datas)) {
datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
}
Map<String, String> map = StreamUtils.toMap(datas, SysDictData::getDictLabel, SysDictData::getDictValue);
if (StringUtils.containsAny(dictLabel, separator)) {
return Arrays.stream(dictLabel.split(separator))
.map(l -> map.getOrDefault(l, StringUtils.EMPTY))
.collect(Collectors.joining(separator));
} else {
return map.getOrDefault(dictLabel, StringUtils.EMPTY);
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
}

View File

@@ -11,6 +11,7 @@ import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.TreeBuildUtils;
import com.ruoyi.system.domain.SysRoleMenu;
@@ -425,13 +426,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
* 得到子节点列表
*/
private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
List<SysMenu> tlist = new ArrayList<SysMenu>();
for (SysMenu n : list) {
if (n.getParentId().longValue() == t.getMenuId().longValue()) {
tlist.add(n);
}
}
return tlist;
return StreamUtils.filter(list, n -> n.getParentId().equals(t.getMenuId()));
}
/**

View File

@@ -1,5 +1,6 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -8,10 +9,13 @@ import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.oss.core.OssClient;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.enumd.AccessPolicyType;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
@@ -20,14 +24,18 @@ import com.ruoyi.system.mapper.SysOssMapper;
import com.ruoyi.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 文件上传 服务层实现
@@ -44,6 +52,8 @@ public class SysOssServiceImpl implements ISysOssService {
public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
List<SysOssVo> filterResult = result.getRecords().stream().map(this::matchingUrl).collect(Collectors.toList());
result.setRecords(filterResult);
return TableDataInfo.build(result);
}
@@ -53,7 +63,7 @@ public class SysOssServiceImpl implements ISysOssService {
for (Long id : ossIds) {
SysOssVo vo = SpringUtils.getAopProxy(this).getById(id);
if (ObjectUtil.isNotNull(vo)) {
list.add(vo);
list.add(this.matchingUrl(vo));
}
}
return list;
@@ -80,7 +90,25 @@ public class SysOssServiceImpl implements ISysOssService {
}
@Override
public SysOss upload(MultipartFile file) {
public void download(Long ossId, HttpServletResponse response) throws IOException {
SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId);
if (ObjectUtil.isNull(sysOss)) {
throw new ServiceException("文件数据不存在!");
}
FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
OssClient storage = OssFactory.instance();
try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) {
int available = inputStream.available();
IoUtil.copy(inputStream, response.getOutputStream(), available);
response.setContentLength(available);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
@Override
public SysOssVo upload(MultipartFile file) {
String originalfileName = file.getOriginalFilename();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance();
@@ -98,7 +126,9 @@ public class SysOssServiceImpl implements ISysOssService {
oss.setOriginalName(originalfileName);
oss.setService(storage.getConfigKey());
baseMapper.insert(oss);
return oss;
SysOssVo sysOssVo = new SysOssVo();
BeanCopyUtils.copy(oss, sysOssVo);
return this.matchingUrl(sysOssVo);
}
@Override
@@ -114,4 +144,18 @@ public class SysOssServiceImpl implements ISysOssService {
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 匹配Url
*
* @param oss OSS对象
* @return oss 匹配Url的OSS对象
*/
private SysOssVo matchingUrl(SysOssVo oss) {
OssClient storage = OssFactory.instance(oss.getService());
// 仅修改桶类型为 private 的URL临时URL时长为120s
if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120));
}
return oss;
}
}