✨ 计划任务中断及清理.
This commit is contained in:
80
orion-ops-ui/src/components/exec/job/selector/index.vue
Normal file
80
orion-ops-ui/src/components/exec/job/selector/index.vue
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<a-select v-model:model-value="value as any"
|
||||||
|
:options="optionData"
|
||||||
|
:allow-search="true"
|
||||||
|
:loading="loading"
|
||||||
|
:disabled="loading"
|
||||||
|
:filter-option="labelFilter"
|
||||||
|
:allow-create="allowCreate"
|
||||||
|
placeholder="请选择计划任务" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'execJobSelector'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { SelectOptionData } from '@arco-design/web-vue';
|
||||||
|
import { computed, onBeforeMount, ref } from 'vue';
|
||||||
|
import { useCacheStore } from '@/store';
|
||||||
|
import { labelFilter } from '@/types/form';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Partial<{
|
||||||
|
modelValue: number;
|
||||||
|
name: string;
|
||||||
|
allowCreate: boolean;
|
||||||
|
}>>(), {
|
||||||
|
allowCreate: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(['update:modelValue', 'update:name']);
|
||||||
|
|
||||||
|
const { loading, setLoading } = useLoading();
|
||||||
|
const cacheStore = useCacheStore();
|
||||||
|
|
||||||
|
const value = computed({
|
||||||
|
get() {
|
||||||
|
if (props.allowCreate) {
|
||||||
|
return props.modelValue || props.name;
|
||||||
|
} else {
|
||||||
|
return props.modelValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set(e) {
|
||||||
|
if (typeof e === 'string') {
|
||||||
|
emits('update:modelValue', null);
|
||||||
|
emits('update:name', e);
|
||||||
|
} else {
|
||||||
|
// 已有的值
|
||||||
|
emits('update:modelValue', e);
|
||||||
|
emits('update:name', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const optionData = ref<Array<SelectOptionData>>([]);
|
||||||
|
|
||||||
|
// 初始化选项
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const dictKeys = await cacheStore.loadExecJobs();
|
||||||
|
optionData.value = dictKeys.map(s => {
|
||||||
|
return {
|
||||||
|
label: s.name,
|
||||||
|
value: s.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// 执行类型
|
||||||
|
export type ExecType = 'BATCH' | 'JOB';
|
||||||
|
|
||||||
// 批量执行状态
|
// 批量执行状态
|
||||||
export const execStatus = {
|
export const execStatus = {
|
||||||
// 等待中
|
// 等待中
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
:loading="loading">
|
:loading="loading">
|
||||||
<div class="panel-wrapper">
|
<div class="panel-wrapper">
|
||||||
<!-- 日志面板 -->
|
<!-- 日志面板 -->
|
||||||
<exec-log-panel ref="log" :visible-back="false" />
|
<exec-log-panel ref="log"
|
||||||
|
:type="type"
|
||||||
|
:visible-back="false" />
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@@ -29,12 +31,18 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { ExecType } from '../const';
|
||||||
import useVisible from '@/hooks/visible';
|
import useVisible from '@/hooks/visible';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { nextTick, ref } from 'vue';
|
import { nextTick, ref } from 'vue';
|
||||||
import { getExecCommandLog } from '@/api/exec/exec-command-log';
|
import { getExecCommandLog } from '@/api/exec/exec-command-log';
|
||||||
|
import { getExecJobLog } from '@/api/exec/exec-job-log';
|
||||||
import ExecLogPanel from '../panel/index.vue';
|
import ExecLogPanel from '../panel/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
type: ExecType;
|
||||||
|
}>();
|
||||||
|
|
||||||
const { visible, setVisible } = useVisible();
|
const { visible, setVisible } = useVisible();
|
||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
|
|
||||||
@@ -46,7 +54,15 @@
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// 获取执行日志
|
// 获取执行日志
|
||||||
const { data } = await getExecCommandLog(id);
|
let detailGetter;
|
||||||
|
if (props.type === 'BATCH') {
|
||||||
|
// 批量执行日志
|
||||||
|
detailGetter = getExecCommandLog(id);
|
||||||
|
} else {
|
||||||
|
// 计划任务日志
|
||||||
|
detailGetter = getExecJobLog(id);
|
||||||
|
}
|
||||||
|
const { data } = await detailGetter;
|
||||||
// 打开日志
|
// 打开日志
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@@ -10,8 +10,9 @@
|
|||||||
<!-- 日志容器 -->
|
<!-- 日志容器 -->
|
||||||
<log-view ref="logViewRef"
|
<log-view ref="logViewRef"
|
||||||
class="log-view-container"
|
class="log-view-container"
|
||||||
|
:type="type"
|
||||||
:current="currentHostExecId"
|
:current="currentHostExecId"
|
||||||
:hosts="execLog.hosts"
|
:exec-log="execLog"
|
||||||
:appender="appender" />
|
:appender="appender" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -25,16 +26,19 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ExecLogQueryResponse } from '@/api/exec/exec-log';
|
import type { ExecLogQueryResponse } from '@/api/exec/exec-log';
|
||||||
import type { ILogAppender } from './appender-const';
|
import type { ILogAppender } from './appender-const';
|
||||||
|
import type { ExecType } from '../const';
|
||||||
import { onUnmounted, ref, nextTick, onMounted } from 'vue';
|
import { onUnmounted, ref, nextTick, onMounted } from 'vue';
|
||||||
import { getExecCommandLogStatus } from '@/api/exec/exec-command-log';
|
import { getExecCommandLogStatus } from '@/api/exec/exec-command-log';
|
||||||
|
import { getExecJobLogStatus } from '@/api/exec/exec-job-log';
|
||||||
import { dictKeys, execHostStatus, execStatus } from '../const';
|
import { dictKeys, execHostStatus, execStatus } from '../const';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
import ExecHost from './exec-host.vue';
|
import ExecHost from './exec-host.vue';
|
||||||
import LogView from './log-view.vue';
|
import LogView from './log-view.vue';
|
||||||
import LogAppender from '@/components/exec/log/panel/log-appender';
|
import LogAppender from './log-appender';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visibleBack: boolean
|
visibleBack: boolean;
|
||||||
|
type: ExecType;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emits = defineEmits(['back']);
|
const emits = defineEmits(['back']);
|
||||||
@@ -48,7 +52,7 @@
|
|||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: ExecLogQueryResponse) => {
|
const open = (record: ExecLogQueryResponse) => {
|
||||||
appender.value = new LogAppender({ execId: record.id });
|
appender.value = new LogAppender(props.type, { execId: record.id });
|
||||||
execLog.value = record;
|
execLog.value = record;
|
||||||
currentHostExecId.value = record.hosts[0].id;
|
currentHostExecId.value = record.hosts[0].id;
|
||||||
// 定时查询执行状态
|
// 定时查询执行状态
|
||||||
@@ -71,7 +75,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const { data: { logList, hostList } } = await getExecCommandLogStatus([execLog.value.id]);
|
let statusGetter;
|
||||||
|
if (props.type === 'BATCH') {
|
||||||
|
// 批量执行日志状态
|
||||||
|
statusGetter = getExecCommandLogStatus([execLog.value.id]);
|
||||||
|
} else {
|
||||||
|
// 计划任务日志状态
|
||||||
|
statusGetter = getExecJobLogStatus([execLog.value.id]);
|
||||||
|
}
|
||||||
|
const { data: { logList, hostList } } = await statusGetter;
|
||||||
if (logList.length) {
|
if (logList.length) {
|
||||||
execLog.value.status = logList[0].status;
|
execLog.value.status = logList[0].status;
|
||||||
execLog.value.startTime = logList[0].startTime;
|
execLog.value.startTime = logList[0].startTime;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import type { ILogAppender, LogAddons, LogAppenderConf, LogDomRef } from './appender-const';
|
import type { ILogAppender, LogAddons, LogAppenderConf, LogDomRef } from './appender-const';
|
||||||
import { LogAppenderOptions } from './appender-const';
|
import { LogAppenderOptions } from './appender-const';
|
||||||
|
import type { ExecType } from '../const';
|
||||||
import type { ExecLogTailRequest } from '@/api/exec/exec-log';
|
import type { ExecLogTailRequest } from '@/api/exec/exec-log';
|
||||||
import { getExecCommandLogTailToken } from '@/api/exec/exec-command-log';
|
import { getExecCommandLogTailToken } from '@/api/exec/exec-command-log';
|
||||||
|
import { getExecJobLogTailToken } from '@/api/exec/exec-job-log';
|
||||||
import { webSocketBaseUrl } from '@/utils/env';
|
import { webSocketBaseUrl } from '@/utils/env';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { createWebSocket } from '@/utils';
|
import { createWebSocket } from '@/utils';
|
||||||
@@ -29,8 +31,11 @@ export default class LogAppender implements ILogAppender {
|
|||||||
|
|
||||||
private readonly fitAllFn: () => {};
|
private readonly fitAllFn: () => {};
|
||||||
|
|
||||||
constructor(config: ExecLogTailRequest) {
|
private readonly type: ExecType;
|
||||||
|
|
||||||
|
constructor(type: ExecType, config: ExecLogTailRequest) {
|
||||||
this.current = undefined as unknown as LogAppenderConf;
|
this.current = undefined as unknown as LogAppenderConf;
|
||||||
|
this.type = type;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.appenderRel = {};
|
this.appenderRel = {};
|
||||||
this.fitAllFn = useDebounceFn(this.fitAll).bind(this);
|
this.fitAllFn = useDebounceFn(this.fitAll).bind(this);
|
||||||
@@ -141,8 +146,16 @@ export default class LogAppender implements ILogAppender {
|
|||||||
|
|
||||||
// 初始化 client
|
// 初始化 client
|
||||||
async openClient() {
|
async openClient() {
|
||||||
|
let tokenMaker;
|
||||||
// 获取 token
|
// 获取 token
|
||||||
const { data } = await getExecCommandLogTailToken(this.config);
|
if (this.type === 'BATCH') {
|
||||||
|
// 获取批量执行日志 token
|
||||||
|
tokenMaker = getExecCommandLogTailToken(this.config);
|
||||||
|
} else {
|
||||||
|
// 获取计划任务日志 token
|
||||||
|
tokenMaker = getExecJobLogTailToken(this.config);
|
||||||
|
}
|
||||||
|
const { data } = await tokenMaker;
|
||||||
// 打开会话
|
// 打开会话
|
||||||
try {
|
try {
|
||||||
this.client = await createWebSocket(`${webSocketBaseUrl}/exec/log/${data}`);
|
this.client = await createWebSocket(`${webSocketBaseUrl}/exec/log/${data}`);
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
<div class="log-header">
|
<div class="log-header">
|
||||||
<!-- 左侧信息 -->
|
<!-- 左侧信息 -->
|
||||||
<a-space class="log-header-left" :size="12">
|
<a-space class="log-header-left" :size="12">
|
||||||
|
<!-- 执行序列 -->
|
||||||
|
<a-tag v-if="execLog.execSeq" color="green">
|
||||||
|
#{{ execLog.execSeq }}
|
||||||
|
</a-tag>
|
||||||
<!-- 状态 -->
|
<!-- 状态 -->
|
||||||
<a-tag :color="getDictValue(execHostStatusKey, host.status, 'color')">
|
<a-tag :color="getDictValue(execHostStatusKey, host.status, 'color')">
|
||||||
{{ getDictValue(execHostStatusKey, host.status) }}
|
{{ getDictValue(execHostStatusKey, host.status) }}
|
||||||
@@ -160,20 +164,24 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ExecHostLogQueryResponse } from '@/api/exec/exec-log';
|
import type { ExecLogQueryResponse, ExecHostLogQueryResponse } from '@/api/exec/exec-log';
|
||||||
import type { ILogAppender } from './appender-const';
|
import type { ILogAppender } from './appender-const';
|
||||||
|
import type { ExecType } from '../const';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { execHostStatus, execHostStatusKey } from '../const';
|
import { execHostStatus, execHostStatusKey } from '../const';
|
||||||
import { formatDuration } from '@/utils';
|
import { formatDuration } from '@/utils';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
import { downloadExecCommandLogFile } from '@/api/exec/exec-command-log';
|
import { downloadExecCommandLogFile } from '@/api/exec/exec-command-log';
|
||||||
|
import { downloadExecJobLogFile } from '@/api/exec/exec-job-log';
|
||||||
import { downloadFile } from '@/utils/file';
|
import { downloadFile } from '@/utils/file';
|
||||||
import XtermSearchModal from '@/components/xtrem/search-modal/index.vue';
|
import XtermSearchModal from '@/components/xtrem/search-modal/index.vue';
|
||||||
import 'xterm/css/xterm.css';
|
import 'xterm/css/xterm.css';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
type: ExecType;
|
||||||
|
execLog: ExecLogQueryResponse;
|
||||||
host: ExecHostLogQueryResponse;
|
host: ExecHostLogQueryResponse;
|
||||||
appender: ILogAppender
|
appender: ILogAppender;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { getDictValue } = useDictStore();
|
const { getDictValue } = useDictStore();
|
||||||
@@ -204,7 +212,17 @@
|
|||||||
|
|
||||||
// 下载文件
|
// 下载文件
|
||||||
const downloadLogFile = async (id: number) => {
|
const downloadLogFile = async (id: number) => {
|
||||||
const data = await downloadExecCommandLogFile(id);
|
// 获取日志文件
|
||||||
|
let fileGetter;
|
||||||
|
if (props.type === 'BATCH') {
|
||||||
|
// 下载批量执行日志
|
||||||
|
fileGetter = downloadExecCommandLogFile(id);
|
||||||
|
} else {
|
||||||
|
// 下载计划任务日志
|
||||||
|
fileGetter = downloadExecJobLogFile(id);
|
||||||
|
}
|
||||||
|
// 瞎子啊
|
||||||
|
const data = await fileGetter;
|
||||||
downloadFile(data);
|
downloadFile(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<log-item class="log-item"
|
<log-item class="log-item"
|
||||||
v-show="current === host.id"
|
v-show="current === host.id"
|
||||||
v-for="host in hosts"
|
v-for="host in execLog.hosts"
|
||||||
:key="host.id"
|
:key="host.id"
|
||||||
:ref="addRef as unknown as VNodeRef"
|
:ref="addRef as unknown as VNodeRef"
|
||||||
|
:type="type"
|
||||||
:host="host"
|
:host="host"
|
||||||
|
:exec-log="execLog"
|
||||||
:appender="appender" />
|
:appender="appender" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -19,14 +21,16 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VNodeRef } from 'vue';
|
import type { VNodeRef } from 'vue';
|
||||||
import type { LogDomRef, ILogAppender } from './appender-const';
|
import type { LogDomRef, ILogAppender } from './appender-const';
|
||||||
import type { ExecHostLogQueryResponse } from '@/api/exec/exec-log';
|
import type { ExecLogQueryResponse } from '@/api/exec/exec-log';
|
||||||
|
import type { ExecType } from '../const';
|
||||||
import { nextTick, ref, watch } from 'vue';
|
import { nextTick, ref, watch } from 'vue';
|
||||||
import LogItem from './log-item.vue';
|
import LogItem from './log-item.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
current: number;
|
current: number;
|
||||||
hosts: Array<ExecHostLogQueryResponse>;
|
execLog: ExecLogQueryResponse;
|
||||||
appender: ILogAppender;
|
appender: ILogAppender;
|
||||||
|
type: ExecType;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const logRefs = ref<Array<LogDomRef>>([]);
|
const logRefs = ref<Array<LogDomRef>>([]);
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ import { getHostGroupTree } from '@/api/asset/host-group';
|
|||||||
import { getMenuList } from '@/api/system/menu';
|
import { getMenuList } from '@/api/system/menu';
|
||||||
import { getCurrentAuthorizedHostIdentity, getCurrentAuthorizedHostKey } from '@/api/asset/asset-authorized-data';
|
import { getCurrentAuthorizedHostIdentity, getCurrentAuthorizedHostKey } from '@/api/asset/asset-authorized-data';
|
||||||
import { getCommandSnippetGroupList } from '@/api/asset/command-snippet-group';
|
import { getCommandSnippetGroupList } from '@/api/asset/command-snippet-group';
|
||||||
|
import { getExecJobList } from '@/api/exec/exec-job';
|
||||||
|
|
||||||
export type CacheType = 'users' | 'menus' | 'roles'
|
export type CacheType = 'users' | 'menus' | 'roles'
|
||||||
| 'hosts' | 'hostGroups' | 'hostKeys' | 'hostIdentities'
|
| 'hosts' | 'hostGroups' | 'hostKeys' | 'hostIdentities'
|
||||||
| 'dictKeys'
|
| 'dictKeys'
|
||||||
| 'authorizedHostKeys' | 'authorizedHostIdentities'
|
| 'authorizedHostKeys' | 'authorizedHostIdentities'
|
||||||
| 'commandSnippetGroups'
|
| 'commandSnippetGroups'
|
||||||
|
| 'execJob'
|
||||||
| string
|
| string
|
||||||
|
|
||||||
export default defineStore('cache', {
|
export default defineStore('cache', {
|
||||||
@@ -118,5 +120,10 @@ export default defineStore('cache', {
|
|||||||
return await this.load('commandSnippetGroups', getCommandSnippetGroupList, force);
|
return await this.load('commandSnippetGroups', getCommandSnippetGroupList, force);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 获取执行计划列表
|
||||||
|
async loadExecJobs(force = false) {
|
||||||
|
return await this.load('execJob', getExecJobList, force);
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<exec-log-panel ref="log" :visible-back="false" />
|
<exec-log-panel ref="log"
|
||||||
|
type="BATCH"
|
||||||
|
:visible-back="false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
<exec-command-log-clear-modal ref="clearModal"
|
<exec-command-log-clear-modal ref="clearModal"
|
||||||
@clear="clearCallback" />
|
@clear="clearCallback" />
|
||||||
<!-- 执行日志模态框 -->
|
<!-- 执行日志模态框 -->
|
||||||
<exec-log-panel-modal ref="logModal" />
|
<exec-log-panel-modal ref="logModal"
|
||||||
|
type="BATCH" />
|
||||||
<!-- json 模态框 -->
|
<!-- json 模态框 -->
|
||||||
<json-editor-modal ref="jsonModal"
|
<json-editor-modal ref="jsonModal"
|
||||||
:esc-to-close="true" />
|
:esc-to-close="true" />
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
<!-- 执行日志 -->
|
<!-- 执行日志 -->
|
||||||
<div v-if="logVisible" class="panel-wrapper">
|
<div v-if="logVisible" class="panel-wrapper">
|
||||||
<exec-log-panel ref="log"
|
<exec-log-panel ref="log"
|
||||||
|
type="BATCH"
|
||||||
:visibleBack="true"
|
:visibleBack="true"
|
||||||
@back="setLogVisible(false)" />
|
@back="setLogVisible(false)" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<exec-log-panel ref="log" :visible-back="false" />
|
<exec-log-panel ref="log"
|
||||||
|
type="JOB"
|
||||||
|
:visible-back="false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -103,17 +103,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ExecLogQueryResponse, ExecHostLogQueryResponse } from '@/api/exec/exec-log';
|
import type { ExecLogQueryResponse, ExecHostLogQueryResponse } from '@/api/exec/exec-log';
|
||||||
import { deleteExecJobHostLog } from '@/api/exec/exec-job-log';
|
import { deleteExecJobHostLog } from '@/api/exec/exec-job-log';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { interruptHostExecJob } from '@/api/exec/exec-job-log';
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import columns from '../../exec-command-log/types/host-table.columns';
|
|
||||||
import { execHostStatusKey, execHostStatus } from '@/components/exec/log/const';
|
import { execHostStatusKey, execHostStatus } from '@/components/exec/log/const';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
|
import columns from '../../exec-command-log/types/host-table.columns';
|
||||||
import { useExpandable } from '@/types/table';
|
import { useExpandable } from '@/types/table';
|
||||||
import { dateFormat, formatDuration } from '@/utils';
|
import { dateFormat, formatDuration } from '@/utils';
|
||||||
// import { interruptHostExecJob } from '@/api/exec/exec-job';
|
|
||||||
import { downloadExecJobLogFile } from '@/api/exec/exec-job-log';
|
import { downloadExecJobLogFile } from '@/api/exec/exec-job-log';
|
||||||
import { copy } from '@/hooks/copy';
|
import { copy } from '@/hooks/copy';
|
||||||
import { downloadFile } from '@/utils/file';
|
import { downloadFile } from '@/utils/file';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
row: ExecLogQueryResponse;
|
row: ExecLogQueryResponse;
|
||||||
@@ -136,9 +136,9 @@
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
// 调用中断接口
|
// 调用中断接口
|
||||||
// await interruptHostExecJob({
|
await interruptHostExecJob({
|
||||||
// hostLogId: record.id
|
hostLogId: record.id
|
||||||
// });
|
});
|
||||||
Message.success('已中断');
|
Message.success('已中断');
|
||||||
record.status = execHostStatus.INTERRUPTED;
|
record.status = execHostStatus.INTERRUPTED;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<a-modal v-model:visible="visible"
|
<a-modal v-model:visible="visible"
|
||||||
body-class="modal-form"
|
body-class="modal-form"
|
||||||
title-align="start"
|
title-align="start"
|
||||||
title="清空批量执行日志"
|
title="清空计划任务日志"
|
||||||
:align-center="false"
|
:align-center="false"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
@@ -25,16 +25,11 @@
|
|||||||
show-time
|
show-time
|
||||||
format="YYYY-MM-DD HH:mm:ss" />
|
format="YYYY-MM-DD HH:mm:ss" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 执行用户 -->
|
<!-- 计划任务 -->
|
||||||
<a-form-item field="userId" label="执行用户">
|
<a-form-item field="sourceId" label="计划任务">
|
||||||
<user-selector v-model="formModel.userId"
|
<exec-job-selector v-model:model-value="formModel.sourceId"
|
||||||
placeholder="请选择执行用户"
|
v-model:name="formModel.description"
|
||||||
allow-clear />
|
allow-create
|
||||||
</a-form-item>
|
|
||||||
<!-- 执行描述 -->
|
|
||||||
<a-form-item field="description" label="执行描述">
|
|
||||||
<a-input v-model="formModel.description"
|
|
||||||
placeholder="请输入执行描述"
|
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 执行命令 -->
|
<!-- 执行命令 -->
|
||||||
@@ -69,7 +64,7 @@
|
|||||||
import { getExecJobLogCount, clearExecJobLog } from '@/api/exec/exec-job-log';
|
import { getExecJobLogCount, clearExecJobLog } from '@/api/exec/exec-job-log';
|
||||||
import { Message, Modal } from '@arco-design/web-vue';
|
import { Message, Modal } from '@arco-design/web-vue';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
import UserSelector from '@/components/user/user/selector/index.vue';
|
import ExecJobSelector from '@/components/exec/job/selector/index.vue';
|
||||||
|
|
||||||
const emits = defineEmits(['clear']);
|
const emits = defineEmits(['clear']);
|
||||||
|
|
||||||
@@ -83,7 +78,7 @@
|
|||||||
const defaultForm = (): ExecLogQueryRequest => {
|
const defaultForm = (): ExecLogQueryRequest => {
|
||||||
return {
|
return {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
userId: undefined,
|
sourceId: undefined,
|
||||||
description: undefined,
|
description: undefined,
|
||||||
command: undefined,
|
command: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
@@ -103,6 +98,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({ open });
|
defineExpose({ open });
|
||||||
|
|
||||||
// 确定
|
// 确定
|
||||||
const handlerOk = async () => {
|
const handlerOk = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
<a-card class="general-card table-search-card">
|
<a-card class="general-card table-search-card">
|
||||||
<query-header :model="formModel"
|
<query-header :model="formModel"
|
||||||
label-align="left"
|
label-align="left"
|
||||||
:itemOptions="{ 5: { span: 2 } }"
|
:itemOptions="{ 4: { span: 2 } }"
|
||||||
@submit="fetchTableData"
|
@submit="fetchTableData"
|
||||||
@reset="fetchTableData"
|
@reset="fetchTableData"
|
||||||
@keyup.enter="() => fetchTableData()">
|
@keyup.enter="() => fetchTableData()">
|
||||||
<!-- 执行描述 -->
|
<!-- 任务名称 -->
|
||||||
<a-form-item field="description" label="执行描述">
|
<a-form-item field="description" label="任务名称">
|
||||||
<a-input v-model="formModel.description"
|
<a-input v-model="formModel.description"
|
||||||
placeholder="请输入执行描述"
|
placeholder="请输入任务名称"
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 执行状态 -->
|
<!-- 执行状态 -->
|
||||||
@@ -20,12 +20,6 @@
|
|||||||
placeholder="请选择执行状态"
|
placeholder="请选择执行状态"
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 执行用户 -->
|
|
||||||
<a-form-item field="userId" label="执行用户">
|
|
||||||
<user-selector v-model="formModel.userId"
|
|
||||||
placeholder="请选择执行用户"
|
|
||||||
allow-clear />
|
|
||||||
</a-form-item>
|
|
||||||
<!-- 执行命令 -->
|
<!-- 执行命令 -->
|
||||||
<a-form-item field="command" label="执行命令">
|
<a-form-item field="command" label="执行命令">
|
||||||
<a-input v-model="formModel.command"
|
<a-input v-model="formModel.command"
|
||||||
@@ -212,8 +206,7 @@
|
|||||||
import { useExpandable, usePagination, useRowSelection } from '@/types/table';
|
import { useExpandable, usePagination, useRowSelection } from '@/types/table';
|
||||||
import { useDictStore } from '@/store';
|
import { useDictStore } from '@/store';
|
||||||
import { dateFormat, formatDuration } from '@/utils';
|
import { dateFormat, formatDuration } from '@/utils';
|
||||||
// import { interruptExecJob } from '@/api/exec/exec-job';
|
import { interruptExecJob } from '@/api/exec/exec-job-log';
|
||||||
import UserSelector from '@/components/user/user/selector/index.vue';
|
|
||||||
import ExecJobHostLogTable from './exec-job-host-log-table.vue';
|
import ExecJobHostLogTable from './exec-job-host-log-table.vue';
|
||||||
|
|
||||||
const emits = defineEmits(['viewCommand', 'viewParams', 'viewLog', 'openClear']);
|
const emits = defineEmits(['viewCommand', 'viewParams', 'viewLog', 'openClear']);
|
||||||
@@ -230,7 +223,6 @@
|
|||||||
const tableRenderData = ref<ExecLogQueryResponse[]>([]);
|
const tableRenderData = ref<ExecLogQueryResponse[]>([]);
|
||||||
const formModel = reactive<ExecLogQueryRequest>({
|
const formModel = reactive<ExecLogQueryRequest>({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
userId: undefined,
|
|
||||||
description: undefined,
|
description: undefined,
|
||||||
command: undefined,
|
command: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
@@ -239,7 +231,7 @@
|
|||||||
|
|
||||||
// 打开清理
|
// 打开清理
|
||||||
const openClear = () => {
|
const openClear = () => {
|
||||||
emits('openClear', { ...formModel, id: undefined });
|
emits('openClear', { ...formModel, id: undefined, description: undefined });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除选中行
|
// 删除选中行
|
||||||
@@ -281,9 +273,9 @@
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
// 调用中断接口
|
// 调用中断接口
|
||||||
// await interruptExecJob({
|
await interruptExecJob({
|
||||||
// logId: record.id
|
logId: record.id
|
||||||
// });
|
});
|
||||||
Message.success('已中断');
|
Message.success('已中断');
|
||||||
record.status = execStatus.COMPLETED;
|
record.status = execStatus.COMPLETED;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
<exec-job-log-clear-modal ref="clearModal"
|
<exec-job-log-clear-modal ref="clearModal"
|
||||||
@clear="clearCallback" />
|
@clear="clearCallback" />
|
||||||
<!-- 执行日志模态框 -->
|
<!-- 执行日志模态框 -->
|
||||||
<exec-log-panel-modal ref="logModal" />
|
<exec-log-panel-modal ref="logModal"
|
||||||
|
type="JOB" />
|
||||||
<!-- json 模态框 -->
|
<!-- json 模态框 -->
|
||||||
<json-editor-modal ref="jsonModal"
|
<json-editor-modal ref="jsonModal"
|
||||||
:esc-to-close="true" />
|
:esc-to-close="true" />
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { DictKeyQueryResponse } from '@/api/system/dict-key';
|
||||||
import type { DictValueUpdateRequest } from '@/api/system/dict-value';
|
import type { DictValueUpdateRequest } from '@/api/system/dict-value';
|
||||||
import type { ExtraParamType } from '../../dict-key/types/const';
|
import type { ExtraParamType } from '../../dict-key/types/const';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
@@ -97,7 +98,6 @@
|
|||||||
import { createDictValue, updateDictValue } from '@/api/system/dict-value';
|
import { createDictValue, updateDictValue } from '@/api/system/dict-value';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { ValueType, sortStep } from '../../dict-key/types/const';
|
import { ValueType, sortStep } from '../../dict-key/types/const';
|
||||||
import { DictKeyQueryResponse } from '@/api/system/dict-key';
|
|
||||||
import { useCacheStore } from '@/store';
|
import { useCacheStore } from '@/store';
|
||||||
import DictKeySelector from '@/components/system/dict-key/selector/index.vue';
|
import DictKeySelector from '@/components/system/dict-key/selector/index.vue';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user