mirror of
https://gitee.com/lijiahangmax/orion-ops.git
synced 2026-09-24 15:30:00 +08:00
feat: import machine proxy logger.
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<a-modal v-model="visible"
|
||||
:title="importType.title"
|
||||
:okText="dataCheckPage ? '开始导入' : '导入'"
|
||||
:width="500"
|
||||
:okButtonProps="{props: {disabled: loading}}"
|
||||
:maskClosable="false"
|
||||
:destroyOnClose="true"
|
||||
@ok="clickImport"
|
||||
@cancel="close">
|
||||
<a-spin :spinning="loading">
|
||||
<!-- 导入页面 -->
|
||||
<div class="data-import-container" v-if="!dataCheckPage">
|
||||
<!-- 导入提示 -->
|
||||
<a-alert class="import-alert-message" :message="importType.tips" type="info"/>
|
||||
<!-- 上传框 -->
|
||||
<div class="file-select-container">
|
||||
<!-- 文件选择 -->
|
||||
<div class="file-select-wrapper">
|
||||
<a-upload accept=".xlsx"
|
||||
:beforeUpload="selectFile"
|
||||
:customRequest="() => {}"
|
||||
:showUploadList="false">
|
||||
<a-button type="link">选择文件</a-button>
|
||||
</a-upload>
|
||||
<!-- 已选择的文件 -->
|
||||
<span class="selected-file-name" v-if="uploadFile" :title="uploadFile.name">
|
||||
{{ uploadFile.name }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- 下载模板 -->
|
||||
<a-button type="link" @click="downloadTemplate">下载模板</a-button>
|
||||
</div>
|
||||
<!-- 参数 -->
|
||||
<div class="data-import-params">
|
||||
<!-- 文档密码 -->
|
||||
<div class="data-import-param">
|
||||
<span class="normal-label import-label">文档密码</span>
|
||||
<a-input class="param-input"
|
||||
v-model="protectPassword"
|
||||
:maxLength="10"
|
||||
placeholder="导入文档的密码"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 检查页面 -->
|
||||
<div class="data-check-container" v-else>
|
||||
<!-- 非法数据 -->
|
||||
<div class="check-data-container" v-if="checkData.illegalRows.length">
|
||||
<span class="normal-label check-label span-red">非法数据 (不会导入)</span>
|
||||
<div class="check-data-wrapper" v-for="row of checkData.illegalRows" :key="row.index">
|
||||
第 <span class="span-red">{{ row.row }}</span> 行, <span v-if="row.symbol" class="ml4 mr8">{{ row.symbol }}</span>
|
||||
<span class="span-red">{{ row.illegalMessage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 新增数据 -->
|
||||
<div class="check-data-container" v-if="checkData.insertRows.length">
|
||||
<span class="normal-label check-label span-blue">新增数据</span>
|
||||
<div class="check-data-wrapper" v-for="row of checkData.insertRows" :key="row.index">
|
||||
第 <span class="span-blue">{{ row.row }}</span> 行, <span class="ml4">{{ row.symbol }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 修改数据 -->
|
||||
<div class="check-data-container" v-if="checkData.updateRows.length">
|
||||
<span class="normal-label check-label span-blue">修改数据</span>
|
||||
<div class="check-data-wrapper" v-for="row of checkData.updateRows" :key="row.index">
|
||||
第 <span class="span-blue">{{ row.row }}</span> 行, <span class="ml4">{{ row.symbol }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DataImportModal',
|
||||
props: {
|
||||
importType: Object
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
visible: false,
|
||||
loading: false,
|
||||
dataCheckPage: false,
|
||||
protectPassword: undefined,
|
||||
uploadFile: null,
|
||||
checkData: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.dataCheckPage = false
|
||||
this.protectPassword = undefined
|
||||
this.uploadFile = null
|
||||
this.checkData = null
|
||||
this.loading = false
|
||||
this.visible = true
|
||||
},
|
||||
selectFile(e) {
|
||||
const suffix = e.name.substring(e.name.lastIndexOf('.') + 1)
|
||||
if (suffix !== 'xlsx') {
|
||||
this.$message.error('请选择 xlsx 表格进行导入')
|
||||
return false
|
||||
}
|
||||
this.uploadFile = e
|
||||
},
|
||||
clickImport() {
|
||||
if (this.dataCheckPage) {
|
||||
this.asyncImportData()
|
||||
} else {
|
||||
this.checkImportData()
|
||||
}
|
||||
},
|
||||
checkImportData() {
|
||||
if (!this.uploadFile) {
|
||||
this.$message.warning('请选择导入文件')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
const formData = new FormData()
|
||||
formData.append('file', this.uploadFile)
|
||||
formData.append('type', this.importType.value)
|
||||
formData.append('protectPassword', this.protectPassword)
|
||||
this.$api.checkImportData(formData).then(({ data }) => {
|
||||
this.loading = false
|
||||
this.dataCheckPage = true
|
||||
this.checkData = data
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
asyncImportData() {
|
||||
if (this.checkData.insertRows.length + this.checkData.updateRows.length === 0) {
|
||||
this.$message.warning('无可用导入数据, 无法导入')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
this.$api[this.importType.api]({
|
||||
importToken: this.checkData.importToken
|
||||
}).then(() => {
|
||||
this.loading = false
|
||||
this.visible = false
|
||||
this.$message.success('已开始导入')
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
downloadTemplate() {
|
||||
this.$api.getImportTemplate({
|
||||
type: this.importType.value
|
||||
}).then((e) => {
|
||||
this.$utils.downloadFile(e)
|
||||
}).catch(() => {
|
||||
this.$message.error('下载失败')
|
||||
})
|
||||
},
|
||||
close() {
|
||||
if (this.dataCheckPage) {
|
||||
this.$api.cancelImportData({
|
||||
importToken: this.checkData.importToken
|
||||
})
|
||||
}
|
||||
this.visible = false
|
||||
this.loading = false
|
||||
this.uploadFile = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.data-import-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.import-alert-message {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.file-select-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
|
||||
button {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.selected-file-name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
width: 294px;
|
||||
display: inline-flex;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.import-label {
|
||||
width: 64px;
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.data-import-param {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.param-input {
|
||||
margin-left: 8px;
|
||||
width: 236px;
|
||||
}
|
||||
|
||||
.data-check-container {
|
||||
margin: -12px 0;
|
||||
|
||||
.check-data-container {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.check-label {
|
||||
margin-bottom: 4px;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.check-data-wrapper {
|
||||
line-height: 1.6;
|
||||
font-size: 15px;
|
||||
padding-left: 16px;
|
||||
color: rgba(0, 0, 0, .85);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -173,8 +173,8 @@ export default {
|
||||
validateUsername(rule, value, callback) {
|
||||
if (!value) {
|
||||
callback(new Error('请输入用户名'))
|
||||
} else if (value.length > 32) {
|
||||
callback(new Error('用户名长度不能大于32位'))
|
||||
} else if (value.length > 128) {
|
||||
callback(new Error('用户名长度不能大于128位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ function getDecorators() {
|
||||
required: true,
|
||||
message: '请输入主机'
|
||||
}, {
|
||||
max: 32,
|
||||
message: '主机长度不能大于32位'
|
||||
max: 128,
|
||||
message: '主机长度不能大于128位'
|
||||
}]
|
||||
}],
|
||||
port: ['port', {
|
||||
|
||||
@@ -2194,14 +2194,14 @@ const $api = {
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出机器终端日志
|
||||
* 导出终端日志
|
||||
*/
|
||||
exportMachineTerminalLog: param => {
|
||||
return $http.$export('/data-export/machine-terminal-log', param)
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出机器日志文件
|
||||
* 导出日志文件
|
||||
*/
|
||||
exportMachineTailFile: param => {
|
||||
return $http.$export('/data-export/machine-tail-file', param)
|
||||
@@ -2273,12 +2273,26 @@ const $api = {
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入机器数据
|
||||
* 导入机器信息
|
||||
*/
|
||||
importMachineData: param => {
|
||||
return $http.$post('/data-import/import-machine', param)
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入机器代理
|
||||
*/
|
||||
importMachineProxy: param => {
|
||||
return $http.$post('/data-import/import-machine-proxy', param)
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入日志文件
|
||||
*/
|
||||
importTailFile: param => {
|
||||
return $http.$post('/data-import/import-tail-file', param)
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消导入数据
|
||||
*/
|
||||
|
||||
@@ -1586,11 +1586,11 @@ const $enum = {
|
||||
value: 8510,
|
||||
label: '机器代理'
|
||||
},
|
||||
DATA_EXPORT_MACHINE_TERMINAL_LOG: {
|
||||
DATA_EXPORT_TERMINAL_LOG: {
|
||||
value: 8515,
|
||||
label: '终端日志'
|
||||
},
|
||||
DATA_EXPORT_MACHINE_TAIL_FILE: {
|
||||
DATA_EXPORT_TAIL_FILE: {
|
||||
value: 8520,
|
||||
label: '日志文件'
|
||||
},
|
||||
@@ -2220,7 +2220,22 @@ const $enum = {
|
||||
*/
|
||||
IMPORT_TYPE: {
|
||||
MACHINE: {
|
||||
value: 10
|
||||
value: 100,
|
||||
tips: '使用唯一标识来区分数据, 存在更新不存在新增, 优先使用导入密码',
|
||||
title: '机器信息 导入',
|
||||
api: 'importMachineData'
|
||||
},
|
||||
MACHINE_PROXY: {
|
||||
value: 110,
|
||||
tips: '导入时优先使用导入密码',
|
||||
title: '机器代理 导入',
|
||||
api: 'importMachineProxy'
|
||||
},
|
||||
TAIL_FILE: {
|
||||
value: 130,
|
||||
tips: '通过机器标识来区分机器, 机器名称无需填写',
|
||||
title: '日志文件 导入',
|
||||
api: 'importTailFile'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -326,6 +326,28 @@ function clearStainKeywords(message) {
|
||||
.replaceAll('</sr>', '')
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*/
|
||||
function downloadFile(res) {
|
||||
const blob = new Blob([res.data])
|
||||
const tempLink = document.createElement('a')
|
||||
const blobURL = window.URL.createObjectURL(blob)
|
||||
tempLink.style.display = 'none'
|
||||
tempLink.href = blobURL
|
||||
const fileName = res.headers['content-disposition']
|
||||
? res.headers['content-disposition'].split(';')[1].split('=')[1]
|
||||
: new Date().getTime()
|
||||
tempLink.download = decodeURIComponent(fileName)
|
||||
if (typeof tempLink.download === 'undefined') {
|
||||
tempLink.target = '_blank'
|
||||
}
|
||||
document.body.appendChild(tempLink)
|
||||
tempLink.click()
|
||||
document.body.removeChild(tempLink)
|
||||
window.URL.revokeObjectURL(blobURL)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自适应终端大小
|
||||
*/
|
||||
@@ -404,5 +426,6 @@ export default {
|
||||
replaceStainKeywords,
|
||||
clearStainKeywords,
|
||||
fitDimensions,
|
||||
getUUID
|
||||
getUUID,
|
||||
downloadFile
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@
|
||||
<LoggerViewModal ref="logView"/>
|
||||
<!-- 导出模态框 -->
|
||||
<MachineTailFileExportModal ref="export"/>
|
||||
<!-- 导入模态框 -->
|
||||
<DataImportModal ref="import" :importType="$enum.IMPORT_TYPE.TAIL_FILE"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -137,6 +139,7 @@ import TextPreview from '@/components/preview/TextPreview'
|
||||
import LoggerViewModal from '@/components/log/LoggerViewModal'
|
||||
import _filters from '@/lib/filters'
|
||||
import MachineTailFileExportModal from '@/components/export/MachineTailFileExportModal'
|
||||
import DataImportModal from '@/components/import/DataImportModal'
|
||||
|
||||
/**
|
||||
* 列
|
||||
@@ -212,6 +215,7 @@ const columns = [
|
||||
export default {
|
||||
name: 'LoggerList',
|
||||
components: {
|
||||
DataImportModal,
|
||||
MachineTailFileExportModal,
|
||||
LoggerViewModal,
|
||||
MachineSelector,
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
<!-- 导出模态框 -->
|
||||
<MachineExportModal ref="export"/>
|
||||
<!-- 导入模态框 -->
|
||||
<MachineImportModal ref="import"/>
|
||||
<DataImportModal ref="import" :importType="$enum.IMPORT_TYPE.MACHINE"/>
|
||||
<!-- 终端模态框 -->
|
||||
<div v-if="openTerminalArr.length">
|
||||
<TerminalModal v-for="openTerminal of openTerminalArr"
|
||||
@@ -236,7 +236,7 @@ import MachineDetailModal from '@/components/machine/MachineDetailModal'
|
||||
import AddMachineModal from '@/components/machine/AddMachineModal'
|
||||
import TerminalModal from '@/components/terminal/TerminalModal'
|
||||
import MachineExportModal from '@/components/export/MachineExportModal'
|
||||
import MachineImportModal from '@/components/import/MachineImportModal'
|
||||
import DataImportModal from '@/components/import/DataImportModal'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -369,7 +369,7 @@ const moreMenuHandler = {
|
||||
export default {
|
||||
name: 'MachineList',
|
||||
components: {
|
||||
MachineImportModal,
|
||||
DataImportModal,
|
||||
MachineExportModal,
|
||||
TerminalModal,
|
||||
MachineDetailModal,
|
||||
|
||||
@@ -107,6 +107,8 @@
|
||||
<AddMachineProxyModal ref="addModal" @added="getList({})" @updated="getList({})"/>
|
||||
<!-- 导出模态框 -->
|
||||
<MachineProxyExportModal ref="export"/>
|
||||
<!-- 导入模态框 -->
|
||||
<DataImportModal ref="import" :importType="$enum.IMPORT_TYPE.MACHINE_PROXY"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -114,6 +116,7 @@
|
||||
<script>
|
||||
import AddMachineProxyModal from '@/components/machine/AddMachineProxyModal'
|
||||
import MachineProxyExportModal from '@/components/export/MachineProxyExportModal'
|
||||
import DataImportModal from '@/components/import/DataImportModal'
|
||||
|
||||
/**
|
||||
* 列
|
||||
@@ -165,6 +168,7 @@ const columns = [
|
||||
export default {
|
||||
name: 'MachineProxy',
|
||||
components: {
|
||||
DataImportModal,
|
||||
MachineProxyExportModal,
|
||||
AddMachineProxyModal
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user