import { unreachable } from '.'; import { getTeam } from '../../data/team'; import { icon } from '../../utils/components'; import { isMobile } from '../../utils/device'; import { duration } from '../../utils/format'; import { ColumnField, Tab } from './types'; type JobDocTypes = 'Site' | 'Bench' | 'Server' | 'Release Group'; // 英文 job_type 到中文的映射 const jobTypeI18nMap: Record = { 'Update Site Status': '更新站点状态', 'Update Site Configuration': '更新站点配置', 'Install App on Site': '安装应用到站点', 'Uninstall App from Site': '从站点卸载应用', 'Backup Site': '备份站点', 'Restore Site': '恢复站点', 'Create Server': '创建服务器', 'Update In Place': '原地升级', // 可按需补充更多 }; function jobTypeI18n(type: string) { return jobTypeI18nMap[type] || type; } const statusI18nMap: Record = { 'Pending': '待处理', 'Running': '运行中', 'Success': '成功', 'Failure': '失败', }; function statusI18n(status: string) { return statusI18nMap[status] || status; } export function getJobsTab(pagetype: JobDocTypes) { const jobRoute = getJobRoute(pagetype); return { label: '任务', icon: icon('truck'), childrenRoutes: [jobRoute], route: 'jobs', type: 'list', list: { pagetype: 'Agent Job', filters: res => { if (pagetype === 'Site') return { site: res.name }; else if (pagetype === 'Bench') return { bench: res.name }; else if (pagetype === 'Server') return { server: res.name }; else if (pagetype === 'Release Group') return { group: res.name }; throw unreachable; }, route: undefined, orderBy: 'creation desc', searchField: 'job_type', fields: ['end', 'job_id'], filterControls() { return [ { type: 'select', label: '状态', fieldname: 'status', class: !isMobile() ? 'w-24' : '', options: ['', 'Pending', 'Running', 'Success', 'Failure'] }, { type: 'link', label: '类型', fieldname: 'job_type', options: { pagetype: 'Agent Job Type', orderBy: 'name asc', pageLength: 100 } } ]; }, rowActions: ({ row }) => [ { label: '在桌面查看', condition: () => getTeam()?.pg?.is_desk_user, onClick() { window.open( `${window.location.protocol}//${window.location.host}/app/agent-job/${row.name}`, '_blank' ); } } ], columns: getJobTabColumns(pagetype) } } satisfies Tab as Tab; } function getJobRoute(pagetype: JobDocTypes) { if (pagetype === 'Site') return 'Site Job'; else if (pagetype === 'Bench') return 'Bench Job'; else if (pagetype === 'Server') return 'Server Job'; else if (pagetype === 'Release Group') return 'Release Group Job'; throw unreachable; } function getJobTabColumns(pagetype: JobDocTypes) { const columns: ColumnField[] = [ { label: '任务类型', fieldname: 'job_type', class: 'font-medium', format: jobTypeI18n }, { label: '状态', fieldname: 'status', type: 'Badge', width: 0.5, format: statusI18n }, { label: '站点', fieldname: 'site', width: 1.2 }, { label: '持续时间', fieldname: 'duration', width: 0.35, format: (value, row) => { if (row.job_id === 0 || !row.end) return; return duration(value); } }, { label: '创建者', fieldname: 'owner' }, { label: '', fieldname: 'creation', type: 'Timestamp', width: 0.75, align: 'right', format: (value) => formatTimeZh(value) } ]; if (pagetype !== 'Site') return columns; return columns.filter(c => c.fieldname !== 'site'); } // 中文时间格式化函数 function formatTimeZh(time: string | Date) { if (!time) return ''; const date = typeof time === 'string' ? new Date(time) : time; const now = new Date(); const diff = (now.getTime() - date.getTime()) / 1000; if (diff < 60) return '刚刚'; if (diff < 3600) return Math.floor(diff / 60) + '分钟前'; if (diff < 86400) return Math.floor(diff / 3600) + '小时前'; if (diff < 2592000) return Math.floor(diff / 86400) + '天前'; return date.toLocaleDateString('zh-CN'); }