Compare commits

...

2 Commits

Author SHA1 Message Date
735156bbbd 更改 2025-04-07 17:10:59 +08:00
5a9feedbec 文档改动 2025-04-07 17:10:59 +08:00
2 changed files with 420 additions and 228 deletions

View File

@ -70,4 +70,28 @@ export function obtainUrl(params:any) {
method: 'post', method: 'post',
params:params, params:params,
}); });
} }
//文件差异-新增
export function compareLocal(params:any) {
return request({
url: '/experimentalData/ts-files/compareLocal',
method: 'post',
params:params,
});
}
//文件差异变更
export function compareMd5(params:any) {
return request({
url: '/experimentalData/ts-files/compareMd5',
method: 'post',
params:params,
});
}
//文件差异-缺失
export function compareMinio(params:any) {
return request({
url: '/experimentalData/ts-files/compareMinio',
method: 'post',
params:params,
});
}

View File

@ -9,8 +9,9 @@ import { ref, onMounted, nextTick, defineAsyncComponent, onBeforeUnmount } from
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import { ElMessageBox, ElMessage } from "element-plus"; import { ElMessageBox, ElMessage } from "element-plus";
import { tstaskList, getTsNodesTree, tsFilesPage, deleteTsFilesByIds } from "@/api/datamanagement"; import { tstaskList, getTsNodesTree, tsFilesPage, deleteTsFilesByIds } from "@/api/datamanagement";
import { listLocalAndBackup, compare, uploadToBackup, downloadToLocal, deleteTsFilesById,automaticFileBackup,obtainUrl } from "@/api/fileSynchronization"; import { listLocalAndBackup, compare, compareLocal, compareMd5, compareMinio, uploadToBackup, downloadToLocal, deleteTsFilesById, automaticFileBackup, obtainUrl, listBackupTree, listLocalTree } from "@/api/fileSynchronization";
import { debounce } from 'lodash-es'; import { debounce } from 'lodash-es';
import Page from '@/components/Pagination/page.vue';
//text //text
import textEdit from '@/components/textEditing/index.vue' import textEdit from '@/components/textEditing/index.vue'
import txtexl from '@/components/textEditing/txtexl.vue' import txtexl from '@/components/textEditing/txtexl.vue'
@ -69,38 +70,73 @@ function diffFile() {
comparearr.value = comparearr.value.filter(item => { comparearr.value = comparearr.value.filter(item => {
return seen.has(item.id) ? false : seen.add(item.id); return seen.has(item.id) ? false : seen.add(item.id);
}); });
tabs.value = 3
differential.value = true differential.value = true
getchayi() // getchayi()
diffSure()
diffChange()
diffMiss()
} }
function backups(){ function backups() {
ElMessageBox.confirm( ElMessageBox.confirm(
'您确定要将文件/文件夹自动备份到备份空间吗?', '您确定要将文件/文件夹自动备份到备份空间吗?',
'警告', '警告',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
}
)
.then(() => {
worktree.value = true
worktree1.value = true
automaticFileBackup({ nodeId: pathid.value, taskId: projectId.value }).then((res: any) => {
if (res.code == 0) {
ElMessage.success(res.msg)
getlocaltree()
getminiotree()
} }
) })
.then(() => { })
worktree.value = true
automaticFileBackup({ nodeId: pathid.value, taskId: projectId.value }).then((res: any) => {
if(res.code == 0){
ElMessage.success(res.msg)
getWorkData()
}
})
})
} }
// //
const comparearr: any = ref([]) const comparearr: any = ref([])
const localOnlyFiles: any = ref([]) const localOnlyFiles: any = ref([])
const md5MismatchedFiles: any = ref([]) const md5MismatchedFiles: any = ref([])
const minioOnlyFiles: any = ref([]) const minioOnlyFiles: any = ref([])
const loading = ref(false) const loading1 = ref(false)
function getchayi() { const loading2 = ref(false)
loading.value = true const loading3 = ref(false)
// function getchayi() {
// loading.value = true
// const ids = []
// const params: any = {}
// if (comparearr.value.length > 0) {
// comparearr.value.forEach((item: any) => {
// ids.push(item.id)
// })
// params.id = ids.join(',')
// } else {
// params.nodeId = pathid.value
// params.taskId = projectId.value
// }
// compare(params).then((res: any) => {
// localOnlyFiles.value = res.data.localOnlyFiles
// md5MismatchedFiles.value = res.data.md5MismatchedFiles
// minioOnlyFiles.value = res.data.minioOnlyFiles
// loading.value = false
// diffColor()
// })
// }
//-
const sureSize = ref(100)
const sureTotal = ref()
const sureCurrent = ref(1)
function diffSure() {
loading1.value = true
const ids = [] const ids = []
const params: any = {} const params: any = {}
if (comparearr.value.length > 0) { if (comparearr.value.length > 0) {
@ -112,49 +148,129 @@ function getchayi() {
params.nodeId = pathid.value params.nodeId = pathid.value
params.taskId = projectId.value params.taskId = projectId.value
} }
params.size = sureSize.value
params.current = sureCurrent.value
compare(params).then((res: any) => { compareLocal(params).then((res: any) => {
localOnlyFiles.value = res.data.localOnlyFiles loading1.value = false
md5MismatchedFiles.value = res.data.md5MismatchedFiles localOnlyFiles.value = res.data.records
minioOnlyFiles.value = res.data.minioOnlyFiles sureSize.value = res.data.size
loading.value = false sureTotal.value = res.data.total
diffColor() sureCurrent.value = res.data.current
// diffColor()
})
}
//-
const ChangeSize = ref(10)
const ChangeTotal = ref()
const ChangeCurrent = ref(1)
function diffChange() {
loading2.value = true
const ids = []
const params: any = {}
if (comparearr.value.length > 0) {
comparearr.value.forEach((item: any) => {
ids.push(item.id)
})
params.id = ids.join(',')
} else {
params.nodeId = pathid.value
params.taskId = projectId.value
}
params.size = ChangeSize.value
params.current = ChangeCurrent.value
compareMd5(params).then((res: any) => {
md5MismatchedFiles.value = res.data.records
loading2.value = false
ChangeSize.value = res.data.size
ChangeTotal.value = res.data.total
ChangeCurrent.value = res.data.current
// diffColor()
})
}
//-
const MisseSize = ref(100)
const MissTotal = ref()
const MissCurrent = ref(1)
function diffMiss() {
loading3.value = true
const ids = []
const params: any = {}
if (comparearr.value.length > 0) {
comparearr.value.forEach((item: any) => {
ids.push(item.id)
})
params.id = ids.join(',')
} else {
params.nodeId = pathid.value
params.taskId = projectId.value
}
params.size = MisseSize.value
params.current = MissCurrent.value
compareMinio(params).then((res: any) => {
minioOnlyFiles.value = res.data.records
loading3.value = false
MisseSize.value = res.data.size
MissTotal.value = res.data.total
MissCurrent.value = res.data.current
// diffColor()
}) })
} }
// //
// diffColor
function diffColor() { function diffColor() {
if (workdata.value.length > 0 && localOnlyFiles.value.length > 0) { // 1. 使Map
workdata.value = changeColor(workdata.value, localOnlyFiles.value, '1') const createMap = (arr: any[]) => new Map(arr.map(item => [item.id, item]));
}
if (workdata.value.length > 0 && md5MismatchedFiles.value.length > 0) { const localMap = createMap(localOnlyFiles.value);
workdata.value = changeColor(workdata.value, md5MismatchedFiles.value, '2') const md5Map = createMap(md5MismatchedFiles.value);
backupsdata.value = changeColor(backupsdata.value, md5MismatchedFiles.value, '2') const minioMap = createMap(minioOnlyFiles.value);
}
if (backupsdata.value.length > 0 && minioOnlyFiles.value.length > 0) {
backupsdata.value = changeColor(backupsdata.value, minioOnlyFiles.value, '3')
}
workref.value!.setCheckedKeys([], false)
beifentree.value!.setCheckedKeys([], false)
}
//
function changeColor(data: any, data2: any, type: any) {
data.forEach((item: any) => {
data2.forEach((item2: any) => {
if (item.id == item2.id) {
item.station = type
}
if (item.children.length > 0) {
changeColor(item.children, data2, type)
}
})
})
return data
// 2.
const processTree = (tree: any[], location: 'local' | 'minio') => {
const stack = [...tree];
while (stack.length) {
const node = stack.pop();
if (!node) continue;
// 3. 使
let status = 0;
if (location === 'local') {
status |= localMap.has(node.id) ? 1 : 0;
status |= md5Map.has(node.id) ? 2 : 0;
} else {
status |= minioMap.has(node.id) ? 3 : 0;
status |= md5Map.has(node.id) ? 2 : 0;
}
// 4. 使
node.station = status.toString(10).split('').sort().reverse()[0];
// 5.
if (node.children?.length) {
stack.push(...node.children);
}
}
};
// 6.
if (workdata.value.length) {
processTree(workdata.value, 'local');
}
if (backupsdata.value.length) {
processTree(backupsdata.value, 'minio');
}
// 7. UI
nextTick(() => {
workref.value?.setCheckedKeys([], false);
beifentree.value?.setCheckedKeys([], false);
});
} }
function diffClose() { function diffClose() {
differential.value = false differential.value = false
getWorkData() getlocaltree()
getminiotree()
} }
// //
@ -173,7 +289,7 @@ function gettreedata() {
treedata.value = res.data treedata.value = res.data
treeloading.value = false treeloading.value = false
if (treedata.value[0].nodeId) { if (treedata.value[0].nodeId) {
pathid.value = treedata.value[0].nodeId // pathid.value = treedata.value[0].nodeId
// nextTick(() => { // nextTick(() => {
// treeRef.value?.setCurrentKey(pathid.value); // treeRef.value?.setCurrentKey(pathid.value);
// }); // });
@ -187,14 +303,17 @@ function gettreedata() {
} }
function handleNodeClick(data: any, node: any) { function handleNodeClick(data: any, node: any) {
pathid.value = data.nodeId pathid.value = data.nodeId
getWorkData() getlocaltree()
getminiotree()
} }
// //
const handleCheckChange = debounce(( const handleCheckChange = (
data: any, data: any,
checked: boolean, checked: boolean,
indeterminate: boolean indeterminate: boolean
) => { ) => {
console.log(data)
// debugger
if (checked === true && indeterminate === false) { if (checked === true && indeterminate === false) {
workall.value.push(data) workall.value.push(data)
} else { } else {
@ -202,7 +321,7 @@ const handleCheckChange = debounce((
} }
comparearr.value = getclickdata(workall.value) comparearr.value = getclickdata(workall.value)
beifentree.value!.setCheckedNodes(comparearr.value, false) beifentree.value!.setCheckedNodes(comparearr.value, false)
}, 300) }
// //
function getclickdata(data: any) { function getclickdata(data: any) {
data.forEach((item: any) => { data.forEach((item: any) => {
@ -219,21 +338,46 @@ function getclickdata(data: any) {
} }
// //
// //
function getWorkData() { // function getWorkData() {
// worktree.value = true
// listLocalAndBackup({ taskId: projectId.value, nodeId: pathid.value }).then((res: any) => {
// workdata.value = res.data.localTrees
// backupsdata.value = res.data.minioTrees
// if (workdata.value.length > 0) {
// assignment(workdata.value, 'local')
// }
// if (backupsdata.value.length > 0) {
// assignment(backupsdata.value, 'minio')
// }
// worktree.value = false
// diffColor()
// })
// }
//
function getlocaltree() {
worktree.value = true worktree.value = true
listLocalAndBackup({ taskId: projectId.value, nodeId: pathid.value }).then((res: any) => { listLocalTree({ taskId: projectId.value, nodeId: pathid.value }).then((res: any) => {
workdata.value = res.data.localTrees workdata.value = res.data.localTrees
backupsdata.value = res.data.minioTrees
if (workdata.value.length > 0) { if (workdata.value.length > 0) {
assignment(workdata.value, 'local') assignment(workdata.value, 'local')
} }
if (backupsdata.value.length > 0) {
assignment(backupsdata.value, 'minio')
}
worktree.value = false worktree.value = false
diffColor() diffColor()
}) })
}
const worktree1 = ref(false)
//minio
function getminiotree() {
worktree1.value = true
listBackupTree({ taskId: projectId.value, nodeId: pathid.value }).then((res: any) => {
backupsdata.value = res.data.minioTrees
if (backupsdata.value.length > 0) {
assignment(backupsdata.value, 'minio')
}
worktree1.value = false
diffColor()
})
} }
// //
function assignment(data: any, difference: any) { function assignment(data: any, difference: any) {
@ -247,7 +391,7 @@ function assignment(data: any, difference: any) {
} }
// //
const beifentree = ref() const beifentree = ref()
const backupsChange = debounce(( const backupsChange = (
data: any, data: any,
checked: boolean, checked: boolean,
indeterminate: boolean indeterminate: boolean
@ -257,9 +401,10 @@ const backupsChange = debounce((
} else { } else {
workall.value = workall.value.filter(item => item.id !== data.id); workall.value = workall.value.filter(item => item.id !== data.id);
} }
comparearr.value = getclickdata(workall.value) comparearr.value = getclickdata(workall.value)
workref.value!.setCheckedNodes(comparearr.value, false) workref.value!.setCheckedNodes(comparearr.value, false)
}, 300) }
// //
const handleRightClick = (event: Event, data: any, node: any) => { const handleRightClick = (event: Event, data: any, node: any) => {
if (data.station != '0') { if (data.station != '0') {
@ -312,7 +457,8 @@ const handleMenuClick = (action: string, type: any) => {
ElMessage.success("恢复成功") ElMessage.success("恢复成功")
minioOnlyFiles.value = minioOnlyFiles.value.filter((item: any) => item.id !== currentNode.value.id) minioOnlyFiles.value = minioOnlyFiles.value.filter((item: any) => item.id !== currentNode.value.id)
md5MismatchedFiles.value = md5MismatchedFiles.value.filter((item: any) => item.id !== currentNode.value.id) md5MismatchedFiles.value = md5MismatchedFiles.value.filter((item: any) => item.id !== currentNode.value.id)
getWorkData() getlocaltree()
getminiotree()
} }
}) })
}) })
@ -340,7 +486,8 @@ const handleMenuClick = (action: string, type: any) => {
ElMessage.success("上传成功") ElMessage.success("上传成功")
localOnlyFiles.value = localOnlyFiles.value.filter((item: any) => item.id !== currentNode.value.id) localOnlyFiles.value = localOnlyFiles.value.filter((item: any) => item.id !== currentNode.value.id)
md5MismatchedFiles.value = md5MismatchedFiles.value.filter((item: any) => item.id !== currentNode.value.id) md5MismatchedFiles.value = md5MismatchedFiles.value.filter((item: any) => item.id !== currentNode.value.id)
getWorkData() getlocaltree()
getminiotree()
// getchayi() // getchayi()
} }
}) })
@ -351,14 +498,15 @@ const handleMenuClick = (action: string, type: any) => {
deleteTsFilesById({ id: currentNode.value.id, type: type }).then((res: any) => { deleteTsFilesById({ id: currentNode.value.id, type: type }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
ElMessage.success("删除成功") ElMessage.success("删除成功")
getWorkData() getlocaltree()
getminiotree()
} }
}) })
break break
case 'preview': case 'preview':
// //
openPreview(currentNode.value,type) openPreview(currentNode.value, type)
break break
} }
} }
@ -381,10 +529,10 @@ function tableBeifen(row: any) {
) )
.then(() => { .then(() => {
const params = [{ const params = [{
path: '/' + pathid.value + row.path, path: '/' + pathid.value + row.workPath,
name: row.name, name: row.fileName,
size: row.size, size: row.fileSize,
type: row.type type: row.isFile
}] }]
uploadToBackup({ parameterLists: params }).then((res: any) => { uploadToBackup({ parameterLists: params }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
@ -411,11 +559,13 @@ function moretableBeifen() {
} }
) )
.then(() => { .then(() => {
let beifenArr3 = []
let beifenArr2 = JSON.parse(JSON.stringify(beifenArr.value)) let beifenArr2 = JSON.parse(JSON.stringify(beifenArr.value))
beifenArr2.forEach((items: any) => { beifenArr2.forEach((items: any) => {
items.path = '/' + pathid.value + items.path beifenArr3.push({ path: '/' + pathid.value + items.workPath, name: items.fileName, size: items.fileSize, type: items.isFile })
// items.path = '/' + pathid.value + items.path
}) })
uploadToBackup({ parameterLists: beifenArr2 }).then((res: any) => { uploadToBackup({ parameterLists: beifenArr3 }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
ElMessage.success("上传成功") ElMessage.success("上传成功")
beifenArr.value.forEach((items: any) => { beifenArr.value.forEach((items: any) => {
@ -441,10 +591,10 @@ function tablerestore(row: any) {
) )
.then(() => { .then(() => {
const params = [{ const params = [{
path: '/' + pathid.value + row.path, path: '/' + pathid.value + row.backupPath,
name: row.name, name: row.fileName,
size: row.size, size: row.fileSize,
type: row.type type: row.isFile
}] }]
downloadToLocal({ parameterLists: params }).then((res: any) => { downloadToLocal({ parameterLists: params }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
@ -470,11 +620,13 @@ function moretablerestore() {
} }
) )
.then(() => { .then(() => {
let restoreArr3 = []
let restoreArr2 = JSON.parse(JSON.stringify(restoreArr.value)) let restoreArr2 = JSON.parse(JSON.stringify(restoreArr.value))
restoreArr2.forEach((items: any) => { restoreArr2.forEach((items: any) => {
items.path = '/' + pathid.value + items.path restoreArr3.push({ path: '/' + pathid.value + items.backupPath, name: items.fileName, size: items.fileSize, type: items.isFile })
}) })
downloadToLocal({ parameterLists: restoreArr2 }).then((res: any) => { downloadToLocal({ parameterLists: restoreArr3 }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
ElMessage.success("恢复成功") ElMessage.success("恢复成功")
restoreArr.value.forEach((items: any) => { restoreArr.value.forEach((items: any) => {
@ -535,11 +687,12 @@ function bfclick(type: any) {
) )
.then(() => { .then(() => {
if (type == 'bf') { if (type == 'bf') {
let beifenArr3 = []
let beifenArr2 = JSON.parse(JSON.stringify(changeclick.value)) let beifenArr2 = JSON.parse(JSON.stringify(changeclick.value))
beifenArr2.forEach((items: any) => { beifenArr2.forEach((items: any) => {
items.path = '/' + pathid.value + items.path beifenArr3.push({ path: '/' + pathid.value + items.workPath, name: items.fileName, size: items.fileSize, type: items.isFile })
}) })
uploadToBackup({ parameterLists: beifenArr2 }).then((res: any) => { uploadToBackup({ parameterLists: beifenArr3 }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
ElMessage.success("上传成功") ElMessage.success("上传成功")
changeclick.value.forEach((items: any) => { changeclick.value.forEach((items: any) => {
@ -548,11 +701,12 @@ function bfclick(type: any) {
} }
}) })
} else { } else {
let restoreArr3 = []
let restoreArr2 = JSON.parse(JSON.stringify(changeclick.value)) let restoreArr2 = JSON.parse(JSON.stringify(changeclick.value))
restoreArr2.forEach((items: any) => { restoreArr2.forEach((items: any) => {
items.path = '/' + pathid.value + items.path restoreArr3.push({ path: '/' + pathid.value + items.backupPath, name: items.fileName, size: items.fileSize, type: items.isFile })
}) })
downloadToLocal({ parameterLists: restoreArr2 }).then((res: any) => { downloadToLocal({ parameterLists: restoreArr3 }).then((res: any) => {
if (res.code == '0') { if (res.code == '0') {
ElMessage.success("恢复成功") ElMessage.success("恢复成功")
changeclick.value.forEach((items: any) => { changeclick.value.forEach((items: any) => {
@ -570,9 +724,9 @@ onMounted(() => {
getProject() getProject()
}); });
// //
onBeforeUnmount(() => { // onBeforeUnmount(() => {
handleCheckChange.cancel() // handleCheckChange.cancel()
}) // })
// //
const vMove = { const vMove = {
mounted(el: any) { mounted(el: any) {
@ -619,35 +773,35 @@ const Three3dPreview = defineAsyncComponent({
}) })
// //
const filePreview: any = ref({}) const filePreview: any = ref({})
const ViewfileUrl:any = ref("") const ViewfileUrl: any = ref("")
const title1 = ref('') const title1 = ref('')
const isViewfile = ref(false) const isViewfile = ref(false)
const fileType = ref('') const fileType = ref('')
function openPreview(row: any,type:any) { function openPreview(row: any, type: any) {
if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'pptx' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'xls' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') { if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'pptx' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'xls' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') {
title1.value = row.fileName title1.value = row.fileName
geturl(row.id,type,true) geturl(row.id, type, true)
isViewfile.value = true isViewfile.value = true
fileType.value = getFileExtension(row.fileName) fileType.value = getFileExtension(row.fileName)
} else { } else {
row.fileType = getFileType(row.fileName) row.fileType = getFileType(row.fileName)
filePreview.value = row filePreview.value = row
geturl(row.id,type,false) geturl(row.id, type, false)
console.log(filePreview.value) console.log(filePreview.value)
localStorage.setItem('videorow', JSON.stringify(row)); localStorage.setItem('videorow', JSON.stringify(row));
openRow(row) openRow(row)
} }
} }
function geturl(row:any,type1:any,pan:any){ function geturl(row: any, type1: any, pan: any) {
obtainUrl({id:row,type:type1}).then((res:any)=>{ obtainUrl({ id: row, type: type1 }).then((res: any) => {
if(pan){ if (pan) {
ViewfileUrl.value = res.data.url ViewfileUrl.value = res.data.url
}else{ } else {
filePreview.value.url = res.data.url filePreview.value.url = res.data.url
} }
}) })
} }
@ -753,16 +907,17 @@ const tabs = ref(1)
</aside> </aside>
<section class="silderRight"> <section class="silderRight">
<div class="tree_button"> <div class="tree_button">
<el-button type="primary" :disabled="worktree" @click="backups()">文件自动备份</el-button> <el-button type="primary" :disabled="worktree && worktree1" @click="backups()">文件自动备份</el-button>
<el-button type="primary" :disabled="worktree" @click="diffFile()">文件差异性对比</el-button> <el-button type="primary" :disabled="worktree && worktree1" @click="diffFile()">文件差异性对比</el-button>
<el-button type="primary" :disabled="worktree" @click="differential = true">查看本次差异性对比</el-button> <el-button type="primary" :disabled="worktree && worktree1"
@click="differential = true">查看本次差异性对比</el-button>
</div> </div>
<div class="tree_box"> <div class="tree_box">
<div class="tree_left"> <div class="tree_left">
<div class="tree_title">工作空间:</div> <div class="tree_title">工作空间:</div>
<div class="tree_content"> <div class="tree_content">
<el-scrollbar height="73vh"> <el-scrollbar height="73vh">
<el-tree ref="workref" style="max-width: 600px" :props="props" :data="workdata" <el-tree ref="workref" style="max-width: 600px" :props="props" :data="workdata"
@node-click="workclick" @node-contextmenu="handleRightClick" default-expand-all @node-click="workclick" @node-contextmenu="handleRightClick" default-expand-all
:expand-on-click-node="false" show-checkbox node-key="id" v-loading="worktree" :expand-on-click-node="false" show-checkbox node-key="id" v-loading="worktree"
@check-change="handleCheckChange"> @check-change="handleCheckChange">
@ -798,7 +953,7 @@ const tabs = ref(1)
<el-scrollbar height="73vh"> <el-scrollbar height="73vh">
<el-tree ref="beifentree" style="max-width: 600px" :props="props" :data="backupsdata" <el-tree ref="beifentree" style="max-width: 600px" :props="props" :data="backupsdata"
default-expand-all @node-click="workclick" @node-contextmenu="handleRightClick" default-expand-all @node-click="workclick" @node-contextmenu="handleRightClick"
:expand-on-click-node="false" show-checkbox node-key="id" v-loading="worktree" :expand-on-click-node="false" show-checkbox node-key="id" v-loading="worktree1"
@check-change="backupsChange"> @check-change="backupsChange">
<template #default="{ data }"> <template #default="{ data }">
<span <span
@ -830,126 +985,135 @@ const tabs = ref(1)
<el-dialog title="文件差异性对比" v-model="differential" width="50%" :before-close="diffClose" top="30px" <el-dialog title="文件差异性对比" v-model="differential" width="50%" :before-close="diffClose" top="30px"
draggable destroy-on-close> draggable destroy-on-close>
<div class="tabbs_all"> <div class="tabbs_all">
<div @click="tabs = 1" :class="tabs == 1?'tabbs_box1':'tabbs_box'">新增内容</div> <div @click="tabs = 1" :class="tabs == 1 ? 'tabbs_box1' : 'tabbs_box'">新增内容</div>
<div @click="tabs = 2" :class="tabs == 2?'tabbs_box1':'tabbs_box'">变更内容</div> <div @click="tabs = 2" :class="tabs == 2 ? 'tabbs_box1' : 'tabbs_box'">变更内容</div>
<div @click="tabs = 3" :class="tabs == 3?'tabbs_box1':'tabbs_box'">缺失内容</div> <div @click="tabs = 3" :class="tabs == 3 ? 'tabbs_box1' : 'tabbs_box'">缺失内容</div>
</div> </div>
<div> <div>
<!-- <el-scrollbar height="400px"> --> <!-- <el-scrollbar height="400px"> -->
<div class="newContent" v-if="tabs == 1"> <div class="newContent" v-if="tabs == 1">
<div class="newContent_title"> <div class="newContent_title">
<el-button type="primary" :disabled="beifenArr.length == 0" <el-button type="primary" :disabled="beifenArr.length == 0"
@click="moretableBeifen()">备份</el-button> @click="moretableBeifen()">备份</el-button>
</div>
<el-table v-loading="loading" :data="localOnlyFiles" @selection-change="bifenChange"
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
style="width: 100%; height: calc(60vh);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<!-- <el-table-column type="index" label="序号" width="70" align="center"></el-table-column> -->
<el-table-column prop="name" label="文件名称"></el-table-column>
<el-table-column prop="type" label="文件类型" width="90">
<template #default="scope">
<span v-if="scope.row.type == 'FOLDER'">文件夹</span>
<span v-else>文件</span>
</template>
</el-table-column>
<el-table-column prop="size" label="文件大小" width="100">
<template #default="scope">
<span v-if="scope.row.type != 'FOLDER'">{{ scope.row.size + 'MB' }}</span>
</template>
</el-table-column>
<el-table-column prop="path" label="路径"></el-table-column>
<el-table-column prop="formattedTime" width="170" label="修改日期"></el-table-column>
<el-table-column fixed="right" label="操作" width="60" align="center">
<template #default="scope">
<span style="display: flex;justify-content:center;">
<img @click="tableBeifen(scope.row)" style="cursor: pointer;" title="备份"
src="@/assets/images/beifen.png" alt="">
</span>
</template>
</el-table-column>
</el-table>
</div> </div>
<div class="newContent" v-if="tabs == 2"> <el-table v-loading="loading1" :data="localOnlyFiles" @selection-change="bifenChange"
<div class="newContent_title"> :header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
<div> style="width: 100%; height: calc(60vh);margin-bottom: 20px;" border>
<el-button type="primary" :disabled="changeclick.length == 0" <el-table-column type="selection" width="40" />
@click="bfclick('bei')">备份</el-button>
<el-button type="primary" :disabled="changeclick.length == 0"
@click="bfclick('hui')">恢复</el-button>
</div>
</div>
<el-table v-loading="loading" :data="md5MismatchedFiles"
@selection-change="handleChange"
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
style="width: 100%; height: calc(60vh);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<!-- <el-table-column type="index" label="序号" width="70" align="center"></el-table-column> -->
<el-table-column prop="name" label="文件名称"></el-table-column>
<el-table-column prop="type" label="文件类型" width="90">
<template #default="scope">
<span v-if="scope.row.type == 'FOLDER'">文件夹</span>
<span v-else>文件</span>
</template>
</el-table-column>
<el-table-column prop="size" label="文件大小" width="100">
<template #default="scope">
{{ scope.row.size + 'MB' }}
</template>
</el-table-column>
<el-table-column prop="path" label="路径"></el-table-column>
<el-table-column prop="formattedTime" width="170" label="修改日期"></el-table-column>
<el-table-column label="操作" width="80" align="center">
<template #default="scope">
<span style="display: flex;justify-content:space-around;">
<img @click="tableBeifen(scope.row)" style="cursor: pointer;" title="备份"
src="@/assets/images/beifen.png" alt="">
<img @click="tablerestore(scope.row)" style="cursor: pointer;"
title="恢复" src="@/assets/images/huifu.png" alt="">
</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="newContent" v-if="tabs == 3">
<div class="newContent_title">
<div>
<el-button type="primary" :disabled="restoreArr.length == 0"
@click="moretablerestore()">恢复</el-button>
<el-button type="primary" :disabled="restoreArr.length == 0"
@click="delhuifu()">删除</el-button>
</div>
<el-table-column prop="fileName" label="文件名称"></el-table-column>
<el-table-column prop="isFile" label="文件类型" width="90">
<template #default="scope">
<span v-if="scope.row.isFile == 'FOLDER'">文件夹</span>
<span v-else>文件</span>
</template>
</el-table-column>
<el-table-column prop="fileSize" label="文件大小" width="100">
<template #default="scope">
<span v-if="scope.row.isFile != 'FOLDER'">{{ scope.row.fileSize + 'MB' }}</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column prop="workPath" label="路径"></el-table-column>
<el-table-column prop="uploadTime" width="170" label="修改日期"></el-table-column>
<el-table-column label="操作" width="60" align="center">
<template #default="scope">
<span style="display: flex;justify-content:center;">
<img @click="tableBeifen(scope.row)" style="cursor: pointer;" title="备份"
src="@/assets/images/beifen.png" alt="">
</span>
</template>
</el-table-column>
</el-table>
<Page :total="sureTotal" v-model:size="sureSize" v-model:current="sureCurrent"
@pagination="diffSure()">
</Page>
</div>
<div class="newContent" v-if="tabs == 2">
<div class="newContent_title">
<div>
<el-button type="primary" :disabled="changeclick.length == 0"
@click="bfclick('bei')">备份</el-button>
<el-button type="primary" :disabled="changeclick.length == 0"
@click="bfclick('hui')">恢复</el-button>
</div> </div>
<el-table v-loading="loading" :data="minioOnlyFiles" @selection-change="restoreChange"
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
style="width: 100%; height: calc(60vh);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<!-- <el-table-column type="index" label="序号" width="70" align="center"></el-table-column> -->
<el-table-column prop="name" label="文件名称"></el-table-column>
<el-table-column prop="type" label="文件类型" width="90">
<template #default="scope">
<span v-if="scope.row.type == 'FOLDER'">文件夹</span>
<span v-else>文件</span>
</template>
</el-table-column>
<el-table-column prop="size" label="文件大小" width="100">
<template #default="scope">
{{ scope.row.size + 'MB' }}
</template>
</el-table-column>
<el-table-column prop="path" label="路径"></el-table-column>
<el-table-column prop="formattedTime" width="170" label="修改日期"></el-table-column>
<el-table-column fixed="right" label="操作" width="60" align="center">
<template #default="scope">
<span style="display: flex;justify-content:center;">
<img @click="tablerestore(scope.row)" style="cursor: pointer;"
title="恢复" src="@/assets/images/huifu.png" alt="">
</span>
</template>
</el-table-column>
</el-table>
</div> </div>
<el-table v-loading="loading2" :data="md5MismatchedFiles" @selection-change="handleChange"
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
style="width: 100%; height: calc(60vh);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<el-table-column prop="fileName" label="文件名称"></el-table-column>
<el-table-column prop="isFile" label="文件类型" width="90">
<template #default="scope">
<span v-if="scope.row.isFile == 'FOLDER'">文件夹</span>
<span v-else>文件</span>
</template>
</el-table-column>
<el-table-column prop="fileSize" label="文件大小" width="100">
<template #default="scope">
<span v-if="scope.row.isFile != 'FOLDER'">{{ scope.row.fileSize + 'MB' }}</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column prop="workPath" label="路径"></el-table-column>
<el-table-column prop="uploadTime" width="170" label="修改日期"></el-table-column>
<el-table-column label="操作" width="80" align="center">
<template #default="scope">
<span style="display: flex;justify-content:space-around;">
<img @click="tableBeifen(scope.row)" style="cursor: pointer;" title="备份"
src="@/assets/images/beifen.png" alt="">
<img @click="tablerestore(scope.row)" style="cursor: pointer;" title="恢复"
src="@/assets/images/huifu.png" alt="">
</span>
</template>
</el-table-column>
</el-table>
<Page :total="ChangeTotal" v-model:size="ChangeSize" v-model:current="ChangeCurrent"
@pagination="diffChange()">
</Page>
</div>
<div class="newContent" v-if="tabs == 3">
<div class="newContent_title">
<div>
<el-button type="primary" :disabled="restoreArr.length == 0"
@click="moretablerestore()">恢复</el-button>
<el-button type="primary" :disabled="restoreArr.length == 0"
@click="delhuifu()">删除</el-button>
</div>
</div>
<el-table v-loading="loading3" :data="minioOnlyFiles" @selection-change="restoreChange"
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
style="width: 100%; height: calc(60vh);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<el-table-column prop="fileName" label="文件名称"></el-table-column>
<el-table-column prop="isFile" label="文件类型" width="90">
<template #default="scope">
<span v-if="scope.row.isFile == 'FOLDER'">文件夹</span>
<span v-else>文件</span>
</template>
</el-table-column>
<el-table-column prop="fileSize" label="文件大小" width="100">
<template #default="scope">
<span v-if="scope.row.isFile != 'FOLDER'">{{ scope.row.fileSize + 'MB' }}</span>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column prop="workPath" label="路径"></el-table-column>
<el-table-column prop="uploadTime" width="170" label="修改日期"></el-table-column>
<el-table-column label="操作" width="60" align="center">
<template #default="scope">
<span style="display: flex;justify-content:center;">
<img @click="tablerestore(scope.row)" style="cursor: pointer;" title="恢复"
src="@/assets/images/huifu.png" alt="">
</span>
</template>
</el-table-column>
</el-table>
<Page :total="MissTotal" v-model:size="MisseSize" v-model:current="MissCurrent"
@pagination="diffMiss()">
</Page>
</div>
<!-- </el-scrollbar> --> <!-- </el-scrollbar> -->
</div> </div>
@ -1210,27 +1374,31 @@ const tabs = ref(1)
} }
} }
//tab //tab
.tabbs_all{ .tabbs_all {
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
margin-bottom: 5px; margin-bottom: 5px;
.tabbs_box{
.tabbs_box {
padding: 3px 5px 6px 5px; padding: 3px 5px 6px 5px;
cursor: pointer; cursor: pointer;
// color: #; // color: #;
box-sizing: border-box; box-sizing: border-box;
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
} }
.tabbs_box:hover{
.tabbs_box:hover {
color: #409eff; color: #409eff;
cursor: pointer; cursor: pointer;
} }
.tabbs_box1{
.tabbs_box1 {
padding: 3px 5px; padding: 3px 5px;
cursor: pointer; cursor: pointer;
color: #409eff; color: #409eff;