mirror of
https://github.com/jumpserver/lina.git
synced 2025-08-25 09:58:53 +00:00
perf: 使用slot处理文件列表 (#3599)
* perf: 使用slot处理文件列表 * perf: 大小文件超出限制不上传 --------- Co-authored-by: wangruidong <940853815@qq.com>
This commit is contained in:
parent
2ac9183047
commit
d51a787598
@ -5,35 +5,35 @@
|
|||||||
<div class="transition-box" style="width: calc(100% - 17px);">
|
<div class="transition-box" style="width: calc(100% - 17px);">
|
||||||
<div class="upload_input">
|
<div class="upload_input">
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="run_button.disabled"
|
:disabled="runButton.disabled"
|
||||||
:type="run_button.el&&run_button.el.type"
|
:type="runButton.el&&runButton.el.type"
|
||||||
size="mini"
|
size="mini"
|
||||||
style="display: inline-block; margin: 0 2px"
|
style="display: inline-block; margin: 0 2px"
|
||||||
@click="run_button.callback()"
|
@click="runButton.callback()"
|
||||||
>
|
>
|
||||||
<i :class="run_button.icon" style="margin-right: 4px;" />{{ run_button.name }}
|
<i :class="runButton.icon" style="margin-right: 4px;" />{{ runButton.name }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="upload_input">{{ $t('users.Users') }}:</div>
|
<div class="upload_input">{{ $t('users.Users') }}:</div>
|
||||||
<div class="upload_input">
|
<div class="upload_input">
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
v-model="runas_input.value"
|
v-model="runAsInput.value"
|
||||||
:fetch-suggestions="runas_input.el.query"
|
:fetch-suggestions="runAsInput.el.query"
|
||||||
:placeholder="runas_input.placeholder"
|
:placeholder="runAsInput.placeholder"
|
||||||
size="mini"
|
size="mini"
|
||||||
style="display: inline-block; margin: 0 2px"
|
style="display: inline-block; margin: 0 2px"
|
||||||
@change="runas_input.callback(runas_input.value)"
|
@change="runAsInput.callback(runAsInput.value)"
|
||||||
@select="runas_input.callback(runas_input.value)"
|
@select="runAsInput.callback(runAsInput.value)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="upload_input">{{ $t('ops.UploadDir') }}:</div>
|
<div class="upload_input">{{ $t('ops.UploadDir') }}:</div>
|
||||||
<div class="upload_input">
|
<div class="upload_input">
|
||||||
<el-input
|
<el-input
|
||||||
v-if="dst_path_input.type==='input'"
|
v-if="dstPathInput.type==='input'"
|
||||||
v-model="dst_path"
|
v-model="dstPath"
|
||||||
:placeholder="dst_path_input.placeholder"
|
:placeholder="dstPathInput.placeholder"
|
||||||
size="mini"
|
size="mini"
|
||||||
@change="dst_path_input.callback(dst_path_input.value)"
|
@change="dstPathInput.callback(dstPathInput.value)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -45,8 +45,7 @@
|
|||||||
ref="upload"
|
ref="upload"
|
||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
:on-change="onFileChange"
|
:on-change="onFileChange"
|
||||||
:on-remove="onFileChange"
|
:value.sync="uploadFileList"
|
||||||
:value.sync="files"
|
|
||||||
action=""
|
action=""
|
||||||
drag
|
drag
|
||||||
multiple
|
multiple
|
||||||
@ -59,8 +58,25 @@
|
|||||||
<span>
|
<span>
|
||||||
{{ $t('ops.uploadFileLthHelpText') }}
|
{{ $t('ops.uploadFileLthHelpText') }}
|
||||||
</span>
|
</span>
|
||||||
|
<div slot="file" slot-scope="{file}">
|
||||||
|
<li tabindex="0" class="el-upload-list__item is-ready">
|
||||||
|
<a class="el-upload-list__item-name" :style="sameFileStyle(file)">
|
||||||
|
<i class="el-icon-document" />{{ file.name }}
|
||||||
|
<i style="color: #1ab394;float: right;font-weight:normal">
|
||||||
|
{{ formatFileSize(file.size) }}
|
||||||
|
<i class="el-icon-close" @click="removeFile(file)" />
|
||||||
|
</i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-progress v-if="ShowProgress" :percentage="progressLength" />
|
<el-progress v-if="ShowProgress" :percentage="progressLength" />
|
||||||
|
<div
|
||||||
|
v-if="uploadFileList.length===0"
|
||||||
|
class="empty-file-tip"
|
||||||
|
>
|
||||||
|
{{ $tc('ops.NoFiles') }}
|
||||||
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
<b>{{ $tc('ops.output') }}:</b>
|
<b>{{ $tc('ops.output') }}:</b>
|
||||||
@ -119,12 +135,11 @@ export default {
|
|||||||
timeCost: 0,
|
timeCost: 0,
|
||||||
cancel: 0
|
cancel: 0
|
||||||
},
|
},
|
||||||
xtermConfig: {
|
xtermConfig: {},
|
||||||
},
|
|
||||||
DataZTree: 0,
|
DataZTree: 0,
|
||||||
runas: '',
|
runas: '',
|
||||||
dst_path: '',
|
dstPath: '',
|
||||||
run_button: {
|
runButton: {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
name: this.$t('ops.Transfer'),
|
name: this.$t('ops.Transfer'),
|
||||||
align: 'left',
|
align: 'left',
|
||||||
@ -137,7 +152,7 @@ export default {
|
|||||||
this.execute()
|
this.execute()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
runas_input: {
|
runAsInput: {
|
||||||
name: this.$t('ops.runAs'),
|
name: this.$t('ops.runAs'),
|
||||||
align: 'left',
|
align: 'left',
|
||||||
value: '',
|
value: '',
|
||||||
@ -163,7 +178,7 @@ export default {
|
|||||||
this.runas = option
|
this.runas = option
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dst_path_input: {
|
dstPathInput: {
|
||||||
type: 'input',
|
type: 'input',
|
||||||
name: this.$t('ops.runningPath'),
|
name: this.$t('ops.runningPath'),
|
||||||
align: 'left',
|
align: 'left',
|
||||||
@ -173,8 +188,6 @@ export default {
|
|||||||
this.chdir = val
|
this.chdir = val
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
files: null,
|
|
||||||
src_paths: [],
|
|
||||||
treeSetting: {
|
treeSetting: {
|
||||||
treeUrl: '/api/v1/perms/users/self/nodes/children-with-assets/tree/',
|
treeUrl: '/api/v1/perms/users/self/nodes/children-with-assets/tree/',
|
||||||
searchUrl: '/api/v1/perms/users/self/assets/tree/',
|
searchUrl: '/api/v1/perms/users/self/assets/tree/',
|
||||||
@ -192,7 +205,8 @@ export default {
|
|||||||
iShowTree: true,
|
iShowTree: true,
|
||||||
progressLength: 0,
|
progressLength: 0,
|
||||||
ShowProgress: false,
|
ShowProgress: false,
|
||||||
upload_interval: null
|
upload_interval: null,
|
||||||
|
uploadFileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -206,9 +220,9 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.enableWS()
|
this.enableWS()
|
||||||
this.initData()
|
this.initData()
|
||||||
this.handleFileList(null, [])
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formatFileSize,
|
||||||
async initData() {
|
async initData() {
|
||||||
this.recoverStatus()
|
this.recoverStatus()
|
||||||
},
|
},
|
||||||
@ -217,8 +231,8 @@ export default {
|
|||||||
this.currentTaskId = this.$route.query.taskId
|
this.currentTaskId = this.$route.query.taskId
|
||||||
getTaskDetail(this.currentTaskId).then(data => {
|
getTaskDetail(this.currentTaskId).then(data => {
|
||||||
getJob(data.job_id).then(res => {
|
getJob(data.job_id).then(res => {
|
||||||
this.runas_input.value = res.runas
|
this.runAsInput.value = res.runas
|
||||||
this.runas_input.callback(res.runas)
|
this.runAsInput.callback(res.runas)
|
||||||
this.executionInfo.status = data['status']
|
this.executionInfo.status = data['status']
|
||||||
this.executionInfo.timeCost = data['time_cost']
|
this.executionInfo.timeCost = data['time_cost']
|
||||||
this.setCostTimeInterval()
|
this.setCostTimeInterval()
|
||||||
@ -283,8 +297,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setCostTimeInterval() {
|
setCostTimeInterval() {
|
||||||
this.run_button.icon = 'fa fa-spinner fa-spin'
|
this.runButton.icon = 'fa fa-spinner fa-spin'
|
||||||
this.run_button.disabled = true
|
this.runButton.disabled = true
|
||||||
this.executionInfo.cancel = setInterval(() => {
|
this.executionInfo.cancel = setInterval(() => {
|
||||||
this.executionInfo.timeCost += 0.1
|
this.executionInfo.timeCost += 0.1
|
||||||
}, 100)
|
}, 100)
|
||||||
@ -315,49 +329,40 @@ export default {
|
|||||||
handleFileList(file, fileList) {
|
handleFileList(file, fileList) {
|
||||||
const filenameList = fileList.map((file) => file.name)
|
const filenameList = fileList.map((file) => file.name)
|
||||||
const filenameCount = _.countBy(filenameList)
|
const filenameCount = _.countBy(filenameList)
|
||||||
this.$nextTick(() => {
|
if (filenameCount[file.name] > 1) {
|
||||||
const emptyFileTip = document.getElementsByClassName('empty-file-tip')
|
this.$message.error(this.$tc('ops.DuplicateFileExists'))
|
||||||
if (emptyFileTip.length > 0) {
|
file.is_same = true
|
||||||
emptyFileTip[0].style = 'display:none'
|
}
|
||||||
}
|
},
|
||||||
const fileElementList = document.getElementsByClassName('el-upload-list__item-name')
|
sameFileStyle(file) {
|
||||||
if (fileElementList && fileElementList.length > 0) {
|
if (file.is_same) {
|
||||||
for (const ele of fileElementList) {
|
return { backgroundColor: 'var(--color-danger)' }
|
||||||
// 显示文件大小
|
}
|
||||||
if (file.name === ele.outerText) {
|
return ''
|
||||||
ele.insertAdjacentHTML('beforeend',
|
},
|
||||||
`<i style="color: #1ab394;float: right;font-weight:normal">${formatFileSize(file.size)}</i>`)
|
IsFileExceedsLimit(file) {
|
||||||
}
|
const isGt200M = file.size / 1024 / 1024 > 200
|
||||||
// 文件大小超出限制
|
if (isGt200M) {
|
||||||
if (file.size > 200 * 1024 * 1024) {
|
this.$message.error(this.$tc('ops.FileSizeExceedsLimit'))
|
||||||
this.$message.error(this.$tc('ops.FileSizeExceedsLimit'))
|
}
|
||||||
ele.style = 'background-color:var(--color-danger)'
|
return isGt200M
|
||||||
}
|
|
||||||
// 同名文件提示
|
|
||||||
if (filenameCount[ele.outerText] > 1) {
|
|
||||||
this.$message.error(this.$tc('ops.DuplicateFileExists'))
|
|
||||||
ele.style = 'background-color:var(--color-danger)'
|
|
||||||
} else {
|
|
||||||
ele.style = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const emptyFileElementList = document.getElementsByClassName('el-upload-list--text')[0]
|
|
||||||
const text = this.$tc('ops.NoFiles')
|
|
||||||
emptyFileElementList.insertAdjacentHTML('afterbegin',
|
|
||||||
`<div class="empty-file-tip" style="color: #c5c9cc;font-size: 18px;display: flex;justify-content: center;align-items: center;height: 100%">
|
|
||||||
${text}</div>`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
onFileChange(file, fileList) {
|
onFileChange(file, fileList) {
|
||||||
file.name = this.truncateFileName(file.name)
|
file.name = this.truncateFileName(file.name)
|
||||||
this.files = fileList
|
this.uploadFileList = fileList
|
||||||
this.handleFileList(file, fileList)
|
this.handleFileList(file, fileList)
|
||||||
},
|
},
|
||||||
|
removeFile(file) {
|
||||||
|
this.uploadFileList.splice(this.uploadFileList.indexOf(file), 1)
|
||||||
|
},
|
||||||
execute() {
|
execute() {
|
||||||
const { hosts, nodes } = this.getSelectedNodesAndHosts()
|
const { hosts, nodes } = this.getSelectedNodesAndHosts()
|
||||||
if (!this.files) {
|
for (const file of this.uploadFileList) {
|
||||||
|
if (this.IsFileExceedsLimit(file)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.uploadFileList) {
|
||||||
this.$message.error(this.$tc('ops.RequiredUploadFile'))
|
this.$message.error(this.$tc('ops.RequiredUploadFile'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -373,7 +378,7 @@ export default {
|
|||||||
assets: hosts,
|
assets: hosts,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
module: 'shell',
|
module: 'shell',
|
||||||
args: JSON.stringify({ dst_path: this.dst_path }),
|
args: JSON.stringify({ dst_path: this.dstPath }),
|
||||||
type: 'upload_file',
|
type: 'upload_file',
|
||||||
runas: this.runas,
|
runas: this.runas,
|
||||||
runas_policy: 'skip',
|
runas_policy: 'skip',
|
||||||
@ -388,7 +393,7 @@ export default {
|
|||||||
this.progressLength = 0
|
this.progressLength = 0
|
||||||
this.ShowProgress = true
|
this.ShowProgress = true
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
for (const file of this.files) {
|
for (const file of this.uploadFileList) {
|
||||||
form.append('files', file.raw)
|
form.append('files', file.raw)
|
||||||
form.append('job_id', res.id)
|
form.append('job_id', res.id)
|
||||||
}
|
}
|
||||||
@ -415,9 +420,9 @@ export default {
|
|||||||
this.executionInfo.timeCost = 0
|
this.executionInfo.timeCost = 0
|
||||||
this.progressLength = 0
|
this.progressLength = 0
|
||||||
this.ShowProgress = false
|
this.ShowProgress = false
|
||||||
this.run_button.disabled = false
|
this.runButton.disabled = false
|
||||||
clearInterval(this.upload_interval)
|
clearInterval(this.upload_interval)
|
||||||
this.run_button.icon = 'fa fa-play'
|
this.runButton.icon = 'fa fa-play'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,7 +488,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
>>> .el-upload {
|
> > > .el-upload {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -493,6 +498,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty-file-tip {
|
||||||
|
position: relative;
|
||||||
|
bottom: 100px;
|
||||||
|
left: 58%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #c5c9cc;
|
||||||
|
}
|
||||||
|
|
||||||
> > > .el-upload-list {
|
> > > .el-upload-list {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
padding: 0 10px 0 10px;
|
padding: 0 10px 0 10px;
|
||||||
@ -509,7 +522,7 @@ export default {
|
|||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.output >>> #terminal {
|
.output > > > #terminal {
|
||||||
border: dashed 1px #d9d9d9;
|
border: dashed 1px #d9d9d9;
|
||||||
margin: 0 20px 20px;
|
margin: 0 20px 20px;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user