diff --git a/web/package.json b/web/package.json
index 1396af4..190031e 100644
--- a/web/package.json
+++ b/web/package.json
@@ -13,6 +13,7 @@
"@element-plus/icons-vue": "^2.3.1",
"@headlessui/vue": "^1.7.12",
"@heroicons/vue": "^2.0.17",
+ "@kangc/v-md-editor": "^2.3.15",
"@soerenmartius/vue3-clipboard": "^0.1.2",
"@tinymce/tinymce-vue": "^5.1.1",
"@types/js-cookie": "^3.0.2",
@@ -20,6 +21,8 @@
"@vueuse/integrations": "^9.13.0",
"@wangeditor/editor": "^5.0.0",
"@wangeditor/editor-for-vue": "^5.1.10",
+ "aplayer": "^1.10.1",
+ "artplayer": "^4.6.1",
"axios": "^1.2.0",
"beautify-qrcode": "^1.0.3",
"better-scroll": "^2.4.2",
@@ -27,13 +30,19 @@
"docx-preview": "^0.3.0",
"echarts": "^5.2.2",
"element-plus": "^2.2.27",
+ "github-markdown-css": "^5.1.0",
+ "highlight.js": "^10.7.2",
+ "hls.js": "^1.3.5",
"html2canvas": "^1.4.1",
"html2pdf.js": "^0.10.1",
"js-base64": "^3.7.5",
"js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2",
"jspdf": "^2.5.1",
+ "marked": "^4.0.17",
"minimatch": "^5.1.0",
+ "monaco-editor": "^0.36.1",
+ "mpegts.js": "^1.7.2",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.0",
@@ -45,8 +54,10 @@
"v-contextmenu": "^3.0.0",
"v3-img-preview-enhance": "^1.1.18",
"vue": "^3.2.40",
+ "vue-3d-loader": "^2.0.8",
"vue-clipboard3": "^2.0.0",
"vue-i18n": "^9.1.9",
+ "vue-pdf-embed": "^1.1.4",
"vue-router": "^4.1.6",
"vue3-print-nb": "^0.1.4",
"vuedraggable": "^4.1.0",
diff --git a/web/src/api/common.js b/web/src/api/common.js
new file mode 100644
index 0000000..82dbe6e
--- /dev/null
+++ b/web/src/api/common.js
@@ -0,0 +1,19 @@
+// import axios from "~/http/request"
+import axiosOrigin from 'axios';
+import request from '@/utils/request';
+
+// 直接获取文件内容
+export const getFileTextReq = (url) => {
+ return axiosOrigin.get(url, {
+ withCredentials: false
+ })
+}
+
+// 调用服务端接口获取文件内容
+export function getFileTextFromServerReq(data){
+ return request({
+ url: "/api/parse/content",
+ method: "get",
+ params:data
+ })
+}
diff --git a/web/src/api/datamanagement/index.ts b/web/src/api/datamanagement/index.ts
new file mode 100644
index 0000000..bc5e9ab
--- /dev/null
+++ b/web/src/api/datamanagement/index.ts
@@ -0,0 +1,120 @@
+import request from '@/utils/request';
+//查询所有试验数据管理试验任务管理
+export function tstaskList() {
+ return request({
+ url: '/experimentalData/tstask/list',
+ method: 'post',
+ });
+}
+//获取试验任务节点树形结构
+export function getTsNodesTree(params:any) {
+ return request({
+ url: '/experimentalData/ts-nodes/getTsNodesTree',
+ method: 'post',
+ params:params,
+ });
+}
+//增加试验任务节点
+export function addTsNodes(params:any) {
+ return request({
+ url: '/experimentalData/ts-nodes/addTsNodes',
+ method: 'post',
+ data:params,
+ });
+}
+// 修改试验任务节点
+export function updateTsNodes(params:any) {
+ return request({
+ url: '/experimentalData/ts-nodes/updateTsNodes',
+ method: 'post',
+ data:params,
+ });
+}
+//根据ID删除试验任务节点
+export function deleteTsNodesById(params:any) {
+ return request({
+ url: '/experimentalData/ts-nodes/deleteTsNodesById',
+ method: 'post',
+ params:params,
+ });
+}
+//分页查询实验数据管理文档内容
+export function tsFilesPage(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/page',
+ method: 'get',
+ params:params,
+ });
+}
+//新增试验数据管理文档内容
+export function addTsFiles(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/addTsFiles',
+ method: 'post',
+ data:params,
+ });
+}
+//修改试验数据管理文档内容
+export function updateTsFiles(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/updateTsFiles',
+ method: 'post',
+ data:params,
+ });
+}
+//根据ID删除试验数据管理文档内容
+export function deleteTsFilesById(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/deleteTsFilesById',
+ method: 'post',
+ params:params,
+ });
+}
+//批量删除试验数据管理文档内容
+export function deleteTsFilesByIds(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/deleteTsFilesByIds',
+ method: 'post',
+ params:params,
+ });
+}
+//压缩
+export function compress(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/compress',
+ method: 'post',
+ params:params,
+ });
+}
+//解压
+export function Decompression(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/decompression',
+ method: 'post',
+ params:params,
+ });
+}
+//对比两个目录的文件差异
+export function compare(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/compare',
+ method: 'post',
+ params:params,
+ });
+}
+//从备份空间下载到工作空间
+export function downloadToLocal(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/downloadToLocal',
+ method: 'post',
+ params:params,
+ });
+}
+//将文件上传到备份空间
+export function uploadToBackup(params:any) {
+ return request({
+ url: '/experimentalData/ts-files/uploadToBackup',
+ method: 'post',
+ params:params,
+ });
+}
\ No newline at end of file
diff --git a/web/src/assets/image/notFound.svg b/web/src/assets/image/notFound.svg
new file mode 100644
index 0000000..2f70182
--- /dev/null
+++ b/web/src/assets/image/notFound.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/src/assets/image/video-download.png b/web/src/assets/image/video-download.png
new file mode 100644
index 0000000..9c24d26
Binary files /dev/null and b/web/src/assets/image/video-download.png differ
diff --git a/web/src/assets/image/video-iina.png b/web/src/assets/image/video-iina.png
new file mode 100644
index 0000000..db4d267
Binary files /dev/null and b/web/src/assets/image/video-iina.png differ
diff --git a/web/src/assets/image/video-motrix.png b/web/src/assets/image/video-motrix.png
new file mode 100644
index 0000000..16aa31b
Binary files /dev/null and b/web/src/assets/image/video-motrix.png differ
diff --git a/web/src/assets/image/video-mxplayer-pro.png b/web/src/assets/image/video-mxplayer-pro.png
new file mode 100644
index 0000000..6f1366e
Binary files /dev/null and b/web/src/assets/image/video-mxplayer-pro.png differ
diff --git a/web/src/assets/image/video-mxplayer.png b/web/src/assets/image/video-mxplayer.png
new file mode 100644
index 0000000..45e0cd1
Binary files /dev/null and b/web/src/assets/image/video-mxplayer.png differ
diff --git a/web/src/assets/image/video-nplayer.png b/web/src/assets/image/video-nplayer.png
new file mode 100644
index 0000000..ef99cf9
Binary files /dev/null and b/web/src/assets/image/video-nplayer.png differ
diff --git a/web/src/assets/image/video-potplayer.png b/web/src/assets/image/video-potplayer.png
new file mode 100644
index 0000000..da1a6d6
Binary files /dev/null and b/web/src/assets/image/video-potplayer.png differ
diff --git a/web/src/assets/image/video-thunder.png b/web/src/assets/image/video-thunder.png
new file mode 100644
index 0000000..c80e6dd
Binary files /dev/null and b/web/src/assets/image/video-thunder.png differ
diff --git a/web/src/assets/image/video-vlc.png b/web/src/assets/image/video-vlc.png
new file mode 100644
index 0000000..8ee6cb0
Binary files /dev/null and b/web/src/assets/image/video-vlc.png differ
diff --git a/web/src/assets/images/chayi.png b/web/src/assets/images/chayi.png
new file mode 100644
index 0000000..176e3c9
Binary files /dev/null and b/web/src/assets/images/chayi.png differ
diff --git a/web/src/assets/images/jieyasuo.png b/web/src/assets/images/jieyasuo.png
new file mode 100644
index 0000000..a9d88a3
Binary files /dev/null and b/web/src/assets/images/jieyasuo.png differ
diff --git a/web/src/assets/images/yasuo.png b/web/src/assets/images/yasuo.png
new file mode 100644
index 0000000..9ff483c
Binary files /dev/null and b/web/src/assets/images/yasuo.png differ
diff --git a/web/src/components/file/ZUpload.vue b/web/src/components/file/ZUpload.vue
index 4b888f3..2ae4e77 100644
--- a/web/src/components/file/ZUpload.vue
+++ b/web/src/components/file/ZUpload.vue
@@ -57,7 +57,7 @@
class="top-0.5 relative inline text-gray-500 mr-1 text-lg cursor-pointer rounded-full hover:bg-gray-200 box animate__animated animate__fadeIn" /> -->
-

