Commit c5f29f18d386d2dcc564e8f8842257eed2225904
Merge remote-tracking branch 'origin/master' into dev
Showing
9 changed files
with
35 additions
and
17 deletions
pom.xml
| ... | ... | @@ -29,7 +29,7 @@ |
| 29 | 29 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 30 | 30 | |
| 31 | 31 | <properties> |
| 32 | - <revision>1.6.5-snapshot</revision> | |
| 32 | + <revision>1.6.6-snapshot</revision> | |
| 33 | 33 | <!-- Maven 相关 --> |
| 34 | 34 | <java.version>1.8</java.version> |
| 35 | 35 | <maven.compiler.source>${java.version}</maven.compiler.source> | ... | ... |
yudao-dependencies/pom.xml
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClient.java
| ... | ... | @@ -9,10 +9,11 @@ import io.minio.*; |
| 9 | 9 | import java.io.ByteArrayInputStream; |
| 10 | 10 | |
| 11 | 11 | import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN; |
| 12 | +import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_TENCENT; | |
| 12 | 13 | |
| 13 | 14 | /** |
| 14 | 15 | * 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务 |
| 15 | - * | |
| 16 | + * <p> | |
| 16 | 17 | * S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库 |
| 17 | 18 | * |
| 18 | 19 | * @author 芋道源码 |
| ... | ... | @@ -78,6 +79,11 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 78 | 79 | .replaceAll("-internal", "")// 去除内网 Endpoint 的后缀 |
| 79 | 80 | .replaceAll("https://", ""); |
| 80 | 81 | } |
| 82 | + // 腾讯云必须有 region,否则会报错 | |
| 83 | + if (config.getEndpoint().contains(ENDPOINT_TENCENT)) { | |
| 84 | + return StrUtil.subAfter(config.getEndpoint(), ".cos.", false) | |
| 85 | + .replaceAll("." + ENDPOINT_TENCENT, ""); // 去除 Endpoint | |
| 86 | + } | |
| 81 | 87 | return null; |
| 82 | 88 | } |
| 83 | 89 | ... | ... |
yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientConfig.java
| ... | ... | @@ -19,6 +19,7 @@ public class S3FileClientConfig implements FileClientConfig { |
| 19 | 19 | |
| 20 | 20 | public static final String ENDPOINT_QINIU = "qiniucs.com"; |
| 21 | 21 | public static final String ENDPOINT_ALIYUN = "aliyuncs.com"; |
| 22 | + public static final String ENDPOINT_TENCENT = "myqcloud.com"; | |
| 22 | 23 | |
| 23 | 24 | /** |
| 24 | 25 | * 节点地址 | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java
| ... | ... | @@ -75,7 +75,7 @@ public class ConfigController { |
| 75 | 75 | if (config == null) { |
| 76 | 76 | return null; |
| 77 | 77 | } |
| 78 | - if (config.getVisible()) { | |
| 78 | + if (!config.getVisible()) { | |
| 79 | 79 | throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE); |
| 80 | 80 | } |
| 81 | 81 | return success(config.getValue()); | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.infra.dal.mysql.file; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.file.core.client.db.DBFileContentFrameworkDAO; |
| 4 | 5 | import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO; |
| 5 | 6 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 6 | 7 | import org.springframework.stereotype.Repository; |
| 7 | 8 | |
| 8 | 9 | import javax.annotation.Resource; |
| 10 | +import java.util.List; | |
| 11 | +import java.util.Optional; | |
| 9 | 12 | |
| 10 | 13 | @Repository |
| 11 | 14 | public class FileContentDAOImpl implements DBFileContentFrameworkDAO { |
| ... | ... | @@ -27,9 +30,11 @@ public class FileContentDAOImpl implements DBFileContentFrameworkDAO { |
| 27 | 30 | |
| 28 | 31 | @Override |
| 29 | 32 | public byte[] selectContent(Long configId, String path) { |
| 30 | - FileContentDO fileContentDO = fileContentMapper.selectOne( | |
| 31 | - buildQuery(configId, path).select(FileContentDO::getContent)); | |
| 32 | - return fileContentDO != null ? fileContentDO.getContent() : null; | |
| 33 | + List<FileContentDO> list = fileContentMapper.selectList( | |
| 34 | + buildQuery(configId, path).select(FileContentDO::getContent).orderByDesc(FileContentDO::getId)); | |
| 35 | + return Optional.ofNullable(CollUtil.getFirst(list)) | |
| 36 | + .map(FileContentDO::getContent) | |
| 37 | + .orElse(null); | |
| 33 | 38 | } |
| 34 | 39 | |
| 35 | 40 | private LambdaQueryWrapper<FileContentDO> buildQuery(Long configId, String path) { | ... | ... |
yudao-ui-admin-vue3/package.json
yudao-ui-admin/package.json
yudao-ui-admin/src/views/infra/file/index.vue
| 1 | 1 | <template> |
| 2 | 2 | <div class="app-container"> |
| 3 | - <doc-alert title="上传下载" url="https://doc.iocoder.cn/file/" /> | |
| 3 | + <doc-alert title="上传下载" url="https://doc.iocoder.cn/file/"/> | |
| 4 | 4 | <!-- 搜索工作栏 --> |
| 5 | 5 | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| 6 | 6 | <el-form-item label="文件路径" prop="path"> |
| 7 | 7 | <el-input v-model="queryParams.path" placeholder="请输入文件路径" clearable @keyup.enter.native="handleQuery"/> |
| 8 | 8 | </el-form-item> |
| 9 | 9 | <el-form-item label="创建时间" prop="createTime"> |
| 10 | - <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" | |
| 11 | - range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> | |
| 10 | + <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" | |
| 11 | + type="daterange" | |
| 12 | + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" | |
| 13 | + :default-time="['00:00:00', '23:59:59']"/> | |
| 12 | 14 | </el-form-item> |
| 13 | 15 | <el-form-item> |
| 14 | 16 | <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> |
| ... | ... | @@ -35,6 +37,9 @@ |
| 35 | 37 | <template v-slot="scope"> |
| 36 | 38 | <image-preview v-if="scope.row.type&&scope.row.type.indexOf('image/') === 0" :src="scope.row.url" |
| 37 | 39 | :width="'100px'"></image-preview> |
| 40 | + <video v-else-if="scope.row.type&&scope.row.type.indexOf('video/') === 0" :width="'100px'"> | |
| 41 | + <source :src="scope.row.url"/> | |
| 42 | + </video> | |
| 38 | 43 | <i v-else>无法预览,点击 |
| 39 | 44 | <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" target="_blank" |
| 40 | 45 | :href="getFileUrl + scope.row.configId + '/get/' + scope.row.path">下载 |
| ... | ... | @@ -118,7 +123,7 @@ export default { |
| 118 | 123 | title: "", // 弹出层标题 |
| 119 | 124 | isUploading: false, // 是否禁用上传 |
| 120 | 125 | url: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/upload", // 请求地址 |
| 121 | - headers: { Authorization: "Bearer " + getAccessToken() }, // 设置上传的请求头部 | |
| 126 | + headers: {Authorization: "Bearer " + getAccessToken()}, // 设置上传的请求头部 | |
| 122 | 127 | data: {} // 上传的额外数据,用于文件名 |
| 123 | 128 | }, |
| 124 | 129 | }; |
| ... | ... | @@ -189,19 +194,20 @@ export default { |
| 189 | 194 | /** 删除按钮操作 */ |
| 190 | 195 | handleDelete(row) { |
| 191 | 196 | const id = row.id; |
| 192 | - this.$modal.confirm('是否确认删除文件编号为"' + id + '"的数据项?').then(function() { | |
| 197 | + this.$modal.confirm('是否确认删除文件编号为"' + id + '"的数据项?').then(function () { | |
| 193 | 198 | return deleteFile(id); |
| 194 | 199 | }).then(() => { |
| 195 | 200 | this.getList(); |
| 196 | 201 | this.$modal.msgSuccess("删除成功"); |
| 197 | - }).catch(() => {}); | |
| 202 | + }).catch(() => { | |
| 203 | + }); | |
| 198 | 204 | }, |
| 199 | 205 | // 用户昵称展示 |
| 200 | 206 | sizeFormat(row, column) { |
| 201 | - const unitArr = ["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"]; | |
| 207 | + const unitArr = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; | |
| 202 | 208 | const srcSize = parseFloat(row.size); |
| 203 | 209 | const index = Math.floor(Math.log(srcSize) / Math.log(1024)); |
| 204 | - let size =srcSize/Math.pow(1024,index); | |
| 210 | + let size = srcSize / Math.pow(1024, index); | |
| 205 | 211 | size = size.toFixed(2);//保留的小数位数 |
| 206 | 212 | return size + ' ' + unitArr[index]; |
| 207 | 213 | }, | ... | ... |