feat: 文件管理适配详情、下载,音视频、图片文件允许在线打开
This commit is contained in:
parent
c90361d7d9
commit
9a30da9334
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.model.resp;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
||||
|
||||
/**
|
||||
* 文件详情信息
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/23 10:38
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@Schema(description = "文件详情信息")
|
||||
public class FileDetailResp extends BaseDetailResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Schema(description = "名称")
|
||||
@ExcelProperty(value = "名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 大小(字节)
|
||||
*/
|
||||
@Schema(description = "大小(字节)")
|
||||
@ExcelProperty(value = "大小(字节)")
|
||||
private Long size;
|
||||
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
@Schema(description = "URL")
|
||||
@ExcelProperty(value = "URL")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 扩展名
|
||||
*/
|
||||
@Schema(description = "扩展名")
|
||||
@ExcelProperty(value = "扩展名")
|
||||
private String extension;
|
||||
|
||||
/**
|
||||
* MIME类型
|
||||
*/
|
||||
@Schema(description = "MIME类型")
|
||||
@ExcelProperty(value = "MIME类型")
|
||||
private String mimeType;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
@Schema(description = "类型")
|
||||
@ExcelProperty(value = "类型")
|
||||
private FileTypeEnum type;
|
||||
|
||||
/**
|
||||
* 存储库ID
|
||||
*/
|
||||
@Schema(description = "存储库ID")
|
||||
@ExcelProperty(value = "存储库ID")
|
||||
private Long storageId;
|
||||
}
|
@ -17,14 +17,16 @@
|
||||
package top.charles7c.continew.admin.system.model.resp;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseResp;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
||||
|
||||
/**
|
||||
* 文件信息
|
||||
@ -33,8 +35,9 @@ import top.charles7c.continew.starter.extension.crud.base.BaseResp;
|
||||
* @since 2023/12/23 10:38
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "文件信息")
|
||||
public class FileResp extends BaseResp {
|
||||
@ExcelIgnoreUnannotated
|
||||
@Schema(description = "文件详情信息")
|
||||
public class FileResp extends BaseDetailResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@ -42,48 +45,49 @@ public class FileResp extends BaseResp {
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Schema(description = "名称")
|
||||
@Schema(description = "名称", example = "example")
|
||||
@ExcelProperty(value = "名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 大小(字节)
|
||||
*/
|
||||
@Schema(description = "大小(字节)")
|
||||
@Schema(description = "大小(字节)", example = "4096")
|
||||
@ExcelProperty(value = "大小(字节)")
|
||||
private Long size;
|
||||
|
||||
/**
|
||||
* URL
|
||||
*/
|
||||
@Schema(description = "URL")
|
||||
@Schema(description = "URL", example = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/example/example.jpg")
|
||||
@ExcelProperty(value = "URL")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 扩展名
|
||||
*/
|
||||
@Schema(description = "扩展名")
|
||||
@Schema(description = "扩展名", example = "jpg")
|
||||
@ExcelProperty(value = "扩展名")
|
||||
private String extension;
|
||||
|
||||
/**
|
||||
* MIME类型
|
||||
*/
|
||||
@Schema(description = "MIME类型")
|
||||
@ExcelProperty(value = "MIME类型")
|
||||
private String mimeType;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
@Schema(description = "类型")
|
||||
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2", "3", "4", "5"}, example = "2")
|
||||
@ExcelProperty(value = "类型")
|
||||
private FileTypeEnum type;
|
||||
|
||||
/**
|
||||
* 存储库 ID
|
||||
*/
|
||||
@Schema(description = "存储库ID")
|
||||
@Schema(description = "存储库ID", example = "1")
|
||||
@ExcelProperty(value = "存储库ID")
|
||||
private Long storageId;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@Schema(description = "修改时间")
|
||||
private LocalDateTime updateTime;
|
||||
}
|
@ -23,7 +23,6 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.query.FileQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.FileReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileResp;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseService;
|
||||
|
||||
@ -33,7 +32,7 @@ import top.charles7c.continew.starter.extension.crud.base.BaseService;
|
||||
* @author Charles7c
|
||||
* @since 2023/12/23 10:38
|
||||
*/
|
||||
public interface FileService extends BaseService<FileResp, FileDetailResp, FileQuery, FileReq> {
|
||||
public interface FileService extends BaseService<FileResp, FileResp, FileQuery, FileReq> {
|
||||
|
||||
/**
|
||||
* 上传到默认存储库
|
||||
|
@ -38,7 +38,6 @@ import top.charles7c.continew.admin.system.model.entity.FileDO;
|
||||
import top.charles7c.continew.admin.system.model.entity.StorageDO;
|
||||
import top.charles7c.continew.admin.system.model.query.FileQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.FileReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageDetailResp;
|
||||
import top.charles7c.continew.admin.system.service.FileService;
|
||||
@ -57,7 +56,7 @@ import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FileServiceImpl extends BaseServiceImpl<FileMapper, FileDO, FileResp, FileDetailResp, FileQuery, FileReq>
|
||||
public class FileServiceImpl extends BaseServiceImpl<FileMapper, FileDO, FileResp, FileResp, FileQuery, FileReq>
|
||||
implements FileService {
|
||||
|
||||
@Resource
|
||||
|
@ -48,7 +48,8 @@
|
||||
"pinia": "^2.1.7",
|
||||
"query-string": "^8.1.0",
|
||||
"sortablejs": "^1.15.1",
|
||||
"v-viewer": "^1.6.4",
|
||||
"v-viewer": "^3.0.10",
|
||||
"viewerjs": "^1.11.6",
|
||||
"vue": "3.3.7",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"vue-cropper": "^1.1.1",
|
||||
@ -57,7 +58,7 @@
|
||||
"vue-json-pretty": "^2.3.0",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue3-colorpicker": "^2.2.3",
|
||||
"xgplayer": "^3.0.11"
|
||||
"xgplayer": "^2.31.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arco-plugins/vite-vue": "^1.4.5",
|
||||
|
120
continew-admin-ui/pnpm-lock.yaml
generated
120
continew-admin-ui/pnpm-lock.yaml
generated
@ -60,8 +60,11 @@ dependencies:
|
||||
specifier: ^1.15.1
|
||||
version: 1.15.1
|
||||
v-viewer:
|
||||
specifier: ^1.6.4
|
||||
version: 1.6.4
|
||||
specifier: ^3.0.10
|
||||
version: 3.0.11(vue@3.3.7)
|
||||
viewerjs:
|
||||
specifier: ^1.11.6
|
||||
version: 1.11.6
|
||||
vue:
|
||||
specifier: 3.3.7
|
||||
version: 3.3.7(typescript@5.3.3)
|
||||
@ -87,8 +90,8 @@ dependencies:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3(@aesoper/normal-utils@0.1.5)(@popperjs/core@2.11.8)(@vueuse/core@10.7.0)(gradient-parser@1.0.2)(lodash-es@4.17.21)(tinycolor2@1.6.0)(vue-types@4.2.1)(vue@3.3.7)
|
||||
xgplayer:
|
||||
specifier: ^3.0.11
|
||||
version: 3.0.11(core-js@3.34.0)
|
||||
specifier: ^2.31.6
|
||||
version: 2.32.6
|
||||
|
||||
devDependencies:
|
||||
'@arco-plugins/vite-vue':
|
||||
@ -2073,6 +2076,11 @@ packages:
|
||||
uri-js: 4.4.1
|
||||
dev: true
|
||||
|
||||
/amdefine@1.0.1:
|
||||
resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==, tarball: https://registry.npmmirror.com/amdefine/-/amdefine-1.0.1.tgz}
|
||||
engines: {node: '>=0.4.2'}
|
||||
dev: false
|
||||
|
||||
/ansi-escapes@6.2.0:
|
||||
resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==, tarball: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-6.2.0.tgz}
|
||||
engines: {node: '>=14.16'}
|
||||
@ -2923,11 +2931,6 @@ packages:
|
||||
toggle-selection: 1.0.6
|
||||
dev: false
|
||||
|
||||
/core-js@3.34.0:
|
||||
resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==, tarball: https://registry.npmmirror.com/core-js/-/core-js-3.34.0.tgz}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/core-util-is@1.0.3:
|
||||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, tarball: https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz}
|
||||
dev: true
|
||||
@ -3677,10 +3680,6 @@ packages:
|
||||
robust-predicates: 3.0.2
|
||||
dev: false
|
||||
|
||||
/delegate@3.2.0:
|
||||
resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==, tarball: https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz}
|
||||
dev: false
|
||||
|
||||
/dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, tarball: https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz}
|
||||
engines: {node: '>=6'}
|
||||
@ -3842,6 +3841,13 @@ packages:
|
||||
resolution: {integrity: sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q==, tarball: https://registry.npmmirror.com/downloadjs/-/downloadjs-1.4.7.tgz}
|
||||
dev: false
|
||||
|
||||
/draggabilly@2.4.1:
|
||||
resolution: {integrity: sha512-HHHLPEPZqRXIDQDFRFdK7RONZausNlJ4WkA73ST7Z6O2HPWttxFHVwHo8nccuDLzXWwiVKRVuc6fTkW+CQA++A==, tarball: https://registry.npmmirror.com/draggabilly/-/draggabilly-2.4.1.tgz}
|
||||
dependencies:
|
||||
get-size: 2.0.3
|
||||
unidragger: 2.4.0
|
||||
dev: false
|
||||
|
||||
/duplexer3@0.1.5:
|
||||
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==, tarball: https://registry.npmmirror.com/duplexer3/-/duplexer3-0.1.5.tgz}
|
||||
dev: true
|
||||
@ -4509,6 +4515,12 @@ packages:
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: true
|
||||
|
||||
/esprima@1.2.5:
|
||||
resolution: {integrity: sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==, tarball: https://registry.npmmirror.com/esprima/-/esprima-1.2.5.tgz}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/esprima@4.0.1:
|
||||
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, tarball: https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz}
|
||||
engines: {node: '>=4'}
|
||||
@ -4546,6 +4558,10 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/ev-emitter@1.1.1:
|
||||
resolution: {integrity: sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q==, tarball: https://registry.npmmirror.com/ev-emitter/-/ev-emitter-1.1.1.tgz}
|
||||
dev: false
|
||||
|
||||
/event-emitter@0.3.5:
|
||||
resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==, tarball: https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz}
|
||||
dependencies:
|
||||
@ -5021,6 +5037,14 @@ packages:
|
||||
universalify: 2.0.0
|
||||
dev: true
|
||||
|
||||
/fs-extra@5.0.0:
|
||||
resolution: {integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==, tarball: https://registry.npmmirror.com/fs-extra/-/fs-extra-5.0.0.tgz}
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
jsonfile: 4.0.0
|
||||
universalify: 0.1.2
|
||||
dev: false
|
||||
|
||||
/fs-extra@7.0.1:
|
||||
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==, tarball: https://registry.npmmirror.com/fs-extra/-/fs-extra-7.0.1.tgz}
|
||||
engines: {node: '>=6 <7 || >=8'}
|
||||
@ -5059,6 +5083,13 @@ packages:
|
||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==, tarball: https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz}
|
||||
dev: true
|
||||
|
||||
/generate-source-map@0.0.5:
|
||||
resolution: {integrity: sha512-jqiE7f3FEaeMcjnMSEYLjMa39bdx+RrrdfhxdJpMm9S/8IugHF4vLQLZ9sxHylWyxpsBILukC/l/7B0/O0zhNg==, tarball: https://registry.npmmirror.com/generate-source-map/-/generate-source-map-0.0.5.tgz}
|
||||
dependencies:
|
||||
esprima: 1.2.5
|
||||
source-map: 0.1.43
|
||||
dev: false
|
||||
|
||||
/gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -5090,6 +5121,10 @@ packages:
|
||||
npm-conf: 1.1.3
|
||||
dev: true
|
||||
|
||||
/get-size@2.0.3:
|
||||
resolution: {integrity: sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q==, tarball: https://registry.npmmirror.com/get-size/-/get-size-2.0.3.tgz}
|
||||
dev: false
|
||||
|
||||
/get-stdin@4.0.1:
|
||||
resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==, tarball: https://registry.npmmirror.com/get-stdin/-/get-stdin-4.0.1.tgz}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -8904,6 +8939,13 @@ packages:
|
||||
resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==, tarball: https://registry.npmmirror.com/source-map-url/-/source-map-url-0.4.1.tgz}
|
||||
deprecated: See https://github.com/lydell/source-map-url#deprecated
|
||||
|
||||
/source-map@0.1.43:
|
||||
resolution: {integrity: sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.1.43.tgz}
|
||||
engines: {node: '>=0.8.0'}
|
||||
dependencies:
|
||||
amdefine: 1.0.1
|
||||
dev: false
|
||||
|
||||
/source-map@0.5.7:
|
||||
resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -9554,11 +9596,6 @@ packages:
|
||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, tarball: https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz}
|
||||
dev: true
|
||||
|
||||
/throttle-debounce@2.3.0:
|
||||
resolution: {integrity: sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==, tarball: https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/through2@4.0.2:
|
||||
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==, tarball: https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz}
|
||||
dependencies:
|
||||
@ -9819,6 +9856,12 @@ packages:
|
||||
xtend: 4.0.2
|
||||
dev: true
|
||||
|
||||
/unidragger@2.4.0:
|
||||
resolution: {integrity: sha512-MueZK2oXuGE6OAlGKIrSXK2zCq+8yb1QUZgqyTDCSJzvwYL0g2Llrad+TtoQTYxtFnNyxxSw0IMnKNIgEMia1w==, tarball: https://registry.npmmirror.com/unidragger/-/unidragger-2.4.0.tgz}
|
||||
dependencies:
|
||||
unipointer: 2.4.0
|
||||
dev: false
|
||||
|
||||
/unified@7.1.0:
|
||||
resolution: {integrity: sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==, tarball: https://registry.npmmirror.com/unified/-/unified-7.1.0.tgz}
|
||||
dependencies:
|
||||
@ -9841,6 +9884,12 @@ packages:
|
||||
is-extendable: 0.1.1
|
||||
set-value: 2.0.1
|
||||
|
||||
/unipointer@2.4.0:
|
||||
resolution: {integrity: sha512-VjzDLPjGK7aYpQKH7bnDZS8X4axF5AFU/LQi+NQe1oyEHfaz6lWKhaQ7n4o7vJ1iJ4i2T0quCIfrQM139p05Sw==, tarball: https://registry.npmmirror.com/unipointer/-/unipointer-2.4.0.tgz}
|
||||
dependencies:
|
||||
ev-emitter: 1.1.1
|
||||
dev: false
|
||||
|
||||
/uniq@1.0.1:
|
||||
resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==, tarball: https://registry.npmmirror.com/uniq/-/uniq-1.0.1.tgz}
|
||||
dev: true
|
||||
@ -10017,12 +10066,14 @@ packages:
|
||||
sade: 1.8.1
|
||||
dev: false
|
||||
|
||||
/v-viewer@1.6.4:
|
||||
resolution: {integrity: sha512-LVkiUHpmsbsZXebeNXnu8krRCi5i2n07FeLFxoIVGhw8lVvTBO0ffpbDC6mLEuacCjrIh09HjIqpciwUtWE8lQ==, tarball: https://registry.npmmirror.com/v-viewer/-/v-viewer-1.6.4.tgz}
|
||||
engines: {node: '>=4', npm: '>=3'}
|
||||
/v-viewer@3.0.11(vue@3.3.7):
|
||||
resolution: {integrity: sha512-E8LOdAxhzuktt4HB3PswVCccQ1Q1sYHYnLsS6zaJISpb5EvmAFs5sYNfXnDLFxVb5DQ82v4ZlGxkYlseXwWRJw==, tarball: https://registry.npmmirror.com/v-viewer/-/v-viewer-3.0.11.tgz}
|
||||
peerDependencies:
|
||||
vue: ^3.0.0
|
||||
dependencies:
|
||||
throttle-debounce: 2.3.0
|
||||
lodash: 4.17.21
|
||||
viewerjs: 1.11.6
|
||||
vue: 3.3.7(typescript@5.3.3)
|
||||
dev: false
|
||||
|
||||
/validate-npm-package-license@3.0.4:
|
||||
@ -10480,26 +10531,25 @@ packages:
|
||||
resolution: {integrity: sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==, tarball: https://registry.npmmirror.com/x-is-string/-/x-is-string-0.1.0.tgz}
|
||||
dev: true
|
||||
|
||||
/xgplayer-subtitles@3.0.11(core-js@3.34.0):
|
||||
resolution: {integrity: sha512-m/fk9TeeLuwqnryHTqo5SVVS3w9A27hHe7R1HxWQlk5ZZ5H2CxAXn4dv/PU+gI61DWG3sNkjftlq5duHJtdz2g==, tarball: https://registry.npmmirror.com/xgplayer-subtitles/-/xgplayer-subtitles-3.0.11.tgz}
|
||||
peerDependencies:
|
||||
core-js: '>=3.12.1'
|
||||
/xgplayer-subtitles@1.0.19:
|
||||
resolution: {integrity: sha512-ITvMTgnHD0uytWUYYoS3Qtz10T0o8W0YW3J7/GbfipeJQs4IiFyzhnvTXYB2KnZ6wRXLO6LrNhK9esY9iISJWA==, tarball: https://registry.npmmirror.com/xgplayer-subtitles/-/xgplayer-subtitles-1.0.19.tgz}
|
||||
dependencies:
|
||||
core-js: 3.34.0
|
||||
eventemitter3: 4.0.7
|
||||
generate-source-map: 0.0.5
|
||||
dev: false
|
||||
|
||||
/xgplayer@3.0.11(core-js@3.34.0):
|
||||
resolution: {integrity: sha512-n7qpUG46IVjcYWCFq9WLe4OQpIZvtT67lObu6RPgxbMm8IMGCscTVdbWQjRbgrlsvTVfes3zTfjyaymuS5g17g==, tarball: https://registry.npmmirror.com/xgplayer/-/xgplayer-3.0.11.tgz}
|
||||
peerDependencies:
|
||||
core-js: '>=3.12.1'
|
||||
/xgplayer@2.32.6:
|
||||
resolution: {integrity: sha512-ESwYYcG8SQciPaN43tZkN3r0dS/jQ5RtyxyGbxn2+qcKgZQ861M899xq8Cab/z6qVVX+/4eIsxDbm3lfYGYzvA==, tarball: https://registry.npmmirror.com/xgplayer/-/xgplayer-2.32.6.tgz}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
core-js: 3.34.0
|
||||
chalk: 2.4.2
|
||||
commander: 2.20.3
|
||||
danmu.js: 1.1.13
|
||||
delegate: 3.2.0
|
||||
downloadjs: 1.4.7
|
||||
eventemitter3: 4.0.7
|
||||
xgplayer-subtitles: 3.0.11(core-js@3.34.0)
|
||||
draggabilly: 2.4.1
|
||||
event-emitter: 0.3.5
|
||||
fs-extra: 5.0.0
|
||||
xgplayer-subtitles: 1.0.19
|
||||
dev: false
|
||||
|
||||
/xml-name-validator@4.0.0:
|
||||
|
@ -43,10 +43,6 @@ export function list(params: ListParam) {
|
||||
});
|
||||
}
|
||||
|
||||
export function get(id: string) {
|
||||
return axios.get<FileItem>(`${BASE_URL}/${id}`);
|
||||
}
|
||||
|
||||
export interface FileItemUpdate {
|
||||
name: string;
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
title-align="start"
|
||||
width="90%"
|
||||
modal-animation-name="el-fade"
|
||||
:footer="false"
|
||||
:modal-style="{ maxWidth: '300px' }"
|
||||
@close="cancel"
|
||||
>
|
||||
<a-row justify="center" align="center">
|
||||
<div style="height: 100px">
|
||||
<FileImg :data="fileInfo" style="border-radius: 5px"></FileImg>
|
||||
</div>
|
||||
</a-row>
|
||||
<a-row style="margin-top: 15px">
|
||||
<a-descriptions :column="1" title="详细信息" layout="inline-vertical">
|
||||
<a-descriptions-item :label="title">{{
|
||||
formatFileSize(fileInfo.size)
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">{{
|
||||
fileInfo.createTime
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="修改时间">{{
|
||||
fileInfo.updateTime
|
||||
}}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { FileItem } from '@/api/system/file';
|
||||
import FileImg from '../../main/FileMain/FileImg.vue';
|
||||
|
||||
interface Props {
|
||||
fileInfo: FileItem;
|
||||
onClose: () => void;
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
const visible = ref(false);
|
||||
const title = ref();
|
||||
|
||||
onMounted(() => {
|
||||
title.value = `${props.fileInfo.name}.${props.fileInfo.extension}`;
|
||||
visible.value = true;
|
||||
});
|
||||
|
||||
const cancel = () => {
|
||||
visible.value = false;
|
||||
props.onClose();
|
||||
};
|
||||
|
||||
const formatFileSize = (fileSize: number) => {
|
||||
if (fileSize == null || fileSize === 0) {
|
||||
return '0 Bytes';
|
||||
}
|
||||
const unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
let index = 0;
|
||||
const srcSize = parseFloat(fileSize.toString());
|
||||
index = Math.floor(Math.log(srcSize) / Math.log(1024));
|
||||
const size = srcSize / 1024 ** index;
|
||||
return `${size.toFixed(2)} ${unitArr[index]}`;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.label {
|
||||
color: var(--color-text-2);
|
||||
}
|
||||
:deep(.arco-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
:deep(.arco-form-item-label-col > label) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
:deep(.arco-descriptions-title) {
|
||||
font-size: 14px;
|
||||
}
|
||||
:deep(.arco-descriptions-item-label-inline) {
|
||||
font-size: 12px;
|
||||
}
|
||||
:deep(.arco-descriptions-item-value-inline) {
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="视频播放"
|
||||
:title="title"
|
||||
width="auto"
|
||||
:footer="false"
|
||||
draggable
|
||||
@close="close"
|
||||
>
|
||||
@ -22,8 +23,10 @@
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
const visible = ref(false);
|
||||
const title = ref();
|
||||
|
||||
onMounted(() => {
|
||||
title.value = `${props.fileInfo.name}.${props.fileInfo.extension}`;
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
// eslint-disable-next-line no-new
|
||||
@ -34,6 +37,7 @@
|
||||
autoplay: true,
|
||||
closeVideoClick: true,
|
||||
videoInit: true,
|
||||
fitVideoSize: 'auto',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import ArcoVue from '@arco-design/web-vue';
|
||||
import { FileItem } from '@/api/system/file';
|
||||
|
||||
import FileRenameModal from './FileRenameModal/index.vue';
|
||||
import FileDetailModal from './FileDetailModal/index.vue';
|
||||
import PreviewVideoModal from './PreviewVideoModal/index.vue';
|
||||
import PreviewAudioModal from './PreviewAudioModal/index.vue';
|
||||
|
||||
@ -41,15 +42,22 @@ export function openFileRenameModal(fileItem: FileItem) {
|
||||
return createModal<TFileOptions>(FileRenameModal, { fileInfo: fileItem });
|
||||
}
|
||||
|
||||
/** 打开 详情 弹窗 */
|
||||
export function openFileDetailModal(fileItem: FileItem) {
|
||||
return createModal<TFileOptions>(FileDetailModal, { fileInfo: fileItem });
|
||||
}
|
||||
|
||||
/** 预览 视频文件 弹窗 */
|
||||
export function previewFileVideoModal(fileItem: FileItem) {
|
||||
return createModal<TFileOptions>(PreviewVideoModal, { fileInfo: fileItem });
|
||||
}
|
||||
|
||||
/** 预览 音频文件 弹窗 */
|
||||
let fileAudioId = '';
|
||||
let fileAudioId: string = '';
|
||||
export function previewFileAudioModal(fileItem: FileItem) {
|
||||
if (fileAudioId) return; // 防止重复打开
|
||||
if (fileAudioId) {
|
||||
fileAudioId = '';
|
||||
}
|
||||
fileAudioId = fileItem.id;
|
||||
// eslint-disable-next-line consistent-return
|
||||
return createModal<TFileOptions>(PreviewAudioModal, {
|
||||
|
@ -167,6 +167,9 @@
|
||||
padding: 0 5px;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<img v-if="isImage" class="img" :src="props.data.url || ''" alt="" />
|
||||
<svg-icon v-else :icon-class="getFileImg" style="height: 100%; width: 100%" />
|
||||
<SvgIcon v-else :icon-class="getFileImg" style="height: 100%; width: 100%" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { fileExtendNameIconMap, imageTypeList } from '@/constant/file';
|
||||
import type { FileItem } from '@/api/system/file';
|
||||
import { computed } from 'vue';
|
||||
import SvgIcon from '@/components/svg-icon/index.vue';
|
||||
|
||||
interface Props {
|
||||
data: FileItem;
|
||||
@ -21,9 +22,6 @@
|
||||
|
||||
// 获取文件图标,如果是图片这显示图片
|
||||
const getFileImg = computed<string>(() => {
|
||||
// if (props.data?.isDir) {
|
||||
// return fileExtendNameIconMap.dir || '';
|
||||
// }
|
||||
if (imageTypeList.includes(props.data.extension.toLowerCase())) {
|
||||
return props.data.url || '';
|
||||
}
|
||||
|
@ -8,29 +8,6 @@
|
||||
<template #icon><svg-icon icon-class="menu-download" /></template>
|
||||
<span>下载</span>
|
||||
</GiOptionItem>
|
||||
<a-popover
|
||||
v-if="props.fileInfo.extension === 'zip'"
|
||||
position="right"
|
||||
:content-style="{ padding: 0, overflow: 'hidden', width: '150px' }"
|
||||
:arrow-style="{ display: 'none' }"
|
||||
>
|
||||
<GiOptionItem more>
|
||||
<template #icon><svg-icon icon-class="menu-zip" /></template>
|
||||
<span>解压</span>
|
||||
</GiOptionItem>
|
||||
<template #content>
|
||||
<GiOption>
|
||||
<GiOptionItem @click="onClickItem('zip1')">
|
||||
<template #icon><svg-icon icon-class="file-rar" /></template>
|
||||
<span>解压到当前目录</span>
|
||||
</GiOptionItem>
|
||||
<GiOptionItem @click="onClickItem('zip2')">
|
||||
<template #icon><svg-icon icon-class="file-rar" /></template>
|
||||
<span>解压到其他目录</span>
|
||||
</GiOptionItem>
|
||||
</GiOption>
|
||||
</template>
|
||||
</a-popover>
|
||||
<GiOptionItem @click="onClickItem('detail')">
|
||||
<template #icon><svg-icon icon-class="menu-detail" /></template>
|
||||
<span>详情</span>
|
||||
@ -43,25 +20,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FileItem } from '@/api/system/file';
|
||||
import GiOption from '@/components/gi-option/index.vue';
|
||||
import GiOptionItem from '@/components/gi-option-item/index.vue';
|
||||
|
||||
interface Props {
|
||||
fileInfo?: FileItem;
|
||||
showClassStyle?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
fileInfo: () => ({
|
||||
id: '',
|
||||
name: '',
|
||||
size: 0,
|
||||
url: '',
|
||||
extension: '',
|
||||
type: '',
|
||||
updateTime: '',
|
||||
}), // 文件数据
|
||||
withDefaults(defineProps<Props>(), {
|
||||
showClassStyle: true,
|
||||
});
|
||||
|
||||
|
@ -73,7 +73,7 @@
|
||||
:selected-file-ids="fileStore.selectedFileIds"
|
||||
@click="handleClickFile"
|
||||
@check="handleCheckFile"
|
||||
@rightMenuClick="handleRightMenuClick"
|
||||
@right-menu-click="handleRightMenuClick"
|
||||
></FileGrid>
|
||||
|
||||
<!-- 文件列表-列表模式 -->
|
||||
@ -82,7 +82,7 @@
|
||||
:data="fileList"
|
||||
:is-batch-mode="isBatchMode"
|
||||
@click="handleClickFile"
|
||||
@rightMenuClick="handleRightMenuClick"
|
||||
@right-menu-click="handleRightMenuClick"
|
||||
></FileList>
|
||||
|
||||
<a-empty v-show="!fileList.length"></a-empty>
|
||||
@ -91,26 +91,27 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message, Modal, RequestOption } from '@arco-design/web-vue';
|
||||
import { Modal, RequestOption } from '@arco-design/web-vue';
|
||||
import { api as viewerApi } from 'v-viewer';
|
||||
import { imageTypeList } from '@/constant/file';
|
||||
import { useFileStore } from '@/store/modules/file';
|
||||
import type { ListParam, FileItem } from '@/api/system/file';
|
||||
import { list, del } from '@/api/system/file';
|
||||
import { upload } from '@/api/common';
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
|
||||
import { onBeforeRouteUpdate, useRoute } from 'vue-router';
|
||||
import { getCurrentInstance, onMounted, reactive, ref, toRefs } from 'vue';
|
||||
import FileGrid from './FileGrid.vue';
|
||||
import FileList from './FileList.vue';
|
||||
import {
|
||||
openFileRenameModal,
|
||||
openFileDetailModal,
|
||||
previewFileVideoModal,
|
||||
previewFileAudioModal,
|
||||
} from '../../components/index';
|
||||
import 'viewerjs/dist/viewer.css';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const fileStore = useFileStore();
|
||||
const loading = ref(false);
|
||||
// 文件列表数据
|
||||
@ -152,7 +153,6 @@
|
||||
|
||||
// 点击文件
|
||||
const handleClickFile = (item: FileItem) => {
|
||||
Message.success(`点击了文件-${item.name}`);
|
||||
if (imageTypeList.includes(item.extension)) {
|
||||
if (item.url) {
|
||||
const imgList: string[] = fileList.value
|
||||
@ -196,11 +196,19 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
if (mode === 'download') {
|
||||
const link = document.createElement('a');
|
||||
link.href = fileInfo.url;
|
||||
link.download = fileInfo.name;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
if (mode === 'rename') {
|
||||
openFileRenameModal(fileInfo);
|
||||
}
|
||||
if (mode === 'detail') {
|
||||
// TODO
|
||||
openFileDetailModal(fileInfo);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.query.FileQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.FileReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileResp;
|
||||
import top.charles7c.continew.admin.system.service.FileService;
|
||||
import top.charles7c.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
@ -37,5 +36,5 @@ import top.charles7c.continew.starter.extension.crud.enums.Api;
|
||||
*/
|
||||
@Tag(name = "文件管理 API")
|
||||
@RestController
|
||||
@CrudRequestMapping(value = "/system/file", api = {Api.PAGE, Api.GET, Api.UPDATE, Api.DELETE})
|
||||
public class FileController extends BaseController<FileService, FileResp, FileDetailResp, FileQuery, FileReq> {}
|
||||
@CrudRequestMapping(value = "/system/file", api = {Api.PAGE, Api.UPDATE, Api.DELETE})
|
||||
public class FileController extends BaseController<FileService, FileResp, FileResp, FileQuery, FileReq> {}
|
Loading…
Reference in New Issue
Block a user