2021-06-07 17:22:07 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="file-manage">
|
2023-07-05 22:06:32 +08:00
|
|
|
<el-dialog @open="getScripts()" :title="title" v-model="dialogVisible" :destroy-on-close="true" :show-close="true"
|
|
|
|
|
:before-close="handleClose" width="55%">
|
|
|
|
|
|
|
|
|
|
<page-table ref="pageTableRef" :query="queryConfig" v-model:query-form="query" :data="scriptTable"
|
|
|
|
|
:columns="columns" :total="total" v-model:page-size="query.pageSize" v-model:page-num="query.pageNum"
|
|
|
|
|
@pageChange="getScripts()" :show-selection="true" v-model:selection-data="selectionData">
|
|
|
|
|
|
|
|
|
|
<template #typeSelect>
|
|
|
|
|
<el-select v-model="type" placeholder="请选择">
|
2021-06-07 17:22:07 +08:00
|
|
|
<el-option :key="0" label="私有" :value="0"> </el-option>
|
|
|
|
|
<el-option :key="1" label="公共" :value="1"> </el-option>
|
|
|
|
|
</el-select>
|
2023-07-05 22:06:32 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #type="{ data }">
|
|
|
|
|
{{ enums.scriptTypeEnum.getLabelByValue(data.type) }}
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #queryRight>
|
2022-10-29 20:08:15 +08:00
|
|
|
<el-button v-auth="'machine:script:save'" type="primary" @click="editScript(null)" icon="plus"
|
2023-07-05 00:26:00 +08:00
|
|
|
plain>添加</el-button>
|
2023-07-05 22:06:32 +08:00
|
|
|
<el-button v-auth="'machine:script:del'" :disabled="selectionData.length < 1" type="danger"
|
|
|
|
|
@click="deleteRow(selectionData)" icon="delete" plain>删除</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template #action="{ data }">
|
|
|
|
|
<el-button v-auth="'machine:script:run'" v-if="data.id != null" @click="runScript(data)" type="primary"
|
|
|
|
|
icon="video-play" link>执行
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
|
|
<el-button @click="editScript(data)" type="primary" icon="tickets" link>查看
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</page-table>
|
2021-06-07 17:22:07 +08:00
|
|
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
<el-dialog title="脚本参数" v-model="scriptParamsDialog.visible" width="400px">
|
2023-07-05 00:26:00 +08:00
|
|
|
<el-form ref="paramsForm" :model="scriptParamsDialog.params" label-width="auto">
|
2023-07-01 14:34:42 +08:00
|
|
|
<el-form-item v-for="item in scriptParamsDialog.paramsFormItem as any" :key="item.name" :prop="item.model"
|
|
|
|
|
:label="item.name" required>
|
2022-10-29 20:08:15 +08:00
|
|
|
<el-input v-if="!item.options" v-model="scriptParamsDialog.params[item.model]"
|
|
|
|
|
:placeholder="item.placeholder" autocomplete="off" clearable></el-input>
|
|
|
|
|
<el-select v-else v-model="scriptParamsDialog.params[item.model]" :placeholder="item.placeholder"
|
|
|
|
|
filterable autocomplete="off" clearable style="width: 100%">
|
|
|
|
|
<el-option v-for="option in item.options.split(',')" :key="option" :label="option"
|
|
|
|
|
:value="option" />
|
2022-08-15 20:14:02 +08:00
|
|
|
</el-select>
|
2021-07-28 18:03:19 +08:00
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<span class="dialog-footer">
|
2023-07-05 22:06:32 +08:00
|
|
|
<el-button type="primary" @click="hasParamsRun()">确 定</el-button>
|
2021-07-28 18:03:19 +08:00
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
2021-11-18 14:40:12 +08:00
|
|
|
<el-dialog title="执行结果" v-model="resultDialog.visible" width="50%">
|
2021-06-07 17:22:07 +08:00
|
|
|
<div style="white-space: pre-line; padding: 10px; color: #000000">
|
2021-11-18 14:40:12 +08:00
|
|
|
<el-input v-model="resultDialog.result" :rows="20" type="textarea" />
|
2021-06-07 17:22:07 +08:00
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
<el-dialog v-if="terminalDialog.visible" title="终端" v-model="terminalDialog.visible" width="80%"
|
|
|
|
|
:close-on-click-modal="false" :modal="false" @close="closeTermnial">
|
2023-07-01 14:34:42 +08:00
|
|
|
<ssh-terminal ref="terminal" :cmd="terminalDialog.cmd" :machineId="terminalDialog.machineId" height="560px" />
|
2021-06-07 17:22:07 +08:00
|
|
|
</el-dialog>
|
|
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
<script-edit v-model:visible="editDialog.visible" v-model:data="editDialog.data" :title="editDialog.title"
|
|
|
|
|
v-model:machineId="editDialog.machineId" :isCommon="type == 1" @submitSuccess="submitSuccess" />
|
2021-06-07 17:22:07 +08:00
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { ref, toRefs, reactive, watch } from 'vue';
|
2021-06-07 17:22:07 +08:00
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
|
import SshTerminal from './SshTerminal.vue';
|
|
|
|
|
import { machineApi } from './api';
|
|
|
|
|
import enums from './enums';
|
|
|
|
|
import ScriptEdit from './ScriptEdit.vue';
|
2023-07-05 22:06:32 +08:00
|
|
|
import PageTable from '@/components/pagetable/PageTable.vue'
|
|
|
|
|
import { TableColumn, TableQuery } from '@/components/pagetable';
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const props = defineProps({
|
|
|
|
|
visible: { type: Boolean },
|
|
|
|
|
machineId: { type: Number },
|
|
|
|
|
title: { type: String },
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['update:visible', 'cancel', 'update:machineId'])
|
|
|
|
|
|
|
|
|
|
const paramsForm: any = ref(null);
|
2023-07-05 22:06:32 +08:00
|
|
|
const pageTableRef: any = ref(null);
|
|
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const state = reactive({
|
|
|
|
|
dialogVisible: false,
|
|
|
|
|
type: 0,
|
2023-07-05 22:06:32 +08:00
|
|
|
selectionData: [],
|
|
|
|
|
queryConfig: [
|
|
|
|
|
TableQuery.slot("type", "类型", "typeSelect"),
|
|
|
|
|
],
|
|
|
|
|
columns: [
|
|
|
|
|
TableColumn.new("name", "名称"),
|
|
|
|
|
TableColumn.new("description", "描述"),
|
|
|
|
|
TableColumn.new("type", "类型").isSlot().setAddWidth(5),
|
|
|
|
|
TableColumn.new("action", "操作").isSlot().setMinWidth(130).alignCenter(),
|
|
|
|
|
],
|
2022-10-29 20:08:15 +08:00
|
|
|
query: {
|
|
|
|
|
machineId: 0 as any,
|
|
|
|
|
pageNum: 1,
|
2023-07-05 22:06:32 +08:00
|
|
|
pageSize: 6,
|
2021-06-07 17:22:07 +08:00
|
|
|
},
|
2022-10-29 20:08:15 +08:00
|
|
|
editDialog: {
|
|
|
|
|
visible: false,
|
|
|
|
|
data: null as any,
|
|
|
|
|
title: '',
|
|
|
|
|
machineId: 9999999,
|
2021-06-07 17:22:07 +08:00
|
|
|
},
|
2022-10-29 20:08:15 +08:00
|
|
|
total: 0,
|
|
|
|
|
scriptTable: [],
|
|
|
|
|
scriptParamsDialog: {
|
2023-07-05 22:06:32 +08:00
|
|
|
script: null,
|
2022-10-29 20:08:15 +08:00
|
|
|
visible: false,
|
|
|
|
|
params: {},
|
|
|
|
|
paramsFormItem: [],
|
|
|
|
|
},
|
|
|
|
|
resultDialog: {
|
|
|
|
|
visible: false,
|
|
|
|
|
result: '',
|
|
|
|
|
},
|
|
|
|
|
terminalDialog: {
|
|
|
|
|
visible: false,
|
|
|
|
|
cmd: '',
|
|
|
|
|
machineId: 0,
|
|
|
|
|
},
|
|
|
|
|
});
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const {
|
|
|
|
|
dialogVisible,
|
2023-07-05 22:06:32 +08:00
|
|
|
queryConfig,
|
|
|
|
|
columns,
|
2022-10-29 20:08:15 +08:00
|
|
|
type,
|
2023-07-05 22:06:32 +08:00
|
|
|
selectionData,
|
2022-10-29 20:08:15 +08:00
|
|
|
query,
|
|
|
|
|
editDialog,
|
|
|
|
|
total,
|
|
|
|
|
scriptTable,
|
|
|
|
|
scriptParamsDialog,
|
|
|
|
|
resultDialog,
|
|
|
|
|
terminalDialog,
|
|
|
|
|
} = toRefs(state)
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
watch(props, async (newValue) => {
|
2023-07-01 14:34:42 +08:00
|
|
|
state.dialogVisible = newValue.visible;
|
2022-10-29 20:08:15 +08:00
|
|
|
});
|
2022-05-12 10:34:16 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const getScripts = async () => {
|
2023-07-01 14:34:42 +08:00
|
|
|
try {
|
2023-07-05 22:06:32 +08:00
|
|
|
// 通过open事件才开获取到pageTableRef值
|
|
|
|
|
pageTableRef.value.loading(true)
|
2023-07-01 14:34:42 +08:00
|
|
|
state.query.machineId = state.type == 0 ? props.machineId : 9999999;
|
|
|
|
|
const res = await machineApi.scripts.request(state.query);
|
|
|
|
|
state.scriptTable = res.list;
|
|
|
|
|
state.total = res.total;
|
|
|
|
|
} finally {
|
2023-07-05 22:06:32 +08:00
|
|
|
pageTableRef.value.loading(false)
|
2023-07-01 14:34:42 +08:00
|
|
|
}
|
2022-10-29 20:08:15 +08:00
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const runScript = async (script: any) => {
|
|
|
|
|
// 如果存在参数,则弹窗输入参数后执行
|
|
|
|
|
if (script.params) {
|
|
|
|
|
state.scriptParamsDialog.paramsFormItem = JSON.parse(script.params);
|
|
|
|
|
if (state.scriptParamsDialog.paramsFormItem && state.scriptParamsDialog.paramsFormItem.length > 0) {
|
|
|
|
|
state.scriptParamsDialog.visible = true;
|
2023-07-05 22:06:32 +08:00
|
|
|
state.scriptParamsDialog.script = script;
|
2022-10-29 20:08:15 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run(script);
|
|
|
|
|
};
|
2021-07-28 18:03:19 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
// 有参数的脚本执行函数
|
2023-07-05 22:06:32 +08:00
|
|
|
const hasParamsRun = async () => {
|
2022-10-29 20:08:15 +08:00
|
|
|
// 如果脚本参数弹窗显示,则校验参数表单数据通过后执行
|
|
|
|
|
if (state.scriptParamsDialog.visible) {
|
|
|
|
|
paramsForm.value.validate((valid: any) => {
|
|
|
|
|
if (valid) {
|
2023-07-05 22:06:32 +08:00
|
|
|
run(state.scriptParamsDialog.script);
|
2022-10-29 20:08:15 +08:00
|
|
|
state.scriptParamsDialog.params = {};
|
|
|
|
|
state.scriptParamsDialog.visible = false;
|
2023-07-05 22:06:32 +08:00
|
|
|
state.scriptParamsDialog.script = null;
|
2022-10-29 20:08:15 +08:00
|
|
|
paramsForm.value.resetFields();
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
2021-07-28 18:03:19 +08:00
|
|
|
}
|
2022-10-29 20:08:15 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
2021-07-28 18:03:19 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const run = async (script: any) => {
|
|
|
|
|
const noResult = script.type == enums.scriptTypeEnum['NO_RESULT'].value;
|
|
|
|
|
// 如果脚本类型为有结果类型,则显示结果信息
|
|
|
|
|
if (script.type == enums.scriptTypeEnum['RESULT'].value || noResult) {
|
|
|
|
|
const res = await machineApi.runScript.request({
|
|
|
|
|
machineId: props.machineId,
|
|
|
|
|
scriptId: script.id,
|
2023-07-05 22:06:32 +08:00
|
|
|
params: JSON.stringify(state.scriptParamsDialog.params),
|
2022-10-29 20:08:15 +08:00
|
|
|
});
|
2021-07-28 18:03:19 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
if (noResult) {
|
|
|
|
|
ElMessage.success('执行完成');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
state.resultDialog.result = res;
|
|
|
|
|
state.resultDialog.visible = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
if (script.type == enums.scriptTypeEnum['REAL_TIME'].value) {
|
|
|
|
|
script = script.script;
|
|
|
|
|
if (state.scriptParamsDialog.params) {
|
|
|
|
|
script = templateResolve(script, state.scriptParamsDialog.params);
|
|
|
|
|
}
|
|
|
|
|
state.terminalDialog.cmd = script;
|
|
|
|
|
state.terminalDialog.visible = true;
|
|
|
|
|
state.terminalDialog.machineId = props.machineId as any;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
/**
|
|
|
|
|
* 解析 {{.param}} 形式模板字符串
|
|
|
|
|
*/
|
|
|
|
|
function templateResolve(template: string, param: any) {
|
|
|
|
|
return template.replace(/\{{.\w+\}}/g, (word) => {
|
|
|
|
|
const key = word.substring(3, word.length - 2);
|
|
|
|
|
const value = param[key];
|
|
|
|
|
if (value != null || value != undefined) {
|
|
|
|
|
return value;
|
2021-11-25 14:34:15 +08:00
|
|
|
}
|
2022-10-29 20:08:15 +08:00
|
|
|
return '';
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-11-25 14:34:15 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const closeTermnial = () => {
|
|
|
|
|
state.terminalDialog.visible = false;
|
|
|
|
|
state.terminalDialog.machineId = 0;
|
|
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
|
|
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const editScript = (data: any) => {
|
|
|
|
|
state.editDialog.machineId = props.machineId as any;
|
|
|
|
|
state.editDialog.data = data;
|
|
|
|
|
if (data) {
|
|
|
|
|
state.editDialog.title = '查看编辑脚本';
|
|
|
|
|
} else {
|
|
|
|
|
state.editDialog.title = '新增脚本';
|
|
|
|
|
}
|
|
|
|
|
state.editDialog.visible = true;
|
|
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
const submitSuccess = () => {
|
|
|
|
|
getScripts();
|
|
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2023-07-05 22:06:32 +08:00
|
|
|
const deleteRow = (rows: any) => {
|
|
|
|
|
ElMessageBox.confirm(`此操作将删除【${rows.map((x: any) => x.name).join(", ")}】脚本信息, 是否继续?`, '提示', {
|
2022-10-29 20:08:15 +08:00
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning',
|
|
|
|
|
}).then(() => {
|
|
|
|
|
machineApi.deleteScript
|
|
|
|
|
.request({
|
|
|
|
|
machineId: props.machineId,
|
2023-07-05 22:06:32 +08:00
|
|
|
scriptId: rows.map((x: any) => x.id).join(","),
|
2022-10-29 20:08:15 +08:00
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
getScripts();
|
2021-06-07 17:22:07 +08:00
|
|
|
});
|
2022-10-29 20:08:15 +08:00
|
|
|
// 删除配置文件
|
|
|
|
|
});
|
|
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
|
2022-10-29 20:08:15 +08:00
|
|
|
/**
|
|
|
|
|
* 关闭取消按钮触发的事件
|
|
|
|
|
*/
|
|
|
|
|
const handleClose = () => {
|
|
|
|
|
emit('update:visible', false);
|
|
|
|
|
emit('update:machineId', null);
|
|
|
|
|
emit('cancel');
|
2023-07-05 22:06:32 +08:00
|
|
|
state.type = 0;
|
2022-10-29 20:08:15 +08:00
|
|
|
state.scriptTable = [];
|
|
|
|
|
state.scriptParamsDialog.paramsFormItem = [];
|
|
|
|
|
};
|
2021-06-07 17:22:07 +08:00
|
|
|
</script>
|
|
|
|
|
<style lang="sass">
|
|
|
|
|
</style>
|