mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-20 18:15:56 +08:00
oss桶权限为私密时,列表查看时桶为私密的文件获取临时url(优化列表查看功能,添加下载功能)
This commit is contained in:
parent
8665bffcff
commit
a79fda4d05
@ -15,6 +15,8 @@ import com.ruoyi.common.core.validate.QueryGroup;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.oss.core.OssClient;
|
||||
import com.ruoyi.oss.factory.OssFactory;
|
||||
import com.ruoyi.system.domain.SysOss;
|
||||
import com.ruoyi.system.domain.bo.SysOssBo;
|
||||
import com.ruoyi.system.domain.vo.SysOssVo;
|
||||
@ -96,23 +98,7 @@ public class SysOssController extends BaseController {
|
||||
@SaCheckPermission("system:oss:download")
|
||||
@GetMapping("/download/{ossId}")
|
||||
public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
|
||||
SysOssVo sysOss = iSysOssService.getById(ossId);
|
||||
if (ObjectUtil.isNull(sysOss)) {
|
||||
throw new ServiceException("文件数据不存在!");
|
||||
}
|
||||
FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
|
||||
long data;
|
||||
try {
|
||||
data = HttpUtil.download(sysOss.getUrl(), response.getOutputStream(), false);
|
||||
} catch (HttpException e) {
|
||||
if (e.getMessage().contains("403")) {
|
||||
throw new ServiceException("无读取权限, 请在对应的OSS开启'公有读'权限!");
|
||||
} else {
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
response.setContentLength(Convert.toInt(data));
|
||||
iSysOssService.download(ossId,response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -10,11 +10,6 @@ import java.util.List;
|
||||
*/
|
||||
public interface OssConstant {
|
||||
|
||||
/**
|
||||
* OSS模块KEY
|
||||
*/
|
||||
String SYS_OSS_KEY = "sys_oss:";
|
||||
|
||||
/**
|
||||
* 默认配置KEY
|
||||
*/
|
||||
|
||||
@ -172,11 +172,10 @@ public class OssClient {
|
||||
}
|
||||
|
||||
public String getPrivateUrl(String objectKey, Integer second) {
|
||||
// objectKey = "file/2022/10/13/81eef51cb0734dedbfa616493a021fe4.jpg";
|
||||
GeneratePresignedUrlRequest generatePresignedUrlRequest =
|
||||
new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
|
||||
.withMethod(HttpMethod.GET)
|
||||
.withExpiration(new Date(Instant.now().toEpochMilli() + 1000 * second));
|
||||
.withExpiration(new Date(System.currentTimeMillis() + 1000 * second));
|
||||
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
package com.ruoyi.oss.enumd;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 桶访问策略配置
|
||||
*
|
||||
* @author 陈賝
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AccessPolicyType {
|
||||
|
||||
/**
|
||||
* private
|
||||
*/
|
||||
PRIVATE("0"),
|
||||
|
||||
/**
|
||||
* public
|
||||
*/
|
||||
PUBLIC("1"),
|
||||
|
||||
/**
|
||||
* constum
|
||||
*/
|
||||
CONSTUM("2");
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
}
|
||||
@ -7,6 +7,8 @@ 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;
|
||||
|
||||
@ -25,6 +27,8 @@ public interface ISysOssService {
|
||||
|
||||
SysOss upload(MultipartFile file);
|
||||
|
||||
void download(Long ossId, HttpServletResponse response) throws IOException;
|
||||
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HttpException;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -10,10 +13,13 @@ import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.JsonUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.common.utils.redis.CacheUtils;
|
||||
import com.ruoyi.common.utils.redis.RedisUtils;
|
||||
import com.ruoyi.oss.constant.OssConstant;
|
||||
import com.ruoyi.oss.core.OssClient;
|
||||
import com.ruoyi.oss.entity.UploadResult;
|
||||
import com.ruoyi.oss.enumd.AccessPolicyType;
|
||||
import com.ruoyi.oss.exception.OssException;
|
||||
import com.ruoyi.oss.factory.OssFactory;
|
||||
import com.ruoyi.oss.properties.OssProperties;
|
||||
@ -24,9 +30,11 @@ 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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -49,19 +57,7 @@ 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(o -> {
|
||||
Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + o.getService());
|
||||
OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class);
|
||||
if (properties == null) {
|
||||
throw new OssException("系统异常, '" + o.getService() + "'配置信息不存在!");
|
||||
}
|
||||
String privateFlag = "0";
|
||||
if (properties.getAccessPolicy().equals(privateFlag)) {
|
||||
OssClient storage = OssFactory.instance(o.getService());
|
||||
o.setUrl(storage.getPrivateUrl(o.getFileName(), 100));
|
||||
}
|
||||
return o;
|
||||
}).collect(Collectors.toList());
|
||||
List<SysOssVo> filterResult = result.getRecords().stream().map(this::matchingUrl).collect(Collectors.toList());
|
||||
result.setRecords(filterResult);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
@ -98,6 +94,27 @@ public class SysOssServiceImpl implements ISysOssService {
|
||||
return baseMapper.selectVoById(ossId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(Long ossId, HttpServletResponse response) throws IOException {
|
||||
SysOssVo sysOss = this.matchingUrl(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");
|
||||
long data;
|
||||
try {
|
||||
data = HttpUtil.download(sysOss.getUrl(), response.getOutputStream(), false);
|
||||
} catch (HttpException e) {
|
||||
if (e.getMessage().contains("403")) {
|
||||
throw new ServiceException("无读取权限, 请在对应的OSS开启'公有读'权限!");
|
||||
} else {
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
response.setContentLength(Convert.toInt(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysOss upload(MultipartFile file) {
|
||||
String originalfileName = file.getOriginalFilename();
|
||||
@ -133,4 +150,24 @@ public class SysOssServiceImpl implements ISysOssService {
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配Url
|
||||
*
|
||||
* @param oss OSS对象
|
||||
* @return oss 匹配Url的OSS对象
|
||||
*/
|
||||
private SysOssVo matchingUrl(SysOssVo oss) {
|
||||
OssProperties properties = JsonUtils.parseObject(
|
||||
CacheUtils.get(CacheNames.SYS_OSS_CONFIG, oss.getService()).toString(),
|
||||
OssProperties.class
|
||||
);
|
||||
if (properties == null) {
|
||||
throw new OssException("系统异常, '" + oss.getService() + "'配置信息不存在!");
|
||||
}
|
||||
if (StringUtils.equals(AccessPolicyType.PRIVATE.getType(), properties.getAccessPolicy())) {
|
||||
OssClient storage = OssFactory.instance(oss.getService());
|
||||
oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 100));
|
||||
}
|
||||
return oss;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
<el-table-column label="桶名称" align="center" prop="bucketName" />
|
||||
<el-table-column label="前缀" align="center" prop="prefix" />
|
||||
<el-table-column label="域" align="center" prop="region" />
|
||||
<el-table-column label="桶权限类型" align="center" prop="accessPolicy" :formatter = "accessPolicyStateFormat" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
@ -151,14 +152,11 @@
|
||||
>{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="AccessPolicy">
|
||||
<el-form-item label="桶权限类型">
|
||||
<el-radio-group v-model="form.accessPolicy">
|
||||
<el-radio
|
||||
v-for="dict in dict.type.access_policy"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{dict.label}}</el-radio>
|
||||
<el-radio label="0">private</el-radio>
|
||||
<el-radio label="1">public</el-radio>
|
||||
<el-radio label="2">custom</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="域" prop="region">
|
||||
@ -189,7 +187,7 @@ import {
|
||||
|
||||
export default {
|
||||
name: "OssConfig",
|
||||
dicts: ['sys_yes_no', 'sys_normal_disable','access_policy'],
|
||||
dicts: ['sys_yes_no', 'sys_normal_disable'],
|
||||
data() {
|
||||
return {
|
||||
// 按钮loading
|
||||
@ -218,6 +216,21 @@ export default {
|
||||
isHttpsOptions: [],
|
||||
// 状态(0正常 1停用)字典
|
||||
statusOptions: [],
|
||||
// 桶权限类型
|
||||
accessPolicyOptions: [
|
||||
{
|
||||
label: 'private',
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: 'public',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: 'custom',
|
||||
value: 2
|
||||
}
|
||||
],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
@ -392,7 +405,17 @@ export default {
|
||||
}).catch(() => {
|
||||
row.status = row.status === "0" ? "1" : "0";
|
||||
})
|
||||
}
|
||||
},
|
||||
accessPolicyStateFormat(row) {
|
||||
if (row.accessPolicy === "0") {
|
||||
return <span class="el-tag el-tag--warning el-tag--medium el-tag--light" > private </span>
|
||||
} else if (row.accessPolicy === "1") {
|
||||
return <span class="el-tag el-tag--success el-tag--medium el-tag--light" > public </span>
|
||||
} else if (row.accessPolicy === "2") {
|
||||
return <span class="el-tag el-tag--medium el-tag--light" > constum </span>
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -31,9 +31,14 @@
|
||||
<el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
|
||||
</template>
|
||||
<!-- <template slot-scope="scope"> -->
|
||||
<div slot="status" slot-scope="text, record">
|
||||
<a v-if="record.status == 1" style="color: #000000d9">待审核</a>
|
||||
<a v-if="record.status == 2" style="color: #000000d9">正常</a>
|
||||
<a v-if="record.status == 3" style="color: #f36e48">已驳回</a>
|
||||
<a v-if="record.status == 4" style="color: #000000d9">已禁用</a>
|
||||
</div>
|
||||
<!-- </template> -->
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user