mirror of https://github.com/1Panel-dev/1Panel
feat: 增加任务日志列表 (#5999)
parent
636e149b29
commit
bdece10868
|
@ -66,4 +66,5 @@ var (
|
||||||
favoriteService = service.NewIFavoriteService()
|
favoriteService = service.NewIFavoriteService()
|
||||||
|
|
||||||
websiteCAService = service.NewIWebsiteCAService()
|
websiteCAService = service.NewIWebsiteCAService()
|
||||||
|
taskService = service.NewITaskService()
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/api/v1/helper"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags TaskLog
|
||||||
|
// @Summary Page task logs
|
||||||
|
// @Description 获取任务日志列表
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.SearchTaskLogReq true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /logs/tasks/search [post]
|
||||||
|
func (b *BaseApi) PageTasks(c *gin.Context) {
|
||||||
|
var req dto.SearchTaskLogReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, list, err := taskService.Page(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Items: list,
|
||||||
|
Total: total,
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,3 +49,13 @@ type LoginLog struct {
|
||||||
type CleanLog struct {
|
type CleanLog struct {
|
||||||
LogType string `json:"logType" validate:"required,oneof=login operation"`
|
LogType string `json:"logType" validate:"required,oneof=login operation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchTaskLogReq struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
PageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type TaskDTO struct {
|
||||||
|
model.Task
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ type ITaskRepo interface {
|
||||||
WithByID(id string) DBOption
|
WithByID(id string) DBOption
|
||||||
WithType(taskType string) DBOption
|
WithType(taskType string) DBOption
|
||||||
WithResourceID(id uint) DBOption
|
WithResourceID(id uint) DBOption
|
||||||
|
WithStatus(status string) DBOption
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewITaskRepo() ITaskRepo {
|
func NewITaskRepo() ITaskRepo {
|
||||||
|
@ -36,6 +37,12 @@ func (t TaskRepo) WithType(taskType string) DBOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t TaskRepo) WithStatus(status string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("status = ?", status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t TaskRepo) WithResourceID(id uint) DBOption {
|
func (t TaskRepo) WithResourceID(id uint) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("resource_id = ?", id)
|
return g.Where("resource_id = ?", id)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TaskLogService struct{}
|
||||||
|
|
||||||
|
type ITaskLogService interface {
|
||||||
|
Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewITaskService() ITaskLogService {
|
||||||
|
return &TaskLogService{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *TaskLogService) Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, error) {
|
||||||
|
opts := []repo.DBOption{
|
||||||
|
commonRepo.WithOrderBy("created_at desc"),
|
||||||
|
}
|
||||||
|
if req.Status != "" {
|
||||||
|
opts = append(opts, taskRepo.WithStatus(req.Status))
|
||||||
|
}
|
||||||
|
if req.Type != "" {
|
||||||
|
opts = append(opts, taskRepo.WithType(req.Type))
|
||||||
|
}
|
||||||
|
|
||||||
|
total, tasks, err := taskRepo.Page(
|
||||||
|
req.Page,
|
||||||
|
req.PageSize,
|
||||||
|
opts...,
|
||||||
|
)
|
||||||
|
var items []dto.TaskDTO
|
||||||
|
for _, t := range tasks {
|
||||||
|
item := dto.TaskDTO{
|
||||||
|
Task: t,
|
||||||
|
}
|
||||||
|
items = append(items, item)
|
||||||
|
}
|
||||||
|
return total, items, err
|
||||||
|
}
|
|
@ -14,5 +14,6 @@ func (s *LogRouter) InitRouter(Router *gin.RouterGroup) {
|
||||||
{
|
{
|
||||||
operationRouter.GET("/system/files", baseApi.GetSystemFiles)
|
operationRouter.GET("/system/files", baseApi.GetSystemFiles)
|
||||||
operationRouter.POST("/system", baseApi.GetSystemLogs)
|
operationRouter.POST("/system", baseApi.GetSystemLogs)
|
||||||
|
operationRouter.POST("/tasks/search", baseApi.PageTasks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,4 +40,23 @@ export namespace Log {
|
||||||
export interface CleanLog {
|
export interface CleanLog {
|
||||||
logType: string;
|
logType: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SearchTaskReq extends ReqPage {
|
||||||
|
type: string;
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Task {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
logFile: string;
|
||||||
|
status: string;
|
||||||
|
errorMsg: string;
|
||||||
|
operationLogID: number;
|
||||||
|
resourceID: number;
|
||||||
|
currentStep: string;
|
||||||
|
endAt: Date;
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,3 +20,7 @@ export const getSystemLogs = (name: string) => {
|
||||||
export const cleanLogs = (param: Log.CleanLog) => {
|
export const cleanLogs = (param: Log.CleanLog) => {
|
||||||
return http.post(`/logs/clean`, param);
|
return http.post(`/logs/clean`, param);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const searchTasks = (req: Log.SearchTaskReq) => {
|
||||||
|
return http.post<ResPage<Log.Task>>(`/logs/tasks/search`, req);
|
||||||
|
};
|
||||||
|
|
|
@ -131,7 +131,7 @@ const searchLogs = async () => {
|
||||||
const protocol = href.split('//')[0] === 'http:' ? 'ws' : 'wss';
|
const protocol = href.split('//')[0] === 'http:' ? 'ws' : 'wss';
|
||||||
const host = href.split('//')[1].split('/')[0];
|
const host = href.split('//')[1].split('/')[0];
|
||||||
terminalSocket.value = new WebSocket(
|
terminalSocket.value = new WebSocket(
|
||||||
`${protocol}://${host}/api/v1/containers/compose/search/log?compose=${logSearch.compose}&since=${logSearch.mode}&tail=${logSearch.tail}&follow=${logSearch.isWatch}`,
|
`${protocol}://${host}/api/v2/containers/compose/search/log?compose=${logSearch.compose}&since=${logSearch.mode}&tail=${logSearch.tail}&follow=${logSearch.isWatch}`,
|
||||||
);
|
);
|
||||||
terminalSocket.value.onmessage = (event) => {
|
terminalSocket.value.onmessage = (event) => {
|
||||||
logInfo.value += event.data;
|
logInfo.value += event.data;
|
||||||
|
|
|
@ -1155,6 +1155,9 @@ const message = {
|
||||||
websiteLog: 'Website Logs',
|
websiteLog: 'Website Logs',
|
||||||
runLog: 'Run Log',
|
runLog: 'Run Log',
|
||||||
errLog: 'Err Log',
|
errLog: 'Err Log',
|
||||||
|
task: 'Task Log',
|
||||||
|
taskName: 'Task Name',
|
||||||
|
taskRunning: 'Running',
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
dir: 'Folder',
|
dir: 'Folder',
|
||||||
|
|
|
@ -1093,6 +1093,9 @@ const message = {
|
||||||
websiteLog: '網站日誌',
|
websiteLog: '網站日誌',
|
||||||
runLog: '運行日誌',
|
runLog: '運行日誌',
|
||||||
errLog: '錯誤日誌',
|
errLog: '錯誤日誌',
|
||||||
|
task: '任務日誌',
|
||||||
|
taskName: '任務名稱',
|
||||||
|
taskRunning: '運行中',
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
dir: '文件夾',
|
dir: '文件夾',
|
||||||
|
|
|
@ -1095,6 +1095,9 @@ const message = {
|
||||||
websiteLog: '网站日志',
|
websiteLog: '网站日志',
|
||||||
runLog: '运行日志',
|
runLog: '运行日志',
|
||||||
errLog: '错误日志',
|
errLog: '错误日志',
|
||||||
|
task: '任务日志',
|
||||||
|
taskName: '任务名称',
|
||||||
|
taskRunning: '运行中',
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
dir: '文件夹',
|
dir: '文件夹',
|
||||||
|
|
|
@ -67,6 +67,16 @@ const logsRouter = {
|
||||||
requiresAuth: false,
|
requiresAuth: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'task',
|
||||||
|
name: 'Task',
|
||||||
|
component: () => import('@/views/log/task/index.vue'),
|
||||||
|
hidden: true,
|
||||||
|
meta: {
|
||||||
|
activeMenu: '/logs',
|
||||||
|
requiresAuth: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -53,7 +53,7 @@ const loadDataFromDB = async () => {
|
||||||
|
|
||||||
export async function loadProductProFromDB() {
|
export async function loadProductProFromDB() {
|
||||||
const res = await getLicenseStatus();
|
const res = await getLicenseStatus();
|
||||||
if (!res.data) {
|
if (!res || !res.data) {
|
||||||
resetXSetting();
|
resetXSetting();
|
||||||
globalStore.isProductPro = false;
|
globalStore.isProductPro = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -546,7 +546,7 @@ const hideEntrance = () => {
|
||||||
|
|
||||||
const loadUpgradeStatus = async () => {
|
const loadUpgradeStatus = async () => {
|
||||||
const res = await loadUpgradeInfo();
|
const res = await loadUpgradeInfo();
|
||||||
if (res.data.testVersion || res.data.newVersion || res.data.latestVersion) {
|
if (res && (res.data.testVersion || res.data.newVersion || res.data.latestVersion)) {
|
||||||
globalStore.hasNewVersion = true;
|
globalStore.hasNewVersion = true;
|
||||||
} else {
|
} else {
|
||||||
globalStore.hasNewVersion = false;
|
globalStore.hasNewVersion = false;
|
||||||
|
|
|
@ -2,15 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<LayoutContent v-loading="loading" :title="$t('logs.login')">
|
<LayoutContent v-loading="loading" :title="$t('logs.login')">
|
||||||
<template #search>
|
<template #search>
|
||||||
<el-button class="tag-button no-active" @click="onChangeRoute('OperationLog')">
|
<LogRouter current="LoginLog" />
|
||||||
{{ $t('logs.operation') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button class="tag-button" type="primary" @click="onChangeRoute('LoginLog')">
|
|
||||||
{{ $t('logs.login') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button class="tag-button no-active" @click="onChangeRoute('SystemLog')">
|
|
||||||
{{ $t('logs.system') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
<template #leftToolBar>
|
<template #leftToolBar>
|
||||||
<el-button type="primary" plain @click="onClean()">
|
<el-button type="primary" plain @click="onClean()">
|
||||||
|
@ -59,13 +51,12 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||||
|
import LogRouter from '@/views/log/router/index.vue';
|
||||||
import { dateFormat } from '@/utils/util';
|
import { dateFormat } from '@/utils/util';
|
||||||
import { cleanLogs, getLoginLogs } from '@/api/modules/log';
|
import { cleanLogs, getLoginLogs } from '@/api/modules/log';
|
||||||
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const data = ref();
|
const data = ref();
|
||||||
|
@ -98,10 +89,6 @@ const search = async () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeRoute = async (addr: string) => {
|
|
||||||
router.push({ name: addr });
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClean = async () => {
|
const onClean = async () => {
|
||||||
let params = {
|
let params = {
|
||||||
header: i18n.global.t('logs.deleteLogs'),
|
header: i18n.global.t('logs.deleteLogs'),
|
||||||
|
|
|
@ -2,15 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<LayoutContent v-loading="loading" :title="$t('logs.operation')">
|
<LayoutContent v-loading="loading" :title="$t('logs.operation')">
|
||||||
<template #search>
|
<template #search>
|
||||||
<el-button type="primary" class="tag-button" @click="onChangeRoute('OperationLog')">
|
<LogRouter current="OperationLog" />
|
||||||
{{ $t('logs.operation') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button class="tag-button no-active" @click="onChangeRoute('LoginLog')">
|
|
||||||
{{ $t('logs.login') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button class="tag-button no-active" @click="onChangeRoute('SystemLog')">
|
|
||||||
{{ $t('logs.system') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
<template #leftToolBar>
|
<template #leftToolBar>
|
||||||
<el-button type="primary" plain @click="onClean()">
|
<el-button type="primary" plain @click="onClean()">
|
||||||
|
@ -96,14 +88,13 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||||
|
import LogRouter from '@/views/log/router/index.vue';
|
||||||
import { dateFormat } from '@/utils/util';
|
import { dateFormat } from '@/utils/util';
|
||||||
import { cleanLogs, getOperationLogs } from '@/api/modules/log';
|
import { cleanLogs, getOperationLogs } from '@/api/modules/log';
|
||||||
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const data = ref();
|
const data = ref();
|
||||||
|
@ -154,10 +145,6 @@ const onClean = async () => {
|
||||||
confirmDialogRef.value!.acceptParams(params);
|
confirmDialogRef.value!.acceptParams(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeRoute = async (addr: string) => {
|
|
||||||
router.push({ name: addr });
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadDetail = (log: string) => {
|
const loadDetail = (log: string) => {
|
||||||
if (log.indexOf('[enable]') !== -1) {
|
if (log.indexOf('[enable]') !== -1) {
|
||||||
log = log.replace('[enable]', '[' + i18n.global.t('commons.button.enable') + ']');
|
log = log.replace('[enable]', '[' + i18n.global.t('commons.button.enable') + ']');
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
class="tag-button"
|
||||||
|
:class="current != 'OperationLog' ? 'no-active' : ''"
|
||||||
|
:type="current === 'OperationLog' ? 'primary' : ''"
|
||||||
|
@click="onChangeRoute('OperationLog')"
|
||||||
|
>
|
||||||
|
{{ $t('logs.operation') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
class="tag-button"
|
||||||
|
:class="current != 'LoginLog' ? 'no-active' : ''"
|
||||||
|
:type="current === 'LoginLog' ? 'primary' : ''"
|
||||||
|
@click="onChangeRoute('LoginLog')"
|
||||||
|
>
|
||||||
|
{{ $t('logs.login') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
class="tag-button"
|
||||||
|
:class="current != 'SystemLog' ? 'no-active' : ''"
|
||||||
|
:type="current === 'SystemLog' ? 'primary' : ''"
|
||||||
|
@click="onChangeRoute('SystemLog')"
|
||||||
|
>
|
||||||
|
{{ $t('logs.system') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
class="tag-button"
|
||||||
|
:class="current != 'Task' ? 'no-active' : ''"
|
||||||
|
:type="current === 'Task' ? 'primary' : ''"
|
||||||
|
@click="onChangeRoute('Task')"
|
||||||
|
>
|
||||||
|
{{ $t('logs.task') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
current: {
|
||||||
|
type: String,
|
||||||
|
default: 'LoginLog',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const router = useRouter();
|
||||||
|
const onChangeRoute = async (addr: string) => {
|
||||||
|
router.push({ name: addr });
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -2,15 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<LayoutContent v-loading="loading" :title="$t('logs.system')">
|
<LayoutContent v-loading="loading" :title="$t('logs.system')">
|
||||||
<template #search>
|
<template #search>
|
||||||
<el-button class="tag-button no-active" @click="onChangeRoute('OperationLog')">
|
<LogRouter current="SystemLog" />
|
||||||
{{ $t('logs.operation') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button class="tag-button no-active" @click="onChangeRoute('LoginLog')">
|
|
||||||
{{ $t('logs.login') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button class="tag-button" type="primary" @click="onChangeRoute('SystemLog')">
|
|
||||||
{{ $t('logs.system') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
<template #leftToolBar>
|
<template #leftToolBar>
|
||||||
<el-select class="p-w-200 mr-2.5" v-model="logConfig.name" @change="search()">
|
<el-select class="p-w-200 mr-2.5" v-model="logConfig.name" @change="search()">
|
||||||
|
@ -39,12 +31,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, onMounted, reactive, ref } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import { getSystemFiles } from '@/api/modules/log';
|
|
||||||
import LogFile from '@/components/log-file/index.vue';
|
import LogFile from '@/components/log-file/index.vue';
|
||||||
|
import LogRouter from '@/views/log/router/index.vue';
|
||||||
|
import { nextTick, onMounted, reactive, ref } from 'vue';
|
||||||
|
import { getSystemFiles } from '@/api/modules/log';
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const isWatch = ref();
|
const isWatch = ref();
|
||||||
const fileList = ref();
|
const fileList = ref();
|
||||||
|
@ -77,10 +68,6 @@ const search = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeRoute = async (addr: string) => {
|
|
||||||
router.push({ name: addr });
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadFiles();
|
loadFiles();
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<LayoutContent v-loading="loading" :title="$t('logs.task')">
|
||||||
|
<template #search>
|
||||||
|
<LogRouter current="Task" />
|
||||||
|
</template>
|
||||||
|
<template #rightToolBar>
|
||||||
|
<el-select v-model="req.status" @change="search()" clearable class="p-w-200 mr-2.5">
|
||||||
|
<template #prefix>{{ $t('commons.table.status') }}</template>
|
||||||
|
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
||||||
|
<el-option :label="$t('commons.status.success')" value="Success"></el-option>
|
||||||
|
<el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
|
||||||
|
<el-option :label="$t('logs.taskRunning')" value="Running"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<TableSetting @search="search()" />
|
||||||
|
</template>
|
||||||
|
<template #main>
|
||||||
|
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search" :heightDiff="370">
|
||||||
|
<el-table-column :label="$t('logs.taskName')" prop="name" />
|
||||||
|
<el-table-column :label="$t('commons.table.type')" prop="type" />
|
||||||
|
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="row.status === 'Success'">
|
||||||
|
<el-tag type="success">{{ $t('commons.status.success') }}</el-tag>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="dark"
|
||||||
|
:content="row.errorMsg"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<el-tag type="danger">{{ $t('commons.status.failed') }}</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('website.log')" prop="log">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button @click="openTaskLog(row)" link type="primary">
|
||||||
|
{{ $t('website.check') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="createdAt"
|
||||||
|
:label="$t('commons.table.date')"
|
||||||
|
:formatter="dateFormat"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
</ComplexTable>
|
||||||
|
</template>
|
||||||
|
</LayoutContent>
|
||||||
|
<TaskLog ref="taskLogRef" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import LogRouter from '@/views/log/router/index.vue';
|
||||||
|
import { dateFormat } from '@/utils/util';
|
||||||
|
import { searchTasks } from '@/api/modules/log';
|
||||||
|
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||||
|
import { Log } from '@/api/interface/log';
|
||||||
|
import TaskLog from '@/components/task-log/index.vue';
|
||||||
|
|
||||||
|
const loading = ref();
|
||||||
|
const data = ref();
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
cacheSizeKey: 'login-log-page-size',
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
const taskLogRef = ref();
|
||||||
|
const req = reactive({
|
||||||
|
type: '',
|
||||||
|
status: '',
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const search = async () => {
|
||||||
|
req.page = paginationConfig.currentPage;
|
||||||
|
req.pageSize = paginationConfig.pageSize;
|
||||||
|
loading.value = true;
|
||||||
|
await searchTasks(req)
|
||||||
|
.then((res) => {
|
||||||
|
loading.value = false;
|
||||||
|
data.value = res.data.items;
|
||||||
|
paginationConfig.total = res.data.total;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openTaskLog = (row: Log.Task) => {
|
||||||
|
taskLogRef.value.openWithTaskID(row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Reference in New Issue