chore: history page support sharedworker.js
This commit is contained in:
@@ -8,6 +8,8 @@ export const PATHS = {
|
||||
CONFIGS_DIR: '/app/configs',
|
||||
// 环境目录
|
||||
ENVS_DIR: '/app/envs',
|
||||
// 脚本目录占位符
|
||||
SCRIPTS_DIR_PLACEHOLDER: '$SCRIPTS_DIR$',
|
||||
} as const
|
||||
|
||||
// 文件扩展名对应的运行命令
|
||||
@@ -61,3 +63,12 @@ export const ENV_TYPE = {
|
||||
NORMAL: 'normal',
|
||||
SECRET: 'secret',
|
||||
} as const
|
||||
|
||||
// 任务事件类型
|
||||
export const TASK_EVENTS = {
|
||||
SUCCESS: 'task_success',
|
||||
FAILED: 'task_failed',
|
||||
TIMEOUT: 'task_timeout',
|
||||
RUNNING: 'task_running',
|
||||
QUEUED: 'task_queued',
|
||||
} as const
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
export interface WSMessage {
|
||||
type: string
|
||||
timestamp: number
|
||||
payload: any
|
||||
}
|
||||
|
||||
export interface TaskStatusPayload {
|
||||
id: string
|
||||
task_id: string
|
||||
task_name: string
|
||||
status: string
|
||||
duration: number
|
||||
start_time: string | null
|
||||
end_time: string | null
|
||||
error?: string | null
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { RepoConfig, Task } from '@/api'
|
||||
import { PATHS } from '@/constants'
|
||||
|
||||
/**
|
||||
* 仓库命令解析结果
|
||||
@@ -64,10 +65,10 @@ export function parseBaihuCommand(command: string): ParsedRepoResult | null {
|
||||
}
|
||||
break
|
||||
case '--target-path':
|
||||
// 处理 $SCRIPTS_DIR$ 占位符
|
||||
if (value.startsWith('$SCRIPTS_DIR$/')) {
|
||||
repoConfig.target_path = value.replace('$SCRIPTS_DIR$/', '')
|
||||
} else if (value === '$SCRIPTS_DIR$') {
|
||||
// 处理脚本目录占位符
|
||||
if (value.startsWith(`${PATHS.SCRIPTS_DIR_PLACEHOLDER}/`)) {
|
||||
repoConfig.target_path = value.replace(`${PATHS.SCRIPTS_DIR_PLACEHOLDER}/`, '')
|
||||
} else if (value === PATHS.SCRIPTS_DIR_PLACEHOLDER) {
|
||||
repoConfig.target_path = ''
|
||||
} else {
|
||||
repoConfig.target_path = value
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed, watch, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { TASK_STATUS, TASK_TYPE, TASK_STATUS_TEXT } from '@/constants'
|
||||
import { TASK_STATUS, TASK_TYPE, TASK_STATUS_TEXT, TASK_EVENTS } from '@/constants'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import Pagination from '@/components/Pagination.vue'
|
||||
@@ -17,6 +17,7 @@ import BaihuDialog from '@/components/ui/BaihuDialog.vue'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { useSiteSettings } from '@/composables/useSiteSettings'
|
||||
import TextOverflow from '@/components/TextOverflow.vue'
|
||||
import { useEventBus } from '@/composables/useEventBus'
|
||||
|
||||
const route = useRoute()
|
||||
const { pageSize } = useSiteSettings()
|
||||
@@ -34,6 +35,39 @@ let durationTimer: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
const isRefreshing = ref(false)
|
||||
|
||||
// 监听实时任务事件
|
||||
useEventBus(Object.values(TASK_EVENTS), (payload, type) => {
|
||||
const { log_id, status, duration, end_time } = payload
|
||||
|
||||
// 查找列表中的记录
|
||||
const logItem = logs.value.find(l => l.id === log_id)
|
||||
|
||||
if (logItem) {
|
||||
// 更新已有记录状态
|
||||
logItem.status = status
|
||||
if (duration !== undefined) logItem.duration = duration
|
||||
if (end_time !== undefined) logItem.end_time = end_time
|
||||
|
||||
// 如果详情页打开的是这个记录,也同步更新
|
||||
if (selectedLog.value && selectedLog.value.id === log_id) {
|
||||
selectedLog.value.status = status
|
||||
if (duration !== undefined) selectedLog.value.duration = duration
|
||||
if (end_time !== undefined) selectedLog.value.end_time = end_time
|
||||
|
||||
// 如果任务完成了,停止详情页的轮询定时器
|
||||
if (status !== TASK_STATUS.RUNNING && durationTimer) {
|
||||
clearInterval(durationTimer)
|
||||
durationTimer = null
|
||||
}
|
||||
}
|
||||
} else if (type === TASK_EVENTS.RUNNING) {
|
||||
// 新任务开始执行,如果在第一页且没有特定筛选条件,则刷新列表
|
||||
if (currentPage.value === 1 && !filterTaskId.value && !filterKeyword.value && (!filterStatus.value || filterStatus.value === 'all')) {
|
||||
loadLogs()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 全屏查看
|
||||
const showFullscreen = ref(false)
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ const concurrency = ref(0)
|
||||
const concurrencyEnabled = ref(false)
|
||||
const commentToTaskEnabled = ref(false)
|
||||
const allEnvsEnabled = ref(false)
|
||||
const SCRIPTS_DIR_PLACEHPLDER = '$SCRIPTS_DIR$'
|
||||
const scriptsDir = ref<string>(PATHS.SCRIPTS_DIR)
|
||||
|
||||
const cronDescription = computed(() => {
|
||||
@@ -366,9 +365,9 @@ function removeEnv(id: string) {
|
||||
|
||||
function normalizeLocalWorkDirForDisplay(workDir?: string | null): string {
|
||||
if (!workDir) return ''
|
||||
if (workDir === SCRIPTS_DIR_PLACEHPLDER) return ''
|
||||
if (workDir.startsWith(`${SCRIPTS_DIR_PLACEHPLDER}/`)) {
|
||||
return workDir.slice(SCRIPTS_DIR_PLACEHPLDER.length + 1)
|
||||
if (workDir === PATHS.SCRIPTS_DIR_PLACEHOLDER) return ''
|
||||
if (workDir.startsWith(`${PATHS.SCRIPTS_DIR_PLACEHOLDER}/`)) {
|
||||
return workDir.slice(PATHS.SCRIPTS_DIR_PLACEHOLDER.length + 1)
|
||||
}
|
||||
const base = scriptsDir.value || PATHS.SCRIPTS_DIR
|
||||
if (workDir === base) return ''
|
||||
@@ -380,16 +379,16 @@ function normalizeLocalWorkDirForDisplay(workDir?: string | null): string {
|
||||
|
||||
function encodeLocalWorkDir(workDir?: string | null): string {
|
||||
const value = workDir?.trim() || ''
|
||||
if (!value) return SCRIPTS_DIR_PLACEHPLDER
|
||||
if (value === SCRIPTS_DIR_PLACEHPLDER || value.startsWith(`${SCRIPTS_DIR_PLACEHPLDER}/`)) {
|
||||
if (!value) return PATHS.SCRIPTS_DIR_PLACEHOLDER
|
||||
if (value === PATHS.SCRIPTS_DIR_PLACEHOLDER || value.startsWith(`${PATHS.SCRIPTS_DIR_PLACEHOLDER}/`)) {
|
||||
return value
|
||||
}
|
||||
const base = scriptsDir.value || PATHS.SCRIPTS_DIR
|
||||
if (value === base) return SCRIPTS_DIR_PLACEHPLDER
|
||||
if (value === base) return PATHS.SCRIPTS_DIR_PLACEHOLDER
|
||||
if (value.startsWith(`${base}/`)) {
|
||||
return `${SCRIPTS_DIR_PLACEHPLDER}/${value.slice(base.length + 1)}`
|
||||
return `${PATHS.SCRIPTS_DIR_PLACEHOLDER}/${value.slice(base.length + 1)}`
|
||||
}
|
||||
return `${SCRIPTS_DIR_PLACEHPLDER}/${value.replace(/^\/+/, '')}`
|
||||
return `${PATHS.SCRIPTS_DIR_PLACEHOLDER}/${value.replace(/^\/+/, '')}`
|
||||
}
|
||||
|
||||
async function save() {
|
||||
|
||||
Reference in New Issue
Block a user