summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhanyuxia <[email protected]>2024-11-08 13:38:00 +0800
committerhanyuxia <[email protected]>2024-11-08 13:38:00 +0800
commitd61a71c4dba78544e2818e9b0784f37a6f0f2bc4 (patch)
tree02723e164ef9b19a858ed69eb979dc0c8558750f /src
parente811f7f269da8e80670a975c790d6700a9f6a7e0 (diff)
feat: 1、面包屑 Jobs 可以点击,返回 job 列表页面;2、当 job 状态为结束状态时,不再请求log 和 详情接口;
Diffstat (limited to 'src')
-rw-r--r--src/utils/constants.js8
-rw-r--r--src/views/jobs/index.vue18
-rw-r--r--src/views/jobs/log.vue53
3 files changed, 52 insertions, 27 deletions
diff --git a/src/utils/constants.js b/src/utils/constants.js
index 7da684b..cd5dcbd 100644
--- a/src/utils/constants.js
+++ b/src/utils/constants.js
@@ -141,4 +141,12 @@ export const monthDict = {
'10': 'Oct',
'11': 'Nov',
'12': 'Dec',
+}
+export const jobStatus = {
+ created: 'created',
+ pending: 'pending',
+ running: 'running',
+ passed: 'passed',
+ failed: 'failed',
+ cancel: 'cancel'
} \ No newline at end of file
diff --git a/src/views/jobs/index.vue b/src/views/jobs/index.vue
index be71b33..81575f0 100644
--- a/src/views/jobs/index.vue
+++ b/src/views/jobs/index.vue
@@ -54,27 +54,27 @@
</template>
<template v-else-if="item.prop === 'status'">
<div class="statusWrap">
- <div class="statusTag created" v-if="scope.row.status === 'created'">
+ <div class="statusTag created" v-if="scope.row.status === jobStatus.created">
<i class="asw-icon icon-Created statusIcon"></i>
<span>{{ t('job.created') }}</span>
</div>
- <div class="statusTag danger" v-else-if="scope.row.status === 'pending'">
+ <div class="statusTag danger" v-else-if="scope.row.status === jobStatus.pending">
<i class="asw-icon icon-Pending statusIcon"></i>
<span>{{ t('job.pending') }}</span>
</div>
- <div class="statusTag" v-else-if="scope.row.status === 'running'">
+ <div class="statusTag" v-else-if="scope.row.status === jobStatus.running">
<i class="asw-icon icon-Running statusIcon"></i>
<span>{{ t('job.running') }}</span>
</div>
- <div class="statusTag success" v-else-if="scope.row.status === 'passed'">
+ <div class="statusTag success" v-else-if="scope.row.status === jobStatus.passed">
<i class="asw-icon icon-Passed statusIcon"></i>
<span>{{ t('job.passed') }}</span>
</div>
- <div class="statusTag error" v-else-if="scope.row.status === 'failed'">
+ <div class="statusTag error" v-else-if="scope.row.status === jobStatus.failed">
<i class="asw-icon icon-Failed statusIcon"></i>
<span>{{ t('job.failed') }}</span>
</div>
- <div class="statusTag cancel" v-else-if="scope.row.status === 'cancel'">
+ <div class="statusTag cancel" v-else-if="scope.row.status === jobStatus.cancel">
<i class="asw-icon icon-Canceled statusIcon"></i>
<span>{{ t('job.canceled') }}</span>
</div>
@@ -123,13 +123,13 @@
<template #dropdown>
<el-dropdown-menu>
<div v-has="'job_cancel'">
- <el-dropdown-item key="cancel" @click="tableCancel(scope.row)" :disabled="scope.row.status === 'passed' || scope.row.status === 'failed' || scope.row.status === 'cancel'">
+ <el-dropdown-item key="cancel" @click="tableCancel(scope.row)" :disabled="scope.row.status === jobStatus.passed || scope.row.status === jobStatus.failed || scope.row.status === jobStatus.cancel">
<i class="asw-icon icon-cancel cp"></i>
{{ t('job.cancel') }}
</el-dropdown-item>
</div>
<div v-has="'job_retry'">
- <el-dropdown-item key="retry" @click="tableRetry(scope.row)" :disabled="scope.row.status === 'created' || scope.row.status === 'pending' || scope.row.status === 'running' || submitting">
+ <el-dropdown-item key="retry" @click="tableRetry(scope.row)" :disabled="scope.row.status === jobStatus.created || scope.row.status === jobStatus.pending || scope.row.status === jobStatus.running || submitting">
<i class="asw-icon icon-retry cp"></i>
{{t('job.retry')}}
</el-dropdown-item>
@@ -152,7 +152,7 @@
import { toThousands } from '@/utils';
import { useSystemStore } from '@/store/index';
import { useTable } from '@/hooks/useTable';
- import { monthDict } from '@/utils/constants';
+ import { monthDict, jobStatus } from '@/utils/constants';
import { get } from 'lodash';
import { useRouter } from 'vue-router';
import moment from 'moment-timezone';
diff --git a/src/views/jobs/log.vue b/src/views/jobs/log.vue
index 464da02..defa89e 100644
--- a/src/views/jobs/log.vue
+++ b/src/views/jobs/log.vue
@@ -2,34 +2,34 @@
<div id="jobs" class="log-detail">
<div class="log-detail__left">
<div class="detail-header">
- {{ t('overall.jobs') }} / {{ jobInfo.id }}
+ <span @click="jumpBack" class="hover-primary">{{ t('overall.jobs') }}</span> / {{ jobInfo.id }}
</div>
<div class="detail-log__container">
<div class="top-bar">
<div class="log-title">{{ jobInfo.id }}</div>
<div class="log-title__start">
<div class="statusWrap">
- <div class="statusTag created" v-if="jobInfo.status === 'created'">
+ <div class="statusTag created" v-if="jobInfo.status === jobStatus.created">
<i class="asw-icon icon-Created statusIcon"></i>
<span>{{ t('job.created') }}</span>
</div>
- <div class="statusTag danger" v-else-if="jobInfo.status === 'pending'">
+ <div class="statusTag danger" v-else-if="jobInfo.status === jobStatus.pending">
<i class="asw-icon icon-Pending statusIcon"></i>
<span>{{ t('job.pending') }}</span>
</div>
- <div class="statusTag" v-else-if="jobInfo.status === 'running'">
+ <div class="statusTag" v-else-if="jobInfo.status === jobStatus.running">
<i class="asw-icon icon-Running statusIcon"></i>
<span>{{ t('job.running') }}</span>
</div>
- <div class="statusTag success" v-else-if="jobInfo.status === 'passed'">
+ <div class="statusTag success" v-else-if="jobInfo.status === jobStatus.passed">
<i class="asw-icon icon-Passed statusIcon"></i>
<span>{{ t('job.passed') }}</span>
</div>
- <div class="statusTag error" v-else-if="jobInfo.status === 'failed'">
+ <div class="statusTag error" v-else-if="jobInfo.status === jobStatus.failed">
<i class="asw-icon icon-Failed statusIcon"></i>
<span>{{ t('job.failed') }}</span>
</div>
- <div class="statusTag cancel" v-else-if="jobInfo.status === 'cancel'">
+ <div class="statusTag cancel" v-else-if="jobInfo.status === jobStatus.cancel">
<i class="asw-icon icon-Canceled statusIcon"></i>
<span>{{ t('job.canceled') }}</span>
</div>
@@ -50,8 +50,8 @@
</span>
</div>
</div>
- <div class="job-not-started" v-if="jobInfo.status === 'cancel' || jobInfo.status === 'created'">
- <template v-if="jobInfo.status === 'cancel'">
+ <div class="job-not-started" v-if="jobInfo.status === jobStatus.cancel || jobInfo.status === jobStatus.created">
+ <template v-if="jobInfo.status === jobStatus.cancel">
<div class="status-icon">
<svg>
<use xlink:href="#icon-Canceled1"></use>
@@ -64,7 +64,7 @@
</el-button>
</div>
</template>
- <template v-else-if="jobInfo.status === 'created'">
+ <template v-else-if="jobInfo.status === jobStatus.created">
<div class="status-icon">
<svg>
<use xlink:href="#icon-source-document_15399136"></use>
@@ -78,7 +78,7 @@
</div>
</template>
</div>
- <div class="log-content__container" v-else-if="jobInfo.status === 'pending' || jobInfo.status === 'running' || jobInfo.status === 'passed'|| jobInfo.status === 'failed'">
+ <div class="log-content__container" v-else-if="jobInfo.status === jobStatus.pending || jobInfo.status === jobStatus.running || jobInfo.status === jobStatus.passed|| jobInfo.status === jobStatus.failed">
<div class="log-content" id="logScroll" v-html="logShowContent" style="white-space: pre-wrap;">
</div>
</div>
@@ -120,7 +120,7 @@
import { jobLogApi, jobDetailApi, jobCancelApi, jobAddApi} from '@/axios/api';
import { ElMessage } from 'element-plus';
import { useSystemStore } from '@/store/index';
- import { monthDict } from '@/utils/constants';
+ import { monthDict, jobStatus } from '@/utils/constants';
import { get } from 'lodash';
import { useRouter } from 'vue-router';
import moment from 'moment-timezone';
@@ -145,7 +145,7 @@
let logShowContent = ref('');
let offset = ref(0);
let timer = ref(null);
- const getLogData = async () => {
+ const getLogData = async (isStop) => {
try {
let params = {
offset: offset.value
@@ -158,7 +158,9 @@
let logLineList = logRealContent.value.split("\n");
let indexWidth = logLineList.length.toString().length * 8;
logShowContent.value = logLineList.map((item,index) => {
- return `<div style="color:#99A0BC;margin-right:10px;width:${indexWidth}px;">${index}</div><div style="width:calc(100% - ${indexWidth+10}px);min-width:calc(100% - ${indexWidth+10}px);max-width:calc(100% - ${indexWidth+10}px);">${item}</div>`;
+ if(item) {//避免日志最后一行出现空行
+ return `<div style="color:#99A0BC;margin-right:10px;width:${indexWidth}px;">${index}</div><div style="width:calc(100% - ${indexWidth+10}px);min-width:calc(100% - ${indexWidth+10}px);max-width:calc(100% - ${indexWidth+10}px);">${item}</div>`;
+ }
}).join('\n')
nextTick(() => {
try {
@@ -171,7 +173,13 @@
} else {
ElMessage.error(res.msg || res.error);
}
- timer.value = setTimeout(getLogData,3000);
+ if(!isStop) {
+ if(jobInfo.status === jobStatus.running) {
+ timer.value = setTimeout(getLogData,3000);
+ } else if(jobInfo.status === jobStatus.passed || jobInfo.status === jobStatus.failed) {
+ timer.value = setTimeout(getLogData,60000,true);//passed或者failed状态需要再执行一次后停止,否则可能缺少日志,最后一次读取,为passed或者failed状态后1分钟
+ }
+ }
} catch (error) {console.error(error)}
};
@@ -225,8 +233,10 @@
jobInfo.duration = result;
}
//获取日志信息
- if(jobInfo.status !== 'cancel' && jobInfo.status !== 'created') {
- getLogData();
+ if(jobInfo.status === jobStatus.running || jobInfo.status === jobStatus.passed || jobInfo.status === jobStatus.failed) {
+ if(!timer.value) {//避免多次启动日志查询
+ getLogData();
+ }
} else {
if(timer.value) {
clearTimeout(timer.value);
@@ -237,7 +247,14 @@
} else {
ElMessage.error(res.msg || res.error);
}
- timerJob.value = setTimeout(getJobData,3000);
+ if(jobInfo.status === jobStatus.created || jobInfo.status === jobStatus.pending || jobInfo.status === jobStatus.running) {
+ timerJob.value = setTimeout(getJobData,3000);
+ } else {
+ if(timerJob.value) {
+ clearTimeout(timerJob.value);
+ timerJob.value = null;
+ }
+ }
} catch (error) {}
};