diff --git a/agent/app/api/v1/entry.go b/agent/app/api/v1/entry.go index d952afc47..7bdaa2801 100644 --- a/agent/app/api/v1/entry.go +++ b/agent/app/api/v1/entry.go @@ -66,4 +66,5 @@ var ( favoriteService = service.NewIFavoriteService() websiteCAService = service.NewIWebsiteCAService() + taskService = service.NewITaskService() ) diff --git a/agent/app/api/v1/task.go b/agent/app/api/v1/task.go new file mode 100644 index 000000000..741d01a3c --- /dev/null +++ b/agent/app/api/v1/task.go @@ -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, + }) +} diff --git a/agent/app/dto/logs.go b/agent/app/dto/logs.go index 8831801db..21c569f3b 100644 --- a/agent/app/dto/logs.go +++ b/agent/app/dto/logs.go @@ -1,6 +1,7 @@ package dto import ( + "github.com/1Panel-dev/1Panel/agent/app/model" "time" ) @@ -48,3 +49,13 @@ type LoginLog struct { type CleanLog struct { 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 +} diff --git a/agent/app/repo/task.go b/agent/app/repo/task.go index fb51aca5a..957aaf3fa 100644 --- a/agent/app/repo/task.go +++ b/agent/app/repo/task.go @@ -18,6 +18,7 @@ type ITaskRepo interface { WithByID(id string) DBOption WithType(taskType string) DBOption WithResourceID(id uint) DBOption + WithStatus(status string) DBOption } 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 { return func(g *gorm.DB) *gorm.DB { return g.Where("resource_id = ?", id) diff --git a/agent/app/service/task.go b/agent/app/service/task.go new file mode 100644 index 000000000..b4948801e --- /dev/null +++ b/agent/app/service/task.go @@ -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 +} diff --git a/agent/router/ro_log.go b/agent/router/ro_log.go index 8b60ebf56..9849782c9 100644 --- a/agent/router/ro_log.go +++ b/agent/router/ro_log.go @@ -14,5 +14,6 @@ func (s *LogRouter) InitRouter(Router *gin.RouterGroup) { { operationRouter.GET("/system/files", baseApi.GetSystemFiles) operationRouter.POST("/system", baseApi.GetSystemLogs) + operationRouter.POST("/tasks/search", baseApi.PageTasks) } } diff --git a/frontend/src/api/interface/log.ts b/frontend/src/api/interface/log.ts index 7bdc367bb..2084fa7e2 100644 --- a/frontend/src/api/interface/log.ts +++ b/frontend/src/api/interface/log.ts @@ -40,4 +40,23 @@ export namespace Log { export interface CleanLog { 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; + } } diff --git a/frontend/src/api/modules/log.ts b/frontend/src/api/modules/log.ts index 590d223d2..6dd8c2cba 100644 --- a/frontend/src/api/modules/log.ts +++ b/frontend/src/api/modules/log.ts @@ -20,3 +20,7 @@ export const getSystemLogs = (name: string) => { export const cleanLogs = (param: Log.CleanLog) => { return http.post(`/logs/clean`, param); }; + +export const searchTasks = (req: Log.SearchTaskReq) => { + return http.post>(`/logs/tasks/search`, req); +}; diff --git a/frontend/src/components/compose-log/index.vue b/frontend/src/components/compose-log/index.vue index e6bb282af..5d4c82b3d 100644 --- a/frontend/src/components/compose-log/index.vue +++ b/frontend/src/components/compose-log/index.vue @@ -131,7 +131,7 @@ const searchLogs = async () => { const protocol = href.split('//')[0] === 'http:' ? 'ws' : 'wss'; const host = href.split('//')[1].split('/')[0]; 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) => { logInfo.value += event.data; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index a80b32188..61ec05bc5 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1155,6 +1155,9 @@ const message = { websiteLog: 'Website Logs', runLog: 'Run Log', errLog: 'Err Log', + task: 'Task Log', + taskName: 'Task Name', + taskRunning: 'Running', }, file: { dir: 'Folder', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 9432208a6..7c5b991d1 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1093,6 +1093,9 @@ const message = { websiteLog: '網站日誌', runLog: '運行日誌', errLog: '錯誤日誌', + task: '任務日誌', + taskName: '任務名稱', + taskRunning: '運行中', }, file: { dir: '文件夾', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index eb1a16205..daecd2620 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1095,6 +1095,9 @@ const message = { websiteLog: '网站日志', runLog: '运行日志', errLog: '错误日志', + task: '任务日志', + taskName: '任务名称', + taskRunning: '运行中', }, file: { dir: '文件夹', diff --git a/frontend/src/routers/modules/log.ts b/frontend/src/routers/modules/log.ts index 013a97ace..f7f30a367 100644 --- a/frontend/src/routers/modules/log.ts +++ b/frontend/src/routers/modules/log.ts @@ -67,6 +67,16 @@ const logsRouter = { requiresAuth: false, }, }, + { + path: 'task', + name: 'Task', + component: () => import('@/views/log/task/index.vue'), + hidden: true, + meta: { + activeMenu: '/logs', + requiresAuth: false, + }, + }, ], }, ], diff --git a/frontend/src/utils/xpack.ts b/frontend/src/utils/xpack.ts index 9ad6d7ceb..99d2ee5ff 100644 --- a/frontend/src/utils/xpack.ts +++ b/frontend/src/utils/xpack.ts @@ -53,7 +53,7 @@ const loadDataFromDB = async () => { export async function loadProductProFromDB() { const res = await getLicenseStatus(); - if (!res.data) { + if (!res || !res.data) { resetXSetting(); globalStore.isProductPro = false; } else { diff --git a/frontend/src/views/home/index.vue b/frontend/src/views/home/index.vue index 3e71bdedb..f56dffcb3 100644 --- a/frontend/src/views/home/index.vue +++ b/frontend/src/views/home/index.vue @@ -546,7 +546,7 @@ const hideEntrance = () => { const loadUpgradeStatus = async () => { 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; } else { globalStore.hasNewVersion = false; diff --git a/frontend/src/views/log/login/index.vue b/frontend/src/views/log/login/index.vue index f134c3adb..9cd5f1435 100644 --- a/frontend/src/views/log/login/index.vue +++ b/frontend/src/views/log/login/index.vue @@ -2,15 +2,7 @@