mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-09 07:00:48 +08:00
feat(task): Add Execution Validation for Tasks (#7559)
This commit is contained in:
parent
42c97f6eeb
commit
e11a0d5766
21 changed files with 73 additions and 204 deletions
|
@ -135,6 +135,7 @@ type TaskReq struct {
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
TaskType string `json:"taskType"`
|
TaskType string `json:"taskType"`
|
||||||
TaskOperate string `json:"taskOperate"`
|
TaskOperate string `json:"taskOperate"`
|
||||||
|
ResourceID uint `json:"resourceID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileExistReq struct {
|
type FileExistReq struct {
|
||||||
|
|
5
agent/app/repo/entry.go
Normal file
5
agent/app/repo/entry.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package repo
|
||||||
|
|
||||||
|
var (
|
||||||
|
commonRepo = NewCommonRepo()
|
||||||
|
)
|
|
@ -18,6 +18,7 @@ type ITaskRepo interface {
|
||||||
GetFirst(opts ...DBOption) (model.Task, error)
|
GetFirst(opts ...DBOption) (model.Task, error)
|
||||||
Page(page, size int, opts ...DBOption) (int64, []model.Task, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.Task, error)
|
||||||
Update(ctx context.Context, task *model.Task) error
|
Update(ctx context.Context, task *model.Task) error
|
||||||
|
UpdateRunningTaskToFailed() error
|
||||||
|
|
||||||
WithByID(id string) DBOption
|
WithByID(id string) DBOption
|
||||||
WithResourceID(id uint) DBOption
|
WithResourceID(id uint) DBOption
|
||||||
|
@ -90,3 +91,7 @@ func (t TaskRepo) Page(page, size int, opts ...DBOption) (int64, []model.Task, e
|
||||||
func (t TaskRepo) Update(ctx context.Context, task *model.Task) error {
|
func (t TaskRepo) Update(ctx context.Context, task *model.Task) error {
|
||||||
return getTaskTx(ctx).Save(&task).Error
|
return getTaskTx(ctx).Save(&task).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t TaskRepo) UpdateRunningTaskToFailed() error {
|
||||||
|
return getTaskDb(commonRepo.WithByStatus(constant.StatusExecuting)).Model(&model.Task{}).Updates(map[string]interface{}{"status": constant.StatusFailed, "error_msg": "1Panel restart causes failure"}).Error
|
||||||
|
}
|
||||||
|
|
|
@ -170,6 +170,10 @@ func (n NginxService) Build(req request.NginxBuildReq) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
taskName := task.GetTaskName(nginxInstall.Name, task.TaskBuild, task.TaskScopeApp)
|
||||||
|
if err = task.CheckTaskIsExecuting(taskName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
buildPath := path.Join(nginxInstall.GetPath(), "build")
|
buildPath := path.Join(nginxInstall.GetPath(), "build")
|
||||||
if !fileOp.Stat(buildPath) {
|
if !fileOp.Stat(buildPath) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ type TaskLogService struct{}
|
||||||
|
|
||||||
type ITaskLogService interface {
|
type ITaskLogService interface {
|
||||||
Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, error)
|
Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, error)
|
||||||
|
SyncForRestart() error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewITaskService() ITaskLogService {
|
func NewITaskService() ITaskLogService {
|
||||||
|
@ -40,3 +41,7 @@ func (u *TaskLogService) Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, e
|
||||||
}
|
}
|
||||||
return total, items, err
|
return total, items, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *TaskLogService) SyncForRestart() error {
|
||||||
|
return taskRepo.UpdateRunningTaskToFailed()
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package task
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -75,11 +76,6 @@ const (
|
||||||
TaskScopeRuntimeExtension = "RuntimeExtension"
|
TaskScopeRuntimeExtension = "RuntimeExtension"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
TaskSuccess = "Success"
|
|
||||||
TaskFailed = "Failed"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetTaskName(resourceName, operate, scope string) string {
|
func GetTaskName(resourceName, operate, scope string) string {
|
||||||
return fmt.Sprintf("%s%s [%s]", i18n.GetMsgByKey(operate), i18n.GetMsgByKey(scope), resourceName)
|
return fmt.Sprintf("%s%s [%s]", i18n.GetMsgByKey(operate), i18n.GetMsgByKey(scope), resourceName)
|
||||||
}
|
}
|
||||||
|
@ -88,6 +84,16 @@ func NewTaskWithOps(resourceName, operate, scope, taskID string, resourceID uint
|
||||||
return NewTask(GetTaskName(resourceName, operate, scope), operate, scope, taskID, resourceID)
|
return NewTask(GetTaskName(resourceName, operate, scope), operate, scope, taskID, resourceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckTaskIsExecuting(name string) error {
|
||||||
|
taskRepo := repo.NewITaskRepo()
|
||||||
|
commonRepo := repo.NewCommonRepo()
|
||||||
|
task, _ := taskRepo.GetFirst(commonRepo.WithByStatus(constant.StatusExecuting), commonRepo.WithByName(name))
|
||||||
|
if task.ID != "" {
|
||||||
|
return buserr.New("TaskIsExecuting")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, error) {
|
func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, error) {
|
||||||
if taskID == "" {
|
if taskID == "" {
|
||||||
taskID = uuid.New().String()
|
taskID = uuid.New().String()
|
||||||
|
@ -109,7 +115,7 @@ func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, e
|
||||||
Name: name,
|
Name: name,
|
||||||
Type: taskScope,
|
Type: taskScope,
|
||||||
LogFile: logPath,
|
LogFile: logPath,
|
||||||
Status: constant.StatusRunning,
|
Status: constant.StatusExecuting,
|
||||||
ResourceID: resourceID,
|
ResourceID: resourceID,
|
||||||
Operate: operate,
|
Operate: operate,
|
||||||
}
|
}
|
||||||
|
@ -209,7 +215,7 @@ func (t *Task) Execute() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t.Task.Status == constant.Running {
|
if t.Task.Status == constant.StatusExecuting {
|
||||||
t.Task.Status = constant.StatusSuccess
|
t.Task.Status = constant.StatusSuccess
|
||||||
t.Log(i18n.GetWithName("TaskSuccess", t.Name))
|
t.Log(i18n.GetWithName("TaskSuccess", t.Name))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,6 +11,7 @@ const (
|
||||||
StatusDisable = "Disable"
|
StatusDisable = "Disable"
|
||||||
StatusNone = "None"
|
StatusNone = "None"
|
||||||
StatusDeleted = "Deleted"
|
StatusDeleted = "Deleted"
|
||||||
|
StatusExecuting = "Executing"
|
||||||
|
|
||||||
OrderDesc = "descending"
|
OrderDesc = "descending"
|
||||||
OrderAsc = "ascending"
|
OrderAsc = "ascending"
|
||||||
|
|
|
@ -291,6 +291,7 @@ TaskSync: "Sync"
|
||||||
LocalApp: "Local App"
|
LocalApp: "Local App"
|
||||||
SubTask: "Subtask"
|
SubTask: "Subtask"
|
||||||
RuntimeExtension: "Runtime Extension"
|
RuntimeExtension: "Runtime Extension"
|
||||||
|
TaskIsExecuting: "Task is executing"
|
||||||
|
|
||||||
# task - snapshot
|
# task - snapshot
|
||||||
Snapshot: "Snapshot"
|
Snapshot: "Snapshot"
|
||||||
|
|
|
@ -292,7 +292,7 @@ TaskSync: "同步"
|
||||||
LocalApp: "本地應用"
|
LocalApp: "本地應用"
|
||||||
SubTask: "子任務"
|
SubTask: "子任務"
|
||||||
RuntimeExtension: "運行環境擴展"
|
RuntimeExtension: "運行環境擴展"
|
||||||
|
TaskIsExecuting: "任務正在執行中"
|
||||||
|
|
||||||
# task - snapshot
|
# task - snapshot
|
||||||
Snapshot: "快照"
|
Snapshot: "快照"
|
||||||
|
|
|
@ -292,6 +292,7 @@ TaskSync: "同步"
|
||||||
LocalApp: "本地应用"
|
LocalApp: "本地应用"
|
||||||
SubTask: "子任务"
|
SubTask: "子任务"
|
||||||
RuntimeExtension: "运行环境扩展"
|
RuntimeExtension: "运行环境扩展"
|
||||||
|
TaskIsExecuting: "任务正在运行"
|
||||||
|
|
||||||
# task - snapshot
|
# task - snapshot
|
||||||
Snapshot: "快照"
|
Snapshot: "快照"
|
||||||
|
|
|
@ -11,6 +11,7 @@ func Init() {
|
||||||
go syncInstalledApp()
|
go syncInstalledApp()
|
||||||
go syncRuntime()
|
go syncRuntime()
|
||||||
go syncSSL()
|
go syncSSL()
|
||||||
|
go syncTask()
|
||||||
}
|
}
|
||||||
|
|
||||||
func syncApp() {
|
func syncApp() {
|
||||||
|
@ -38,3 +39,9 @@ func syncSSL() {
|
||||||
global.LOG.Errorf("sync ssl status error : %s", err.Error())
|
global.LOG.Errorf("sync ssl status error : %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func syncTask() {
|
||||||
|
if err := service.NewITaskService().SyncForRestart(); err != nil {
|
||||||
|
global.LOG.Errorf("sync task status error : %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, e
|
||||||
Name: name,
|
Name: name,
|
||||||
Type: taskScope,
|
Type: taskScope,
|
||||||
LogFile: logPath,
|
LogFile: logPath,
|
||||||
Status: constant.StatusRunning,
|
Status: constant.StatusExecuting,
|
||||||
ResourceID: resourceID,
|
ResourceID: resourceID,
|
||||||
Operate: operate,
|
Operate: operate,
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ func (t *Task) Execute() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t.Task.Status == constant.StatusRunning {
|
if t.Task.Status == constant.StatusExecuting {
|
||||||
t.Task.Status = constant.StatusSuccess
|
t.Task.Status = constant.StatusSuccess
|
||||||
t.Log(i18n.GetWithName("TaskSuccess", t.Name))
|
t.Log(i18n.GetWithName("TaskSuccess", t.Name))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,7 @@ const (
|
||||||
StatusExceptional = "Exceptional"
|
StatusExceptional = "Exceptional"
|
||||||
StatusRetrying = "Retrying"
|
StatusRetrying = "Retrying"
|
||||||
StatusLost = "Lost"
|
StatusLost = "Lost"
|
||||||
|
StatusExecuting = "Executing"
|
||||||
|
|
||||||
StatusEnable = "Enable"
|
StatusEnable = "Enable"
|
||||||
StatusDisable = "Disable"
|
StatusDisable = "Disable"
|
||||||
|
|
|
@ -175,6 +175,9 @@ export namespace File {
|
||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
taskID?: string;
|
taskID?: string;
|
||||||
|
taskType?: string;
|
||||||
|
taskOperate?: string;
|
||||||
|
resourceID?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Favorite extends CommonModel {
|
export interface Favorite extends CommonModel {
|
||||||
|
|
|
@ -34,6 +34,7 @@ interface LogProps {
|
||||||
type: string;
|
type: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
tail?: boolean;
|
tail?: boolean;
|
||||||
|
taskID?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -72,6 +73,7 @@ const stopSignals = [
|
||||||
'image pull successful!',
|
'image pull successful!',
|
||||||
'image push failed!',
|
'image push failed!',
|
||||||
'image push successful!',
|
'image push successful!',
|
||||||
|
'[TASK-END]',
|
||||||
];
|
];
|
||||||
const emit = defineEmits(['update:loading', 'update:hasContent', 'update:isReading']);
|
const emit = defineEmits(['update:loading', 'update:hasContent', 'update:isReading']);
|
||||||
const tailLog = ref(false);
|
const tailLog = ref(false);
|
||||||
|
@ -83,6 +85,7 @@ const readReq = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 500,
|
pageSize: 500,
|
||||||
latest: false,
|
latest: false,
|
||||||
|
taskID: '',
|
||||||
});
|
});
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const end = ref(false);
|
const end = ref(false);
|
||||||
|
@ -158,6 +161,7 @@ const getContent = async (pre: boolean) => {
|
||||||
readReq.id = props.config.id;
|
readReq.id = props.config.id;
|
||||||
readReq.type = props.config.type;
|
readReq.type = props.config.type;
|
||||||
readReq.name = props.config.name;
|
readReq.name = props.config.name;
|
||||||
|
readReq.taskID = props.config.taskID;
|
||||||
if (readReq.page < 1) {
|
if (readReq.page < 1) {
|
||||||
readReq.page = 1;
|
readReq.page = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ const getType = (status: string) => {
|
||||||
case 'done':
|
case 'done':
|
||||||
case 'healthy':
|
case 'healthy':
|
||||||
case 'used':
|
case 'used':
|
||||||
|
case 'executing':
|
||||||
return 'success';
|
return 'success';
|
||||||
case 'stopped':
|
case 'stopped':
|
||||||
case 'exceptional':
|
case 'exceptional':
|
||||||
|
@ -80,6 +81,7 @@ const loadingStatus = [
|
||||||
'packing',
|
'packing',
|
||||||
'sending',
|
'sending',
|
||||||
'waiting',
|
'waiting',
|
||||||
|
'executing',
|
||||||
];
|
];
|
||||||
|
|
||||||
const loadingIcon = (status: string): boolean => {
|
const loadingIcon = (status: string): boolean => {
|
||||||
|
|
|
@ -9,15 +9,12 @@
|
||||||
:width="width"
|
:width="width"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<highlightjs class="editor-main" ref="editorRef" :autodetect="false" :code="content"></highlightjs>
|
<LogFile :config="config"></LogFile>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onUnmounted, reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { ReadByLine } from '@/api/modules/files';
|
|
||||||
|
|
||||||
const editorRef = ref();
|
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
showClose: {
|
showClose: {
|
||||||
|
@ -30,207 +27,30 @@ defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = ref({
|
const config = reactive({
|
||||||
enable: false,
|
|
||||||
content: '',
|
|
||||||
path: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
let timer: NodeJS.Timer | null = null;
|
|
||||||
const tailLog = ref(false);
|
|
||||||
const content = ref('');
|
|
||||||
const end = ref(false);
|
|
||||||
const lastContent = ref('');
|
|
||||||
const scrollerElement = ref<HTMLElement | null>(null);
|
|
||||||
const minPage = ref(1);
|
|
||||||
const maxPage = ref(1);
|
|
||||||
const open = ref(false);
|
|
||||||
const em = defineEmits(['close']);
|
|
||||||
|
|
||||||
const readReq = reactive({
|
|
||||||
taskID: '',
|
taskID: '',
|
||||||
type: 'task',
|
type: 'task',
|
||||||
page: 1,
|
|
||||||
pageSize: 500,
|
|
||||||
latest: false,
|
|
||||||
taskType: '',
|
|
||||||
taskOperate: '',
|
taskOperate: '',
|
||||||
id: 0,
|
resourceID: 0,
|
||||||
|
taskType: '',
|
||||||
});
|
});
|
||||||
|
const open = ref(false);
|
||||||
const stopSignals = ['[TASK-END]'];
|
|
||||||
|
|
||||||
const initData = () => {
|
|
||||||
open.value = true;
|
|
||||||
initCodemirror();
|
|
||||||
init();
|
|
||||||
};
|
|
||||||
|
|
||||||
const openWithTaskID = (id: string) => {
|
const openWithTaskID = (id: string) => {
|
||||||
readReq.taskID = id;
|
config.taskID = id;
|
||||||
initData();
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const openWithResourceID = (taskType: string, taskOperate: string, resourceID: number) => {
|
const openWithResourceID = (taskType: string, taskOperate: string, resourceID: number) => {
|
||||||
readReq.taskType = taskType;
|
config.taskType = taskType;
|
||||||
readReq.id = resourceID;
|
config.resourceID = resourceID;
|
||||||
readReq.taskOperate = taskOperate;
|
config.taskOperate = taskOperate;
|
||||||
initData();
|
open.value = true;
|
||||||
};
|
|
||||||
|
|
||||||
const getContent = (pre: boolean) => {
|
|
||||||
if (readReq.page < 1) {
|
|
||||||
readReq.page = 1;
|
|
||||||
}
|
|
||||||
ReadByLine(readReq).then((res) => {
|
|
||||||
if (!end.value && res.data.end) {
|
|
||||||
lastContent.value = content.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.data.content = res.data.content.replace(/\\u(\w{4})/g, function (match, grp) {
|
|
||||||
return String.fromCharCode(parseInt(grp, 16));
|
|
||||||
});
|
|
||||||
data.value = res.data;
|
|
||||||
if (res.data.content != '') {
|
|
||||||
if (stopSignals.some((signal) => res.data.content.includes(signal))) {
|
|
||||||
onCloseLog();
|
|
||||||
}
|
|
||||||
if (end.value) {
|
|
||||||
if (lastContent.value == '') {
|
|
||||||
content.value = res.data.content;
|
|
||||||
} else {
|
|
||||||
content.value = pre
|
|
||||||
? res.data.content + '\n' + lastContent.value
|
|
||||||
: lastContent.value + '\n' + res.data.content;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (content.value == '') {
|
|
||||||
content.value = res.data.content;
|
|
||||||
} else {
|
|
||||||
content.value = pre
|
|
||||||
? res.data.content + '\n' + content.value
|
|
||||||
: content.value + '\n' + res.data.content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end.value = res.data.end;
|
|
||||||
nextTick(() => {
|
|
||||||
if (pre) {
|
|
||||||
if (scrollerElement.value.scrollHeight > 2000) {
|
|
||||||
scrollerElement.value.scrollTop = 2000;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
scrollerElement.value.scrollTop = scrollerElement.value.scrollHeight;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (readReq.latest) {
|
|
||||||
readReq.page = res.data.total;
|
|
||||||
readReq.latest = false;
|
|
||||||
maxPage.value = res.data.total;
|
|
||||||
minPage.value = res.data.total;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeTail = (fromOutSide: boolean) => {
|
|
||||||
if (fromOutSide) {
|
|
||||||
tailLog.value = !tailLog.value;
|
|
||||||
}
|
|
||||||
if (tailLog.value) {
|
|
||||||
timer = setInterval(() => {
|
|
||||||
getContent(false);
|
|
||||||
}, 1000 * 3);
|
|
||||||
} else {
|
|
||||||
onCloseLog();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onCloseLog();
|
|
||||||
open.value = false;
|
open.value = false;
|
||||||
em('close', open.value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCloseLog = async () => {
|
|
||||||
tailLog.value = false;
|
|
||||||
clearInterval(Number(timer));
|
|
||||||
timer = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
function isScrolledToBottom(element: HTMLElement): boolean {
|
|
||||||
return element.scrollTop + element.clientHeight + 1 >= element.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isScrolledToTop(element: HTMLElement): boolean {
|
|
||||||
return element.scrollTop === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const init = () => {
|
|
||||||
tailLog.value = true;
|
|
||||||
if (tailLog.value) {
|
|
||||||
changeTail(false);
|
|
||||||
}
|
|
||||||
readReq.latest = true;
|
|
||||||
getContent(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initCodemirror = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
if (editorRef.value) {
|
|
||||||
scrollerElement.value = editorRef.value.$el as HTMLElement;
|
|
||||||
scrollerElement.value.addEventListener('scroll', function () {
|
|
||||||
if (isScrolledToBottom(scrollerElement.value)) {
|
|
||||||
readReq.page = maxPage.value;
|
|
||||||
getContent(false);
|
|
||||||
}
|
|
||||||
if (isScrolledToTop(scrollerElement.value)) {
|
|
||||||
readReq.page = minPage.value - 1;
|
|
||||||
if (readReq.page < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
minPage.value = readReq.page;
|
|
||||||
getContent(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let hljsDom = scrollerElement.value.querySelector('.hljs') as HTMLElement;
|
|
||||||
hljsDom.style['min-height'] = '400px';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
onCloseLog();
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({ openWithResourceID, openWithTaskID });
|
defineExpose({ openWithResourceID, openWithTaskID });
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
|
||||||
.task-log-dialog {
|
|
||||||
--dialog-max-height: 80vh;
|
|
||||||
--dialog-header-height: 50px;
|
|
||||||
--dialog-padding: 20px;
|
|
||||||
.el-dialog {
|
|
||||||
max-width: 60%;
|
|
||||||
max-height: var(--dialog-max-height);
|
|
||||||
margin-top: 5vh !important;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.el-dialog__body {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: var(--dialog-padding);
|
|
||||||
}
|
|
||||||
.log-container {
|
|
||||||
height: calc(var(--dialog-max-height) - var(--dialog-header-height) - var(--dialog-padding) * 2);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-main {
|
|
||||||
width: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
height: 420px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -301,6 +301,7 @@ const message = {
|
||||||
packing: 'Packing',
|
packing: 'Packing',
|
||||||
sending: 'Sending',
|
sending: 'Sending',
|
||||||
healthy: 'Normal',
|
healthy: 'Normal',
|
||||||
|
executing: 'Executing',
|
||||||
},
|
},
|
||||||
units: {
|
units: {
|
||||||
second: 'Second',
|
second: 'Second',
|
||||||
|
|
|
@ -296,6 +296,7 @@ const message = {
|
||||||
packing: '打包中',
|
packing: '打包中',
|
||||||
sending: '下發中',
|
sending: '下發中',
|
||||||
healthy: '正常',
|
healthy: '正常',
|
||||||
|
executing: '執行中',
|
||||||
},
|
},
|
||||||
units: {
|
units: {
|
||||||
second: '秒',
|
second: '秒',
|
||||||
|
|
|
@ -296,6 +296,7 @@ const message = {
|
||||||
packing: '打包中',
|
packing: '打包中',
|
||||||
sending: '下发中',
|
sending: '下发中',
|
||||||
healthy: '正常',
|
healthy: '正常',
|
||||||
|
executing: '执行中',
|
||||||
},
|
},
|
||||||
units: {
|
units: {
|
||||||
second: '秒',
|
second: '秒',
|
||||||
|
@ -1165,7 +1166,7 @@ const message = {
|
||||||
errLog: '错误日志',
|
errLog: '错误日志',
|
||||||
task: '任务日志',
|
task: '任务日志',
|
||||||
taskName: '任务名称',
|
taskName: '任务名称',
|
||||||
taskRunning: '运行中',
|
taskRunning: '执行中',
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
dir: '文件夹',
|
dir: '文件夹',
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<el-option :label="$t('commons.table.all')" value=""></el-option>
|
<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.success')" value="Success"></el-option>
|
||||||
<el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
|
<el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
|
||||||
<el-option :label="$t('logs.taskRunning')" value="Running"></el-option>
|
<el-option :label="$t('logs.taskRunning')" value="Executing"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<TableRefresh @search="search()" />
|
<TableRefresh @search="search()" />
|
||||||
<TableSetting title="task-log-refresh" @search="search()" />
|
<TableSetting title="task-log-refresh" @search="search()" />
|
||||||
|
|
Loading…
Add table
Reference in a new issue