feat:外部打开Terminal (80%)
This commit is contained in:
@@ -1,35 +1,99 @@
|
||||
<template>
|
||||
<div class="fileDirectory" style="width: 100% !important;">
|
||||
<div class="fileDirectory">
|
||||
<div class="file-directory-header">
|
||||
<span style="color: #fff">
|
||||
{{$t('terminal.sftp')}}
|
||||
<span style="color: #B7B7B7;margin-left: 10px">
|
||||
<span @click="getSftpPath('/')" class="breadcrumb-item breadcrumb-action"><i class="nz-icon nz-icon-Computer"/></span>
|
||||
<span v-for="(item,index) in breadcrumb" :key="index" class="breadcrumb-item">
|
||||
/<span class="breadcrumb-action" @click="gotoPath(item,index)">{{item}}</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
<span style="color: #fff" class="header-option">
|
||||
<i class="nz-icon nz-icon-a-newfolder" @click="newFolderBoxShow = true"></i>
|
||||
<span class="header-option">
|
||||
<i class="nz-icon nz-icon-upload" @click="uploadFile"></i>
|
||||
<i class="nz-icon nz-icon-close" @click="$emit('close')"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="file-directory-content" v-my-loading="fileDirectoryLoading">
|
||||
<div v-if="fileDirectory !== '/'" @click="backFileDirectory" class="file-item"><i class="nz-icon nz-icon-a-upperlevel" style="margin-right: 10px"/>{{$t('terminal.back')}}</div>
|
||||
<div v-for="(item,index) in fileList" :key="index" class="file-item" @click="selectFile(item)">
|
||||
<div class="file-directory-path" v-clickoutside="hideEditPath">
|
||||
<span v-show="!editPathShow" class="breadcrumb-box">
|
||||
<span @click="getSftpPath('/')" class="breadcrumb-item breadcrumb-action"><i class="nz-icon nz-icon-home"/></span>
|
||||
<span v-for="(item,index) in breadcrumb" :key="index" class="breadcrumb-item">
|
||||
/<span class="breadcrumb-action" @click="gotoPath(item,index)">{{item}}</span>
|
||||
</span>
|
||||
<i class="nz-icon nz-icon-edit" @click="showEditPath"/>
|
||||
</span>
|
||||
<span v-show="editPathShow">
|
||||
<el-input v-model="editPath" size="small" @keyup.enter.native="goEditPath"/>
|
||||
</span>
|
||||
<div class="path-option">
|
||||
<span style="margin-right: 5px">Show hide File: </span>
|
||||
<el-switch v-model="showHideFile"/>
|
||||
<i class="nz-icon nz-icon-a-newfolder" @click="newFolderBoxShow = true"></i>
|
||||
<i class="nz-icon nz-icon-upload" @click="uploadFile"></i>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style="padding: 0 20px;height: calc(100% - 50px)" v-my-loading="fileDirectoryLoading">
|
||||
<div class="directory-content-header">
|
||||
<div class="text-ellipsis file-name">
|
||||
<i class="nz-icon" :class="selIcon(item)"/>
|
||||
{{item.name}}
|
||||
{{$t('overall.name')}}
|
||||
</div>
|
||||
<div class="file-feature" v-if="!item.isDir">
|
||||
<i class="nz-icon nz-icon-download1" v-if="!item.isDir" @click="downloadFile(item)"></i>
|
||||
<i class="nz-icon nz-icon-delete" v-if="!item.isDir" @click="delFile(item)"></i>
|
||||
<div class="text-ellipsis file-size">
|
||||
{{$t('backup.size')}}
|
||||
</div>
|
||||
<div class="file-date">
|
||||
<span>{{momentTz(item.cts * 1000)}}</span>
|
||||
<span v-if="!item.isDir">{{bytes(item.size, 0, 0)}}</span>
|
||||
<div class="text-ellipsis file-date">
|
||||
{{$t('issue.createTime')}}
|
||||
</div>
|
||||
<div class="text-ellipsis file-opt">
|
||||
{{$t('overall.option')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="file-directory-content">
|
||||
<div v-if="fileDirectory !== '/'" @click="backFileDirectory" class="file-item">
|
||||
<div class="text-ellipsis file-name">
|
||||
<i class="nz-icon nz-icon-a-upperlevel" style="margin-right: 10px"/>
|
||||
{{$t('terminal.back')}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(item,index) in fileList" :key="index" class="file-item" @click="selectFile(item)">
|
||||
<div class="text-ellipsis file-name">
|
||||
<i class="nz-icon" :class="selIcon(item)"/>
|
||||
{{item.name}}
|
||||
</div>
|
||||
<div class="text-ellipsis file-size">
|
||||
<span v-if="!item.isDir">{{bytes(item.size, 0, 0)}}</span>
|
||||
</div>
|
||||
<div class="text-ellipsis file-date">
|
||||
<span>{{momentTz(item.cts * 1000)}}</span>
|
||||
</div>
|
||||
<div class="text-ellipsis file-opt">
|
||||
<i class="nz-icon nz-icon-shuxing" @click.stop="showFileInfo(item)"/>
|
||||
<el-dropdown size="medium" trigger="click" @command="tableOperation">
|
||||
<div class="table-operation-item table-operation-item--more" @click.stop="" :title="$t('overall.moreOperations')">
|
||||
<i class="nz-icon nz-icon-more3"></i>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown" class="right-box-select-top right-public-box-dropdown-top">
|
||||
<el-dropdown-item
|
||||
:command="['rename', item]">
|
||||
<i class="nz-icon nz-icon-edit"></i>
|
||||
<span class="operation-dropdown-text">
|
||||
{{$t('terminal.rename')}}
|
||||
</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:disabled="item.isDir"
|
||||
:command="['download', item]">
|
||||
<i class="nz-icon nz-icon-download1"></i>
|
||||
<span class="operation-dropdown-text">
|
||||
{{$t('overall.download')}}
|
||||
</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:disabled="item.isDir"
|
||||
:command="['del', item]">
|
||||
<i class="nz-icon nz-icon-delete"></i>
|
||||
<span class="operation-dropdown-text">
|
||||
{{$t('overall.delete')}}
|
||||
</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<!-- <i class="nz-icon nz-icon-download1" v-if="!item.isDir" @click="downloadFile(item)"></i>-->
|
||||
<!-- <i class="nz-icon nz-icon-delete" v-if="!item.isDir" @click="delFile(item)"></i>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,7 +107,7 @@
|
||||
@close="newFolder(false)"
|
||||
>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 100px;flex-shrink: 1">{{$t('overall.folderName')}}</div>
|
||||
<div style="width: 100px;flex-shrink: 1;text-transform: capitalize">{{$t('overall.folderName')}}</div>
|
||||
<el-input v-model="folder" size="small" style="flex: 1"/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
@@ -57,6 +121,87 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("terminal.rename")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="renameBox"
|
||||
@close="renameBox = false"
|
||||
>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 100px;flex-shrink: 1;text-transform: capitalize">{{$t('overall.name')}}</div>
|
||||
<el-input v-model="renameStr" size="small" style="flex: 1"/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button el-button--small el-button--default" @click="renameBox = false">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="setRename">
|
||||
<span style="text-transform:Capitalize">{{$t('overall.save')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("overall.delete")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="delDialog"
|
||||
@close="delDialog = false"
|
||||
>
|
||||
<div style="display: flex; align-items: center" v-if="delObj">
|
||||
{{$t('terminal.delinfo',{fileName: delObj.name})}}
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button el-button--small el-button--default" @click="delDialog = false" >
|
||||
<span>{{$t('tip.no')}}</span>
|
||||
</button>
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="delFile">
|
||||
<span style="text-transform:Capitalize">{{$t('tip.yes')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- fileInfo-->
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("overall.labels")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="fileInfoShow"
|
||||
@close="fileInfoShow = false"
|
||||
>
|
||||
<div v-if="fileInfo">
|
||||
<div class="file-info-item-header">
|
||||
<i class="nz-icon" :class="selIcon(fileInfo)"/>
|
||||
{{fileInfo.name}}
|
||||
</div>
|
||||
<div v-for="item in fileAttr" :key="item.name" class="file-info-item">
|
||||
<div class="file-info-item-left" :class="{'is-disabled': fileInfo.isDir && item.key =='size'}">
|
||||
{{$t(item.name)}} :
|
||||
</div>
|
||||
<div class="file-info-item-right">
|
||||
{{selInfo(fileInfo, item.key)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="fileInfoShow = false">
|
||||
<span style="text-transform:Capitalize">{{$t('overall.close')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -66,7 +211,8 @@ export default {
|
||||
name: 'fileDirectory',
|
||||
props: {
|
||||
uuid: {},
|
||||
fileDirectoryShow: {}
|
||||
fileDirectoryShow: {},
|
||||
host: {}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -76,7 +222,27 @@ export default {
|
||||
newFolderBoxShow: false,
|
||||
folder: '',
|
||||
fileDirectoryLoading: false,
|
||||
timer: ''
|
||||
timer: '',
|
||||
editPathShow: false,
|
||||
editPath: '',
|
||||
showHideFile: false,
|
||||
delObj: '',
|
||||
delDialog: false,
|
||||
renameBox: false,
|
||||
renameStr: '',
|
||||
fileInfo: '',
|
||||
fileInfoShow: false,
|
||||
fileAttr: [
|
||||
{ name: 'overall.type', key: 'isDir' },
|
||||
{ name: 'config.operationlog.ip', key: 'ip' },
|
||||
{ name: 'asset.location', key: 'location' },
|
||||
{ name: 'backup.size', key: 'size' },
|
||||
{ name: 'terminal.modifyTime', key: 'uts' },
|
||||
{ name: 'Owner', key: 'Owner' },
|
||||
{ name: 'dashboard.panel.chartForm.group', key: 'group' },
|
||||
{ name: 'config.menus.perms', key: 'permissionsString' }
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -113,12 +279,33 @@ export default {
|
||||
init () {
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
},
|
||||
showEditPath () {
|
||||
this.editPath = this.fileDirectory
|
||||
this.editPathShow = true
|
||||
},
|
||||
hideEditPath () {
|
||||
this.editPath = ''
|
||||
this.editPathShow = false
|
||||
},
|
||||
goEditPath () {
|
||||
console.log('123123123')
|
||||
this.getSftpPath(this.editPath)
|
||||
setTimeout(() => {
|
||||
this.editPath = ''
|
||||
this.editPathShow = false
|
||||
})
|
||||
},
|
||||
selectFile (item) {
|
||||
if (item.isDir) {
|
||||
const path = this.fileDirectory == '/' ? '' : this.fileDirectory
|
||||
this.getSftpPath(path + '/' + item.name)
|
||||
}
|
||||
},
|
||||
showFileInfo (item) {
|
||||
console.log(item)
|
||||
this.fileInfo = item
|
||||
this.fileInfoShow = true
|
||||
},
|
||||
newFolder (flag) {
|
||||
if (!flag) {
|
||||
this.newFolderBoxShow = false
|
||||
@@ -146,16 +333,23 @@ export default {
|
||||
this.getSftpPath(path || '/')
|
||||
},
|
||||
getSftpPath (path) {
|
||||
this.breadcrumb = path.split('/').filter(item => item)
|
||||
const params = {
|
||||
uuid: this.uuid,
|
||||
path: path
|
||||
path: path,
|
||||
showHideFile: this.showHideFile
|
||||
}
|
||||
this.fileDirectoryLoading = true
|
||||
this.$post('/terminal/sftp/ls', params).then(res => {
|
||||
this.fileDirectoryLoading = false
|
||||
this.fileDirectory = res.data.path
|
||||
this.fileList = res.data.list
|
||||
if (res.code === 200) {
|
||||
this.fileDirectoryLoading = false
|
||||
this.fileDirectory = res.data.path
|
||||
this.fileList = res.data.list
|
||||
this.editPath = ''
|
||||
this.breadcrumb = res.data.path.split('/').filter(item => item)
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
this.editPath = ''
|
||||
}
|
||||
})
|
||||
},
|
||||
uploadFile () {
|
||||
@@ -166,6 +360,7 @@ export default {
|
||||
type: 'upload',
|
||||
isStart: false,
|
||||
isFinish: false,
|
||||
isError: false,
|
||||
importFileList: [],
|
||||
total: '',
|
||||
speed: '',
|
||||
@@ -174,7 +369,8 @@ export default {
|
||||
cancel: '',
|
||||
axios: '',
|
||||
timer: '',
|
||||
done: 0
|
||||
done: 0,
|
||||
delObj: ''
|
||||
}
|
||||
this.$store.dispatch('uploadFile', params)
|
||||
},
|
||||
@@ -192,6 +388,7 @@ export default {
|
||||
type: 'download',
|
||||
isStart: false,
|
||||
isFinish: false,
|
||||
isError: false,
|
||||
total: '',
|
||||
speed: '',
|
||||
fileLength: '',
|
||||
@@ -202,7 +399,11 @@ export default {
|
||||
this.$store.dispatch('dispatchAddFileList', params)
|
||||
}, 300)
|
||||
},
|
||||
delFile (item) {
|
||||
setRename () {
|
||||
this.renameBox = false
|
||||
},
|
||||
delFile () {
|
||||
const item = this.delObj
|
||||
const path = this.fileDirectory == '/' ? '' : this.fileDirectory
|
||||
const params = {
|
||||
uuid: this.uuid,
|
||||
@@ -210,8 +411,10 @@ export default {
|
||||
}
|
||||
this.$post('/terminal/sftp/rm', params).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.delDialog = false
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
} else {
|
||||
this.delDialog = false
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
@@ -227,6 +430,66 @@ export default {
|
||||
return 'nz-icon-File'
|
||||
}
|
||||
return 'nz-icon-File'
|
||||
},
|
||||
selInfo (item, key) {
|
||||
if (key === 'isDir') {
|
||||
if (item.isDir) {
|
||||
return this.$t('terminal.catalogueFile')
|
||||
} else {
|
||||
return this.$t('backup.File')
|
||||
}
|
||||
}
|
||||
if (key === 'ip') {
|
||||
return this.host
|
||||
}
|
||||
// fileAttr: [
|
||||
// { name: 'overall.type', key: 'isDir' },
|
||||
// { name: 'config.operationlog.ip', key: 'ip' },
|
||||
// { name: 'asset.location', key: 'location' },
|
||||
// { name: 'backup.size', key: 'size' },
|
||||
// { name: 'terminal.modifyTime', key: 'uts' },
|
||||
// { name: 'Owner', key: 'Owner' },
|
||||
// { name: 'dashboard.panel.chartForm.group', key: 'group' },
|
||||
// { name: 'config.menus.perms', key: 'permissionsString' }
|
||||
//
|
||||
// ]
|
||||
if (key === 'location') {
|
||||
return this.fileDirectory
|
||||
}
|
||||
if (key === 'size' && !item.isDir) {
|
||||
return this.bytes(item.size, 0, 0)
|
||||
} else if (key === 'size' && item.isDir) {
|
||||
return ''
|
||||
}
|
||||
if (key === 'uts') {
|
||||
return this.momentTz(item.uts * 1000)
|
||||
}
|
||||
if (key === 'Owner') {
|
||||
return 'Owner'
|
||||
}
|
||||
if (key === 'group') {
|
||||
return 'group'
|
||||
}
|
||||
if (key === 'permissionsString') {
|
||||
return item.permissionsString
|
||||
}
|
||||
return '-'
|
||||
},
|
||||
tableOperation ([command, row, param]) {
|
||||
switch (command) {
|
||||
case 'rename':
|
||||
this.renameStr = row.name
|
||||
this.renameBox = true
|
||||
break
|
||||
case 'download':
|
||||
this.downloadFile(row)
|
||||
break
|
||||
case 'del':
|
||||
this.delObj = row
|
||||
this.delDialog = true
|
||||
// this.delFile(row)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user