feat(任务调度): 重构任务调度界面并替换cron组件

refactor(IntervalTab): 优化时间间隔选择组件样式和功能
feat(任务管理): 使用vue3-cron-plus替换原有cron组件
fix(样式): 修复导航栏下拉菜单图标颜色问题
chore(依赖): 更新package.json依赖项和node版本要求
perf(构建): 优化vite配置和代码分割策略
This commit is contained in:
zhangtao
2025-07-28 00:23:29 +08:00
parent 96fd8dcfb3
commit a7942616bf
12 changed files with 326 additions and 178 deletions
-1
View File
@@ -17,7 +17,6 @@ import { useAppStore, useSettingsStore } from "@/store";
import { defaultSettings } from "@/settings";
import { ThemeMode } from "@/enums/settings/theme.enum";
import { ComponentSize } from "@/enums/settings/layout.enum";
import { ElNotification } from 'element-plus'
const appStore = useAppStore();
const settingsStore = useSettingsStore();
+145 -28
View File
@@ -1,37 +1,74 @@
<template>
<el-form :model="crontabValueObj" ref="formRef" label-width="auto" label-suffix=":" :inline="true" class="flex">
<el-form-item label="秒" prop="second" style="width: 20%">
<el-select v-model:value="crontabValueObj.second" placeholder="秒">
<el-option v-for="second in seconds" :key="second" :value="second">{{ second }}</el-option>
<el-form :model="crontabValueObj" ref="formRef" label-width="auto" label-suffix=":" :inline="true" class="interval-tab-form">
<el-form-item label="秒" prop="second" class="form-item">
<el-select v-model="crontabValueObj.second" placeholder="秒" clearable>
<el-option label="每秒" value="*">*</el-option>
<el-option v-for="second in seconds" :key="second" :label="second" :value="second.toString()">{{ second }}</el-option>
</el-select>
</el-form-item>
<el-form-item label="分" prop="min" style="width: 20%">
<el-select v-model:value="crontabValueObj.min" placeholder="分">
<el-option v-for="min in minutes" :key="min" :value="min">{{min}}</el-option>
<el-form-item label="分" prop="min" class="form-item">
<el-select v-model="crontabValueObj.min" placeholder="分" clearable>
<el-option label="每分" value="*">*</el-option>
<el-option v-for="min in minutes" :key="min" :label="min" :value="min.toString()">{{min}}</el-option>
</el-select>
</el-form-item>
<el-form-item label="时" prop="hour" style="width: 20%">
<el-select v-model:value="crontabValueObj.hour" placeholder="时">
<el-option v-for="hour in hours" :key="hour" :value="hour">{{hour}}</el-option>
<el-form-item label="时" prop="hour" class="form-item">
<el-select v-model="crontabValueObj.hour" placeholder="时" clearable>
<el-option label="每时" value="*">*</el-option>
<el-option v-for="hour in hours" :key="hour" :label="hour" :value="hour.toString()">{{hour}}</el-option>
</el-select>
</el-form-item>
<el-form-item label="天" prop="day" style="width: 20%">
<el-select v-model:value="crontabValueObj.day" placeholder="天">
<el-option v-for="day in days" :key="day" :value="day">{{day}}</el-option>
<el-form-item label="天" prop="day" class="form-item">
<el-select v-model="crontabValueObj.day" placeholder="天" clearable>
<el-option label="每天" value="*">*</el-option>
<el-option v-for="day in days" :key="day" :label="day" :value="day">{{day}}</el-option>
</el-select>
</el-form-item>
<el-form-item label="周" prop="week" style="width: 20%">
<el-select v-model:value="crontabValueObj.week" placeholder="周">
<el-option v-for="week in weeks" :key="week" :value="week">{{week}}</el-option>
<el-form-item label="周" prop="week" class="form-item">
<el-select v-model="crontabValueObj.week" placeholder="周" clearable>
<el-option label="每周" value="*">*</el-option>
<el-option v-for="week in weekOptions" :key="week.value" :label="week.label" :value="week.value">{{week.label}}</el-option>
</el-select>
</el-form-item>
<div class="form-actions">
<el-button @click="emit('cancel')">取消</el-button>
<el-button type="primary" @click="handleConfirm">确认</el-button>
</div>
</el-form>
</template>
<script setup>
import { ref } from "vue";
<script lang="ts" setup>
const crontabValueObj = ref({
// 定义接口,增强类型安全
interface CrontabValue {
second: string;
min: string;
hour: string;
day: string;
week: string;
}
interface WeekOption {
value: string;
label: string;
}
// 定义props
const props = defineProps<{
cronValue?: string;
}>();
// 定义emits
const emit = defineEmits<{
(e: 'confirm', value: string): void;
(e: 'cancel'): void;
}>();
const formRef = ref();
// 响应式数据
const crontabValueObj = ref<CrontabValue>({
second: "*",
min: "*",
hour: "*",
@@ -39,20 +76,100 @@ const crontabValueObj = ref({
week: "*",
});
const seconds = ref(Array.from({ length: 60 }, (_, i) => i.toString()));
const minutes = ref(Array.from({ length: 60 }, (_, i) => i.toString()));
const hours = ref(Array.from({ length: 24 }, (_, i) => i.toString()));
const days = ref(Array.from({ length: 31 }, (_, i) => (i + 1).toString()));
const weeks = ref(["*", "1", "2", "3", "4", "5", "6", "7"]);
// 常量定义,避免魔法数字
const MAX_SECONDS = 60;
const MAX_MINUTES = 60;
const MAX_HOURS = 24;
const MAX_DAYS = 31;
// 生成选择器选项
const seconds = ref(Array.from({ length: MAX_SECONDS }, (_, i) => i));
const minutes = ref(Array.from({ length: MAX_MINUTES }, (_, i) => i));
const hours = ref(Array.from({ length: MAX_HOURS }, (_, i) => i));
const days = ref(Array.from({ length: MAX_DAYS }, (_, i) => i + 1));
const weekOptions: WeekOption[] = [
{ value: "1", label: "周一" },
{ value: "2", label: "周二" },
{ value: "3", label: "周三" },
{ value: "4", label: "周四" },
{ value: "5", label: "周五" },
{ value: "6", label: "周六" },
{ value: "7", label: "周日" }
];
// 初始化时设置cron值
onMounted(() => {
if (props.cronValue) {
setCron(props.cronValue);
}
});
// 处理确认
const handleConfirm = () => {
// 简单验证
const obj = crontabValueObj.value;
return `${obj.second} ${obj.min} ${obj.hour} ${obj.day} ${obj.week}`;
if (!obj.second || !obj.min || !obj.hour || !obj.day || !obj.week) {
ElMessage.warning('请完善所有时间选项');
return;
}
const cronStr = `${obj.second} ${obj.min} ${obj.hour} ${obj.day} ${obj.week}`;
emit('confirm', cronStr);
};
// 暴露方法和属性给父组件
defineExpose({ handleConfirm, crontabValueObj });
// 设置cron表达式的值
const setCron = (cronStr: string) => {
if (!cronStr) return;
const parts = cronStr.split(' ');
if (parts.length !== 5) {
ElMessage.warning('无效的cron表达式格式');
return;
}
const [second, min, hour, day, week] = parts;
crontabValueObj.value = {
second: second || '*',
min: min || '*',
hour: hour || '*',
day: day || '*',
week: week || '*'
};
};
// 暴露方法给父组件
defineExpose({ setCron });
</script>
<style lang="scss" scoped>
// 样式可以根据需要调整</style>
.interval-tab-form {
width: 100%;
flex-wrap: wrap;
gap: 16px 8px;
}
.form-item {
width: calc(20% - 8px);
min-width: 120px;
}
.form-actions {
width: 100%;
display: flex;
justify-content: flex-end;
margin-top: 16px;
gap: 8px;
}
// 响应式调整
@media (max-width: 768px) {
.form-item {
width: calc(33.33% - 8px);
}
}
@media (max-width: 480px) {
.form-item {
width: calc(50% - 8px);
}
}
</style>
@@ -152,7 +152,7 @@ function handleDocumentClick() {
* Gitee 项目地址
*/
function handleGiteeClick() {
window.open('https://element-plus-admin-doc.cn/')
window.open('https://gitee.com/tao__tao/fastapi_vue3_admin')
}
/**
@@ -283,7 +283,7 @@ function logout() {
display: flex;
align-items: center;
justify-content: center;
// height: 100%;
height: 100%;
padding: 0 8px;
&__avatar {
@@ -344,4 +344,14 @@ function logout() {
}
}
// 确保下拉菜单中的图标不受影响
:deep(.el-dropdown-menu) {
[class^="i-svg:"] {
color: var(--el-text-color-regular) !important;
&:hover {
color: var(--el-color-primary) !important;
}
}
}
</style>
+3 -3
View File
@@ -6,7 +6,7 @@ import { setupStore } from "@/store";
import { setupElIcons } from "./icons";
import { setupPermission } from "./permission";
import { InstallCodeMirror } from "codemirror-editor-vue3";
// import ElementPlus from 'element-plus'
import ElementPlus from 'element-plus'
export default {
install(app: App<Element>) {
@@ -22,7 +22,7 @@ export default {
setupPermission();
// 注册 CodeMirror
app.use(InstallCodeMirror);
// // 注册 ElementPlus
// app.use(ElementPlus);
// 注册 ElementPlus
app.use(ElementPlus);
},
};
+3
View File
@@ -16,6 +16,9 @@
"info": (
"base": #a9aeb8,
),
"default": (
"base": #f5f5f5,
),
),
$bg-color: (
+1 -1
View File
@@ -626,4 +626,4 @@ declare module 'vue' {
readonly watchWithFilter: UnwrapRef<typeof import('@vueuse/core')['watchWithFilter']>
readonly whenever: UnwrapRef<typeof import('@vueuse/core')['whenever']>
}
}
}
+50 -51
View File
@@ -8,18 +8,18 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
AppLink: typeof import('./src/components/AppLink/index.vue')['default']
AppLogo: typeof import('./src/layouts/components/AppLogo/index.vue')['default']
AppMain: typeof import('./src/layouts/components/AppMain/index.vue')['default']
BasicMenu: typeof import('./src/layouts/components/Menu/BasicMenu.vue')['default']
Breadcrumb: typeof import('./src/components/Breadcrumb/index.vue')['default']
CommonWrapper: typeof import('./src/components/CommonWrapper/index.vue')['default']
ConfigInfoDrawer: typeof import('./src/views/system/config/components/ConfigInfoDrawer.vue')['default']
CopyButton: typeof import('./src/components/CopyButton/index.vue')['default']
DarkModeSwitch: typeof import('./src/components/DarkModeSwitch/index.vue')['default']
DataDrawer: typeof import('./src/views/system/dict/components/DataDrawer.vue')['default']
DeptTree: typeof import('./src/views/system/user/components/DeptTree.vue')['default']
ECharts: typeof import('./src/components/ECharts/index.vue')['default']
AppLink: typeof import('./../components/AppLink/index.vue')['default']
AppLogo: typeof import('./../layouts/components/AppLogo/index.vue')['default']
AppMain: typeof import('./../layouts/components/AppMain/index.vue')['default']
BasicMenu: typeof import('./../layouts/components/Menu/BasicMenu.vue')['default']
Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default']
CommonWrapper: typeof import('./../components/CommonWrapper/index.vue')['default']
ConfigInfoDrawer: typeof import('./../views/system/config/components/ConfigInfoDrawer.vue')['default']
CopyButton: typeof import('./../components/CopyButton/index.vue')['default']
DarkModeSwitch: typeof import('./../components/DarkModeSwitch/index.vue')['default']
DataDrawer: typeof import('./../views/system/dict/components/DataDrawer.vue')['default']
DeptTree: typeof import('./../views/system/user/components/DeptTree.vue')['default']
ECharts: typeof import('./../components/ECharts/index.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
@@ -30,7 +30,6 @@ declare module 'vue' {
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
@@ -63,6 +62,7 @@ declare module 'vue' {
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElResult: typeof import('element-plus/es')['ElResult']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
@@ -85,46 +85,45 @@ declare module 'vue' {
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
ElWatermark: typeof import('element-plus/es')['ElWatermark']
Vue3CronPlusPicker: typeof import('vue3-cron-plus-picker')['default']
FileUpload: typeof import('./src/components/Upload/FileUpload.vue')['default']
Frame: typeof import('./src/components/Frame/index.vue')['default']
Fullscreen: typeof import('./src/components/Fullscreen/index.vue')['default']
GithubCorner: typeof import('./src/components/GithubCorner/index.vue')['default']
Guide: typeof import('./src/components/Guide/index.vue')['default']
Hamburger: typeof import('./src/components/Hamburger/index.vue')['default']
IconSelect: typeof import('./src/components/IconSelect/index.vue')['default']
InputTag: typeof import('./src/components/InputTag/index.vue')['default']
IntervalTab: typeof import('./src/components/IntervalTab/index.vue')['default']
LangSelect: typeof import('./src/components/LangSelect/index.vue')['default']
LockDialog: typeof import('./src/layouts/components/NavBar/components/LockDialog.vue')['default']
LockPage: typeof import('./src/layouts/components/NavBar/components/LockPage.vue')['default']
Login: typeof import('./src/views/system/auth/components/Login.vue')['default']
MenuItem: typeof import('./src/layouts/components/Menu/components/MenuItem.vue')['default']
MenuItemContent: typeof import('./src/layouts/components/Menu/components/MenuItemContent.vue')['default']
MenuSearch: typeof import('./src/components/MenuSearch/index.vue')['default']
MixTopMenu: typeof import('./src/layouts/components/Menu/MixTopMenu.vue')['default']
MultiImageUpload: typeof import('./src/components/Upload/MultiImageUpload.vue')['default']
NavBar: typeof import('./src/layouts/components/NavBar/index.vue')['default']
NavbarActions: typeof import('./src/layouts/components/NavBar/components/NavbarActions.vue')['default']
Notification: typeof import('./src/components/Notification/index.vue')['default']
OperationColumn: typeof import('./src/components/OperationColumn/index.vue')['default']
PageContent: typeof import('./src/components/CURD/PageContent.vue')['default']
PageModal: typeof import('./src/components/CURD/PageModal.vue')['default']
PageSearch: typeof import('./src/components/CURD/PageSearch.vue')['default']
Pagination: typeof import('./src/components/Pagination/index.vue')['default']
PermissonDrawer: typeof import('./src/views/system/role/components/PermissonDrawer.vue')['default']
Register: typeof import('./src/views/system/auth/components/Register.vue')['default']
ResetPwd: typeof import('./src/views/system/auth/components/ResetPwd.vue')['default']
FileUpload: typeof import('./../components/Upload/FileUpload.vue')['default']
Frame: typeof import('./../components/Frame/index.vue')['default']
Fullscreen: typeof import('./../components/Fullscreen/index.vue')['default']
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default']
Guide: typeof import('./../components/Guide/index.vue')['default']
Hamburger: typeof import('./../components/Hamburger/index.vue')['default']
IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
InputTag: typeof import('./../components/InputTag/index.vue')['default']
IntervalTab: typeof import('./../components/IntervalTab/index.vue')['default']
LangSelect: typeof import('./../components/LangSelect/index.vue')['default']
LockDialog: typeof import('./../layouts/components/NavBar/components/LockDialog.vue')['default']
LockPage: typeof import('./../layouts/components/NavBar/components/LockPage.vue')['default']
Login: typeof import('./../views/system/auth/components/Login.vue')['default']
MenuItem: typeof import('./../layouts/components/Menu/components/MenuItem.vue')['default']
MenuItemContent: typeof import('./../layouts/components/Menu/components/MenuItemContent.vue')['default']
MenuSearch: typeof import('./../components/MenuSearch/index.vue')['default']
MixTopMenu: typeof import('./../layouts/components/Menu/MixTopMenu.vue')['default']
MultiImageUpload: typeof import('./../components/Upload/MultiImageUpload.vue')['default']
NavBar: typeof import('./../layouts/components/NavBar/index.vue')['default']
NavbarActions: typeof import('./../layouts/components/NavBar/components/NavbarActions.vue')['default']
Notification: typeof import('./../components/Notification/index.vue')['default']
OperationColumn: typeof import('./../components/OperationColumn/index.vue')['default']
PageContent: typeof import('./../components/CURD/PageContent.vue')['default']
PageModal: typeof import('./../components/CURD/PageModal.vue')['default']
PageSearch: typeof import('./../components/CURD/PageSearch.vue')['default']
Pagination: typeof import('./../components/Pagination/index.vue')['default']
PermissonDrawer: typeof import('./../views/system/role/components/PermissonDrawer.vue')['default']
Register: typeof import('./../views/system/auth/components/Register.vue')['default']
ResetPwd: typeof import('./../views/system/auth/components/ResetPwd.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Settings: typeof import('./src/layouts/components/Settings/index.vue')['default']
SingleImageUpload: typeof import('./src/components/Upload/SingleImageUpload.vue')['default']
SizeSelect: typeof import('./src/components/SizeSelect/index.vue')['default']
TableSelect: typeof import('./src/components/TableSelect/index.vue')['default']
TagsView: typeof import('./src/layouts/components/TagsView/index.vue')['default']
TextScroll: typeof import('./src/components/TextScroll/index.vue')['default']
UserImport: typeof import('./src/views/system/user/components/UserImport.vue')['default']
WangEditor: typeof import('./src/components/WangEditor/index.vue')['default']
Settings: typeof import('./../layouts/components/Settings/index.vue')['default']
SingleImageUpload: typeof import('./../components/Upload/SingleImageUpload.vue')['default']
SizeSelect: typeof import('./../components/SizeSelect/index.vue')['default']
TableSelect: typeof import('./../components/TableSelect/index.vue')['default']
TagsView: typeof import('./../layouts/components/TagsView/index.vue')['default']
TextScroll: typeof import('./../components/TextScroll/index.vue')['default']
UserImport: typeof import('./../views/system/user/components/UserImport.vue')['default']
WangEditor: typeof import('./../components/WangEditor/index.vue')['default']
}
export interface GlobalDirectives {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
-20
View File
@@ -1,20 +0,0 @@
declare module "vue3-cron-plus-picker" {
import { DefineComponent } from "vue";
export const Vue3CronPlusPicker: DefineComponent<{}, {}, any>;
export default Vue3CronPlusPicker;
}
declare module "vue3-cron-plus-picker/style.css" {
const content: any;
export default content;
}
declare module "vue3-cron-plus-picker/vue3-cron-plus-picker.js" {
import { DefineComponent } from "vue";
export const Vue3CronPlusPicker: DefineComponent<{}, {}, any>;
export default Vue3CronPlusPicker;
}
+12
View File
@@ -0,0 +1,12 @@
declare module "vue3-cron-plus" {
import { DefineComponent } from "vue";
export const vue3CronPlus: DefineComponent<{}, {}, any>;
export default vue3CronPlus;
}
declare module "vue3-cron-plus/dist/index.css" {
const content: any;
export default content;
}
+55 -62
View File
@@ -364,37 +364,62 @@
v-else-if="formData.trigger === 'interval'"
label="间隔时间"
prop="trigger_args"
:rules="[{ required: true, message: '请输入间隔时间' }]"
:rules="[{ required: true, message: '请输入间隔时间', trigger: 'change' }]"
style="width: 40%"
>
<el-input
v-model="formData.trigger_args"
placeholder="请输入 秒-分-时-天-周 (* * * * 1)"
clearable
@click="openIntervalTabHandle('create')"
/>
<el-popover
:visible="openIntervalTab"
width="600px"
trigger="click"
:persistent="false"
>
<template #reference>
<el-input
v-model="formData.trigger_args"
placeholder="请输入 秒-分-时-天-周"
readonly
@click="openIntervalTab = true"
/>
</template>
<IntervalTab
ref="intervalTabRef"
@confirm="handleIntervalConfirm"
@cancel="openIntervalTab = false"
:cron-value="formData.trigger_args"
/>
</el-popover>
</el-form-item>
<el-form-item
v-else-if="formData.trigger === 'cron'"
label="Cron表达式"
prop="trigger_args"
:rules="[{ required: true, message: '请输入Cron表达式' }]"
:rules="[{ required: true, message: '请输入Cron表达式', trigger: 'change' }]"
style="width: 40%"
>
<el-input
v-model="formData.trigger_args"
placeholder="请输入 Cron表达式(*/3 * * * *)"
clearable
readonly
@click="handleShowCron"
/>
<el-popover
:visible="openCron"
width="600px"
trigger="click"
:persistent="false"
placement="left"
>
<template #reference>
<el-input
v-model="formData.trigger_args"
placeholder="请输入 * * * * * ? *"
readonly
@click="openCron = true"
/>
</template>
<vue3CronPlus @change="handlechangeCron" @close="openCron = false" max-height="500px" i18n="cn"></vue3CronPlus>
</el-popover>
</el-form-item>
<!-- 开始日期和结束日期 -->
<el-form-item
v-if="formData.trigger && formData.trigger != 'date'"
label="开始日期"
prop="start_date"
:rules="[{ required: false, message: '请选择开始日期' }]"
:rules="[{ required: false, message: '请选择开始日期', trigger: 'blur' }]"
style="width: 40%"
>
<el-date-picker
@@ -409,7 +434,7 @@
v-if="formData.trigger && formData.trigger != 'date'"
label="结束日期"
prop="end_date"
:rules="[{ required: false, message: '请选择结束日期' }]"
:rules="[{ required: false, message: '请选择结束日期', trigger: 'blur' }]"
style="width: 40%"
>
<el-date-picker
@@ -451,23 +476,6 @@
</template>
</el-dialog>
<!-- 时间间隔组件 -->
<el-dialog v-model="openIntervalTab" title="间隔时间设置" :width="700" align-center draggable>
<IntervalTab ref="intervalTabRef" />
<template #footer>
<div class="dialog-footer">
<el-button @click="openIntervalTab = false">取消</el-button>
<el-button type="primary" @click="handleIntervalConfirm">
确认
</el-button>
</div>
</template>
</el-dialog>
<!-- core组件 -->
<el-dialog v-model="openCron">
<Vue3CronPlusPicker @hide="closeDialog" @fill="fillValue" :expression="expression" />
</el-dialog>
</div>
</template>
@@ -478,11 +486,10 @@ defineOptions({
});
import JobAPI, { JobTable, JobForm, JobPageQuery } from "@/api/monitor/job";
import IntervalTab from "@/components/IntervalTab/index.vue";
import "vue3-cron-plus-picker/style.css";
import { Vue3CronPlusPicker } from "vue3-cron-plus-picker";
import { useDictStore } from "@/store/index";
import { vue3CronPlus } from 'vue3-cron-plus'
import 'vue3-cron-plus/dist/index.css' //
const dictStore = useDictStore();
@@ -504,8 +511,7 @@ const isExpandable = ref(true);
// const tableLoading = ref(false);
// const openModal = ref(false);
const openCron = ref(false);
const cronMode = ref("create");
const modalTitle = ref("");
// const modalSubmitLoading = ref(false);
// const detailStateLoading = ref(false);
// const dataSource = ref<tableJobType[]>([]);
@@ -514,7 +520,6 @@ const modalTitle = ref("");
// const detailState = ref<tableJobType>({})
const openIntervalTab = ref(false);
const intervalTabRef = ref();
const expression = ref();
//
const pageTableData = ref<JobTable[]>([]);
@@ -541,7 +546,7 @@ const formData = reactive<JobForm>({
args: undefined,
kwargs: undefined,
coalesce: undefined,
max_instances: undefined,
max_instances: 1,
jobstore: undefined,
executor: undefined,
trigger_args: undefined,
@@ -659,7 +664,7 @@ async function handleSubmit() {
handleCloseDialog();
handleResetQuery();
} catch (error: any) {
ElMessage.error(error.message);
console.log(error);
} finally {
loading.value = false;
}
@@ -671,7 +676,7 @@ async function handleSubmit() {
handleCloseDialog();
handleResetQuery();
} catch (error: any) {
ElMessage.error(error.message);
console.log(error);
} finally {
loading.value = false;
}
@@ -739,7 +744,6 @@ async function handleExport() {
document.body.appendChild(link);
link.click();
} catch (error: any) {
ElMessage.error("文件处理失败", error.message);
console.error("导出错误:", error);
} finally {
loading.value = false;
@@ -749,27 +753,16 @@ async function handleExport() {
});
}
function openIntervalTabHandle(value: any) {
openIntervalTab.value = true;
modalTitle.value = value;
}
function handleIntervalConfirm() {
formData.trigger_args = intervalTabRef.value.handleConfirm();
function handleIntervalConfirm(interval: string) {
formData.trigger_args = interval;
openIntervalTab.value = false;
}
const handleShowCron = () => {
openCron.value = true;
expression.value = formData.trigger_args;
};
const closeDialog = () => {
openCron.value = false;
};
const fillValue = (cronValue: string) => {
formData.trigger_args = cronValue;
const handlechangeCron = (cronStr: string) => {
// formData.trigger_args = cronStr;
if (typeof (cronStr) == "string") {
formData.trigger_args = cronStr;
}
};
//