@@ -68,7 +68,7 @@
class="inline text-red-500 mr-1 text-base cursor-pointer rounded-full hover:bg-gray-200 box animate__animated animate__fadeIn" /> -->
-

@@ -104,6 +104,7 @@
import common from "@/components/file/common";
import { ref, onMounted,defineEmits } from 'vue';
import { useRoute, useRouter } from 'vue-router';
+import { batchDeleteReq } from "@/api/file-operator";
let router = useRouter();
let route = useRoute();
@@ -135,6 +136,32 @@ const dropBoxRef = ref();
onMounted(() => {
listenDropFile();
})
+function delfile(row){
+// debugger
+let fileArrOne = JSON.parse(localStorage.getItem('fileArr')) || [];
+// 过滤掉不需要的条目
+fileArrOne = fileArrOne.filter(item => item.name !== row.name);
+if(fileArrOne.length > 0){
+ localStorage.setItem('fileArr', JSON.stringify(fileArrOne));
+}else{
+ localStorage.setItem('fileArr', '');
+}
+// 回写 localStorage
+
+const parmas= {
+ deleteItems: [
+ {
+ name: row.name,
+ password: "",
+ path: localStorage.getItem('filepath'),
+ type: "FILE"
+ }
+ ],
+ storageKey: "minio"
+}
+batchDeleteReq(JSON.stringify(parmas)).then((res)=>{
+})
+}
diff --git a/web/src/components/file/file/useFileData.js b/web/src/components/file/file/useFileData.js
index 5c7f3ff..3ad757c 100644
--- a/web/src/components/file/file/useFileData.js
+++ b/web/src/components/file/file/useFileData.js
@@ -169,7 +169,7 @@ export default function useFileData() {
// 点击文件时,判断是文件夹则进入文件夹,是文件则进行预览
const openRow = (row) => {
- if (!row.name) {
+ if (!row.fileName) {
return;
}
fileDataStore.updateCurrentClickRow(row);
@@ -179,8 +179,6 @@ export default function useFileData() {
// 获取文件类型
let fileType = row.fileType;
-
-
switch (fileType) {
case 'video': openVideo(); break;
case 'image': openImage(row); break;
@@ -192,7 +190,7 @@ export default function useFileData() {
default: batchDownloadFile(row);
}
- clearSelection();
+ // clearSelection();
} else {
if (row.type === 'ROOT') {
routerRef.value.push(row.path);
diff --git a/web/src/components/file/file/useFileOperator.js b/web/src/components/file/file/useFileOperator.js
index 5a4c4e6..e028b5a 100644
--- a/web/src/components/file/file/useFileOperator.js
+++ b/web/src/components/file/file/useFileOperator.js
@@ -4,7 +4,7 @@ import {
renameFileReq,
renameFolderReq,
} from "@/api/file-operator";
-
+import { ElMessageBox, ElMessage } from "element-plus";
import useFileDataStore from "@/components/file/stores/file-data";
let fileDataStore = useFileDataStore();
diff --git a/web/src/components/file/file/useFilePreview.js b/web/src/components/file/file/useFilePreview.js
index d466b98..d572901 100644
--- a/web/src/components/file/file/useFilePreview.js
+++ b/web/src/components/file/file/useFilePreview.js
@@ -25,25 +25,26 @@ export default function useFilePreview() {
dialogVideoVisible.value = true;
}
- const openAudio = () => {
- fileDataStore.updateAudioList(fileDataStore.filterFileByType('audio'));
+ const openAudio = (row) => {
+ fileDataStore.updateAudioList([row]);
}
const openImage = (row) => {
// 过滤当前页面中所有图片,并记录当前打开的文件的索引位置
let images = [];
let currIndex = 0;
- let imagePreviewMode = globalConfigStore.zfileConfig.imagePreview.mode;
- if (imagePreviewMode === 'only') {
- images.push(row.url);
- } else {
- fileDataStore.filterFileByType('image').forEach((image, index) => {
- if (row.name === image.name) {
- currIndex = index;
- }
- images.push(image.url);
- })
- }
+ // let imagePreviewMode = globalConfigStore.zfileConfig.imagePreview.mode;
+ images.push(row.url);
+ // if (imagePreviewMode === 'only') {
+
+ // } else {
+ // fileDataStore.filterFileByType('image').forEach((image, index) => {
+ // if (row.name === image.name) {
+ // currIndex = index;
+ // }
+ // images.push(image.url);
+ // })
+ // }
v3ImgPreviewFn({
images: images,
diff --git a/web/src/components/file/file/useFileUpload.js b/web/src/components/file/file/useFileUpload.js
index 5e04a78..b002885 100644
--- a/web/src/components/file/file/useFileUpload.js
+++ b/web/src/components/file/file/useFileUpload.js
@@ -1,4 +1,5 @@
import {ElLoading} from "element-plus";
+import { ElMessageBox, ElMessage } from "element-plus";
import { ref,reactive,computed,nextTick,watch} from "vue";
import {uploadFileReq} from "@/api/file-operator";
import axios from "axios";
@@ -354,10 +355,14 @@ export default function useFileUpload() {
* @param param
*/
const beforeUpload = (param) => {
- uploadFile(param.file, param.uploadBasePath);
+ let storageKeyArr = JSON.parse(localStorage.getItem('storageKey'))
+ storageKeyArr.forEach(item=>{
+ uploadFile(param.file, param.uploadBasePath,item);
+ })
+
}
// 文件上传操作.
- const uploadFile = (file, uploadBasePath) => {
+ const uploadFile = (file, uploadBasePath,item) => {
const fileIndex = uploadIndex++;
uploadBasePath = uploadBasePath || currentPath.value;
@@ -385,7 +390,7 @@ export default function useFileUpload() {
})
}
let param = {
- storageKey: 'minio',
+ storageKey: item,
path: localStorage.getItem('filepath'),
name: file.name,
size: file.size
@@ -438,13 +443,19 @@ export default function useFileUpload() {
let proxyUploadType = common.storageType.proxyType;
let s3UploadType = common.storageType.s3Type;
let onedriveUploadType = common.storageType.micrsoftType;
- if (proxyUploadType.includes( param.storageKey)) {
+ let storagea
+ if( param.storageKey === 'local'){
+ storagea = 'local'
+ }else if( param.storageKey === 'minio'){
+ storagea = 'minio'
+ }
+ if (proxyUploadType.includes( storagea)) {
fileProxyUpload(file, res.data, fileIndex);
- } else if (s3UploadType.includes( param.storageKey)) {
+ } else if (s3UploadType.includes( storagea)) {
s3FileUpload(file, res.data, fileIndex);
- } else if (onedriveUploadType.includes( param.storageKey)) {
+ } else if (onedriveUploadType.includes( storagea)) {
onedriveUpload(file, res.data, fileIndex);
- } else if ( param.storageKey === 'upyun') {
+ } else if ( storagea === 'upyun') {
upyunFileUpload(file, res.data, fileIndex);
}
}).catch((err) => {
diff --git a/web/src/components/file/preview/AudioPlayer.vue b/web/src/components/file/preview/AudioPlayer.vue
new file mode 100644
index 0000000..bd6854a
--- /dev/null
+++ b/web/src/components/file/preview/AudioPlayer.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/CopyCode.vue b/web/src/components/file/preview/CopyCode.vue
new file mode 100644
index 0000000..eb0bedf
--- /dev/null
+++ b/web/src/components/file/preview/CopyCode.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/FileGallery.vue b/web/src/components/file/preview/FileGallery.vue
new file mode 100644
index 0000000..a59ca29
--- /dev/null
+++ b/web/src/components/file/preview/FileGallery.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
+ {{colItem.name}}
+ {{common.fileSizeFormat(colItem.size)}}
+
+
+ {{ colItem.name }}
+
+
+
+
+
+
+
+ 退出画廊模式
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/MarkdownViewer.vue b/web/src/components/file/preview/MarkdownViewer.vue
new file mode 100644
index 0000000..85d1a63
--- /dev/null
+++ b/web/src/components/file/preview/MarkdownViewer.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/MarkdownViewerAsyncLoading.vue b/web/src/components/file/preview/MarkdownViewerAsyncLoading.vue
new file mode 100644
index 0000000..b37d36b
--- /dev/null
+++ b/web/src/components/file/preview/MarkdownViewerAsyncLoading.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/MarkdownViewerDialogAsyncLoading.vue b/web/src/components/file/preview/MarkdownViewerDialogAsyncLoading.vue
new file mode 100644
index 0000000..5bec774
--- /dev/null
+++ b/web/src/components/file/preview/MarkdownViewerDialogAsyncLoading.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/OfficeViewer.vue b/web/src/components/file/preview/OfficeViewer.vue
new file mode 100644
index 0000000..94a1238
--- /dev/null
+++ b/web/src/components/file/preview/OfficeViewer.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/PdfViewer.vue b/web/src/components/file/preview/PdfViewer.vue
new file mode 100644
index 0000000..82fb5a7
--- /dev/null
+++ b/web/src/components/file/preview/PdfViewer.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/TextViewer.vue b/web/src/components/file/preview/TextViewer.vue
new file mode 100644
index 0000000..846e46f
--- /dev/null
+++ b/web/src/components/file/preview/TextViewer.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/TextViewerAsyncLoading.vue b/web/src/components/file/preview/TextViewerAsyncLoading.vue
new file mode 100644
index 0000000..ca5d42a
--- /dev/null
+++ b/web/src/components/file/preview/TextViewerAsyncLoading.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/Three3dPreview.vue b/web/src/components/file/preview/Three3dPreview.vue
new file mode 100644
index 0000000..ae05f61
--- /dev/null
+++ b/web/src/components/file/preview/Three3dPreview.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/components/file/preview/VideoPlayer.vue b/web/src/components/file/preview/VideoPlayer.vue
new file mode 100644
index 0000000..f6a46f7
--- /dev/null
+++ b/web/src/components/file/preview/VideoPlayer.vue
@@ -0,0 +1,576 @@
+
+
+
+
+
+
+
+
+ tips: 可点击上方的软件图标进行下载播放, 本地播放器解码效果更佳.
+
+
+
+
+
+
+
diff --git a/web/src/components/file/preview/VideoPlayerAsyncLoading.vue b/web/src/components/file/preview/VideoPlayerAsyncLoading.vue
new file mode 100644
index 0000000..45bfc96
--- /dev/null
+++ b/web/src/components/file/preview/VideoPlayerAsyncLoading.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/views/component/Viewfile.vue b/web/src/views/component/Viewfile.vue
index bd4785f..fac18e9 100644
--- a/web/src/views/component/Viewfile.vue
+++ b/web/src/views/component/Viewfile.vue
@@ -1,101 +1,65 @@
-
-
-
-
+
+
-
![]()
+
-
-
+
+ element-loading-background="rgba(122, 122, 122, 0.8)" class="docWrap">
-
+
-
-
diff --git a/web/src/views/special/document/index.vue b/web/src/views/special/document/index.vue
index dcf34f9..2219105 100644
--- a/web/src/views/special/document/index.vue
+++ b/web/src/views/special/document/index.vue
@@ -5,16 +5,29 @@ export default {
@@ -518,7 +671,12 @@ function findPathById(array: any, targetId: any) {
style="width: 100%; height: calc(100vh - 275px);margin-bottom: 20px;" border>
-
+
+
+ {{ scope.row.fileName }}(点击预览)
+
+
@@ -583,6 +741,40 @@ function findPathById(array: any, targetId: any) {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -683,4 +875,12 @@ function findPathById(array: any, targetId: any) {
}
}
}
+.tableHover {
+ cursor: pointer;
+}
+
+.tableHover:hover {
+ color: #409eff;
+}
+
diff --git a/web/src/views/testdata/datamanagement/index.vue b/web/src/views/testdata/datamanagement/index.vue
index e69de29..dcbd3ad 100644
--- a/web/src/views/testdata/datamanagement/index.vue
+++ b/web/src/views/testdata/datamanagement/index.vue
@@ -0,0 +1,1194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+ 上传
+ 删除
+ 下载
+
+
+
+
+
+
+
+
+ {{ scope.row.nodeName }} (点击进入节点)
+ {{ scope.row.fileName }} (点击预览)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定
+ 取消
+
+
+
+
+
+
+
+ 上传文件
+ 上传文件夹
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定
+ 取消
+
+
+
+
+
+
+
+
+
+
+
+ 备份空间缺失的文件:
+ {{ item.name + '(' + item.path + ')' }}
+
+
+
+
+
+
+ 将文件从 工作空间 上传到 备份空间
+
+
+
+
+
+ 工作空间缺失的文件:
+ {{ item.name + '(' + item.path + ')' }}
+
+
+
+
+ 将文件从 备份空间 下载到 工作空间
+
+
+
+
+
+
+
MD5哈希值不一致的文件:{{ item.name + '(' + item.path + ')' }}
+
本地 MD5:{{ item.locatMd5 }}
+
minio MD5:{{ item.minioMd5 }}
+
+
+
MD5哈希值不一致的文件:
+
本地 MD5:
+
minio MD5:
+
+
+
+
+
+
+
覆盖 备份空间中的文件
+
+
覆盖 工作空间中的文件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+