Browse Source

!236 refactor: Job crontab components
Merge pull request !236 from xingyu/master

芋道源码 2 years ago
parent
commit
fbebcc4467

+ 1 - 1
yudao-ui-admin-vue3/package.json

@@ -1,6 +1,6 @@
 {
   "name": "ruoyi-vue-pro-vue3",
-  "version": "1.6.2.1601",
+  "version": "1.6.3.1601",
   "description": "基于vue3、element-plus、typesScript、vite3",
   "author": "xingyu",
   "private": false,

+ 5 - 5
yudao-ui-admin-vue3/src/api/bpm/task/index.ts

@@ -11,22 +11,22 @@ export const getDoneTaskPage = async (params) => {
 }
 
 export const completeTask = async (data) => {
-  return await request.put({ url: '/bpm/task/complete', data: data })
+  return await request.put({ url: '/bpm/task/complete', data })
 }
 
 export const approveTask = async (data) => {
-  return await request.put({ url: '/bpm/task/approve', data: data })
+  return await request.put({ url: '/bpm/task/approve', data })
 }
 
 export const rejectTask = async (data) => {
-  return await request.put({ url: '/bpm/task/reject', data: data })
+  return await request.put({ url: '/bpm/task/reject', data })
 }
 export const backTask = async (data) => {
-  return await request.put({ url: '/bpm/task/back', data: data })
+  return await request.put({ url: '/bpm/task/back', data })
 }
 
 export const updateTaskAssignee = async (data) => {
-  return await request.put({ url: '/bpm/task/update-assignee', data: data })
+  return await request.put({ url: '/bpm/task/update-assignee', data })
 }
 
 export const getTaskListByProcessInstanceId = async (processInstanceId) => {

+ 4 - 4
yudao-ui-admin-vue3/src/api/infra/job/index.ts

@@ -19,8 +19,8 @@ export const createJobApi = (data: JobVO) => {
 }
 
 // 修改定时任务调度
-export const updateJobApi = (params: JobVO) => {
-  return request.put({ url: '/infra/job/update', params })
+export const updateJobApi = (data: JobVO) => {
+  return request.put({ url: '/infra/job/update', data })
 }
 
 // 删除定时任务调度
@@ -35,11 +35,11 @@ export const exportJobApi = (params) => {
 
 // 任务状态修改
 export const updateJobStatusApi = (id: number, status: number) => {
-  const data = {
+  const params = {
     id,
     status
   }
-  return request.put({ url: '/infra/job/update-status', data: data })
+  return request.put({ url: '/infra/job/update-status', params })
 }
 
 // 定时任务立即执行一次

+ 0 - 1
yudao-ui-admin-vue3/src/api/infra/job/types.ts

@@ -8,5 +8,4 @@ export type JobVO = {
   retryCount: number
   retryInterval: number
   monitorTimeout: number
-  createTime: string
 }

+ 1 - 2
yudao-ui-admin-vue3/src/components/Crontab/index.ts

@@ -1,3 +1,2 @@
-import Crontab from './src/index.vue'
-
+import Crontab from './src/Crontab.vue'
 export { Crontab }

+ 1025 - 0
yudao-ui-admin-vue3/src/components/Crontab/src/Crontab.vue

@@ -0,0 +1,1025 @@
+<!--
+ * @Descripttion: cron规则生成器
+ * @version: 1.0
+ * @Author: sakuya
+ * @Date: 2021年12月29日15:23:54
+ * @LastEditors:
+ * @LastEditTime:
+-->
+<script setup lang="ts">
+import {
+  ElInput,
+  ElInputNumber,
+  ElDropdown,
+  ElDropdownMenu,
+  ElDropdownItem,
+  ElDialog,
+  ElTabs,
+  ElTabPane,
+  ElSelect,
+  ElOption,
+  ElForm,
+  ElFormItem,
+  ElRadioGroup,
+  ElRadioButton,
+  ElMessage
+} from 'element-plus'
+import { ref, computed, onMounted, reactive, watch, PropType } from 'vue'
+interface shortcutsType {
+  text: string
+  value: string
+}
+const props = defineProps({
+  modelValue: { type: String, default: '* * * * * ?' },
+  shortcuts: { type: Array as PropType<shortcutsType[]>, default: () => [] }
+})
+const defaultValue = ref('')
+const dialogVisible = ref(false)
+const getYear = () => {
+  let v: number[] = []
+  let y = new Date().getFullYear()
+  for (let i = 0; i < 11; i++) {
+    v.push(y + i)
+  }
+  return v
+}
+const cronValue = reactive({
+  second: {
+    type: '0',
+    range: {
+      start: 1,
+      end: 2
+    },
+    loop: {
+      start: 0,
+      end: 1
+    },
+    appoint: [] as string[]
+  },
+  minute: {
+    type: '0',
+    range: {
+      start: 1,
+      end: 2
+    },
+    loop: {
+      start: 0,
+      end: 1
+    },
+    appoint: [] as string[]
+  },
+  hour: {
+    type: '0',
+    range: {
+      start: 1,
+      end: 2
+    },
+    loop: {
+      start: 0,
+      end: 1
+    },
+    appoint: [] as string[]
+  },
+  day: {
+    type: '0',
+    range: {
+      start: 1,
+      end: 2
+    },
+    loop: {
+      start: 1,
+      end: 1
+    },
+    appoint: [] as string[]
+  },
+  month: {
+    type: '0',
+    range: {
+      start: 1,
+      end: 2
+    },
+    loop: {
+      start: 1,
+      end: 1
+    },
+    appoint: [] as string[]
+  },
+  week: {
+    type: '5',
+    range: {
+      start: '2',
+      end: '3'
+    },
+    loop: {
+      start: 0,
+      end: '2'
+    },
+    last: '2',
+    appoint: [] as string[]
+  },
+  year: {
+    type: '-1',
+    range: {
+      start: getYear()[0],
+      end: getYear()[1]
+    },
+    loop: {
+      start: getYear()[0],
+      end: 1
+    },
+    appoint: [] as string[]
+  }
+})
+const data = reactive({
+  second: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
+  minute: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
+  hour: [
+    '0',
+    '1',
+    '2',
+    '3',
+    '4',
+    '5',
+    '6',
+    '7',
+    '8',
+    '9',
+    '10',
+    '11',
+    '12',
+    '13',
+    '14',
+    '15',
+    '16',
+    '17',
+    '18',
+    '19',
+    '20',
+    '21',
+    '22',
+    '23'
+  ],
+  day: [
+    '1',
+    '2',
+    '3',
+    '4',
+    '5',
+    '6',
+    '7',
+    '8',
+    '9',
+    '10',
+    '11',
+    '12',
+    '13',
+    '14',
+    '15',
+    '16',
+    '17',
+    '18',
+    '19',
+    '20',
+    '21',
+    '22',
+    '23',
+    '24',
+    '25',
+    '26',
+    '27',
+    '28',
+    '29',
+    '30',
+    '31'
+  ],
+  month: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
+  week: [
+    {
+      value: '1',
+      label: '周日'
+    },
+    {
+      value: '2',
+      label: '周一'
+    },
+    {
+      value: '3',
+      label: '周二'
+    },
+    {
+      value: '4',
+      label: '周三'
+    },
+    {
+      value: '5',
+      label: '周四'
+    },
+    {
+      value: '6',
+      label: '周五'
+    },
+    {
+      value: '7',
+      label: '周六'
+    }
+  ],
+  year: getYear()
+})
+
+const value_second = computed(() => {
+  let v = cronValue.second
+  if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.start + '/' + v.loop.end
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : '*'
+  } else {
+    return '*'
+  }
+})
+const value_minute = computed(() => {
+  let v = cronValue.minute
+  if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.start + '/' + v.loop.end
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : '*'
+  } else {
+    return '*'
+  }
+})
+const value_hour = computed(() => {
+  let v = cronValue.hour
+  if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.start + '/' + v.loop.end
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : '*'
+  } else {
+    return '*'
+  }
+})
+const value_day = computed(() => {
+  let v = cronValue.day
+  if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.start + '/' + v.loop.end
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : '*'
+  } else if (v.type == '4') {
+    return 'L'
+  } else if (v.type == '5') {
+    return '?'
+  } else {
+    return '*'
+  }
+})
+const value_month = computed(() => {
+  let v = cronValue.month
+  if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.start + '/' + v.loop.end
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : '*'
+  } else {
+    return '*'
+  }
+})
+const value_week = computed(() => {
+  let v = cronValue.week
+  if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.end + '#' + v.loop.start
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : '*'
+  } else if (v.type == '4') {
+    return v.last + 'L'
+  } else if (v.type == '5') {
+    return '?'
+  } else {
+    return '*'
+  }
+})
+const value_year = computed(() => {
+  let v = cronValue.year
+  if (v.type == '-1') {
+    return ''
+  } else if (v.type == '0') {
+    return '*'
+  } else if (v.type == '1') {
+    return v.range.start + '-' + v.range.end
+  } else if (v.type == '2') {
+    return v.loop.start + '/' + v.loop.end
+  } else if (v.type == '3') {
+    return v.appoint.length > 0 ? v.appoint.join(',') : ''
+  } else {
+    return ''
+  }
+})
+watch(
+  () => cronValue.week.type,
+  (val) => {
+    if (val != '5') {
+      cronValue.day.type = '5'
+    }
+  }
+)
+watch(
+  () => cronValue.day.type,
+  (val) => {
+    if (val != '5') {
+      cronValue.week.type = '5'
+    }
+  }
+)
+watch(
+  () => props.modelValue,
+  () => {
+    defaultValue.value = props.modelValue
+  }
+)
+onMounted(() => {
+  defaultValue.value = props.modelValue
+})
+const emit = defineEmits(['update:modelValue'])
+const handleShortcuts = (command) => {
+  if (command == 'custom') {
+    open()
+  } else {
+    defaultValue.value = command
+    emit('update:modelValue', defaultValue.value)
+  }
+}
+const open = () => {
+  set()
+  dialogVisible.value = true
+}
+const set = () => {
+  defaultValue.value = props.modelValue
+  let arr = (props.modelValue || '* * * * * ?').split(' ')
+  //简单检查
+  if (arr.length < 6) {
+    ElMessage.warning('cron表达式错误,已转换为默认表达式')
+    arr = '* * * * * ?'.split(' ')
+  }
+
+  //秒
+  if (arr[0] == '*') {
+    cronValue.second.type = '0'
+  } else if (arr[0].includes('-')) {
+    cronValue.second.type = '1'
+    cronValue.second.range.start = Number(arr[0].split('-')[0])
+    cronValue.second.range.end = Number(arr[0].split('-')[1])
+  } else if (arr[0].includes('/')) {
+    cronValue.second.type = '2'
+    cronValue.second.loop.start = Number(arr[0].split('/')[0])
+    cronValue.second.loop.end = Number(arr[0].split('/')[1])
+  } else {
+    cronValue.second.type = '3'
+    cronValue.second.appoint = arr[0].split(',')
+  }
+  //分
+  if (arr[1] == '*') {
+    cronValue.minute.type = '0'
+  } else if (arr[1].includes('-')) {
+    cronValue.minute.type = '1'
+    cronValue.minute.range.start = Number(arr[1].split('-')[0])
+    cronValue.minute.range.end = Number(arr[1].split('-')[1])
+  } else if (arr[1].includes('/')) {
+    cronValue.minute.type = '2'
+    cronValue.minute.loop.start = Number(arr[1].split('/')[0])
+    cronValue.minute.loop.end = Number(arr[1].split('/')[1])
+  } else {
+    cronValue.minute.type = '3'
+    cronValue.minute.appoint = arr[1].split(',')
+  }
+  //小时
+  if (arr[2] == '*') {
+    cronValue.hour.type = '0'
+  } else if (arr[2].includes('-')) {
+    cronValue.hour.type = '1'
+    cronValue.hour.range.start = Number(arr[2].split('-')[0])
+    cronValue.hour.range.end = Number(arr[2].split('-')[1])
+  } else if (arr[2].includes('/')) {
+    cronValue.hour.type = '2'
+    cronValue.hour.loop.start = Number(arr[2].split('/')[0])
+    cronValue.hour.loop.end = Number(arr[2].split('/')[1])
+  } else {
+    cronValue.hour.type = '3'
+    cronValue.hour.appoint = arr[2].split(',')
+  }
+  //日
+  if (arr[3] == '*') {
+    cronValue.day.type = '0'
+  } else if (arr[3] == 'L') {
+    cronValue.day.type = '4'
+  } else if (arr[3] == '?') {
+    cronValue.day.type = '5'
+  } else if (arr[3].includes('-')) {
+    cronValue.day.type = '1'
+    cronValue.day.range.start = Number(arr[3].split('-')[0])
+    cronValue.day.range.end = Number(arr[3].split('-')[1])
+  } else if (arr[3].includes('/')) {
+    cronValue.day.type = '2'
+    cronValue.day.loop.start = Number(arr[3].split('/')[0])
+    cronValue.day.loop.end = Number(arr[3].split('/')[1])
+  } else {
+    cronValue.day.type = '3'
+    cronValue.day.appoint = arr[3].split(',')
+  }
+  //月
+  if (arr[4] == '*') {
+    cronValue.month.type = '0'
+  } else if (arr[4].includes('-')) {
+    cronValue.month.type = '1'
+    cronValue.month.range.start = Number(arr[4].split('-')[0])
+    cronValue.month.range.end = Number(arr[4].split('-')[1])
+  } else if (arr[4].includes('/')) {
+    cronValue.month.type = '2'
+    cronValue.month.loop.start = Number(arr[4].split('/')[0])
+    cronValue.month.loop.end = Number(arr[4].split('/')[1])
+  } else {
+    cronValue.month.type = '3'
+    cronValue.month.appoint = arr[4].split(',')
+  }
+  //周
+  if (arr[5] == '*') {
+    cronValue.week.type = '0'
+  } else if (arr[5] == '?') {
+    cronValue.week.type = '5'
+  } else if (arr[5].includes('-')) {
+    cronValue.week.type = '1'
+    cronValue.week.range.start = arr[5].split('-')[0]
+    cronValue.week.range.end = arr[5].split('-')[1]
+  } else if (arr[5].includes('#')) {
+    cronValue.week.type = '2'
+    cronValue.week.loop.start = Number(arr[5].split('#')[1])
+    cronValue.week.loop.end = arr[5].split('#')[0]
+  } else if (arr[5].includes('L')) {
+    cronValue.week.type = '4'
+    cronValue.week.last = arr[5].split('L')[0]
+  } else {
+    cronValue.week.type = '3'
+    cronValue.week.appoint = arr[5].split(',')
+  }
+  //年
+  if (!arr[6]) {
+    cronValue.year.type = '-1'
+  } else if (arr[6] == '*') {
+    cronValue.year.type = '0'
+  } else if (arr[6].includes('-')) {
+    cronValue.year.type = '1'
+    cronValue.year.range.start = Number(arr[6].split('-')[0])
+    cronValue.year.range.end = Number(arr[6].split('-')[1])
+  } else if (arr[6].includes('/')) {
+    cronValue.year.type = '2'
+    cronValue.year.loop.start = Number(arr[6].split('/')[1])
+    cronValue.year.loop.end = Number(arr[6].split('/')[0])
+  } else {
+    cronValue.year.type = '3'
+    cronValue.year.appoint = arr[6].split(',')
+  }
+}
+const submit = () => {
+  let year = value_year.value ? ' ' + value_year.value : ''
+  defaultValue.value =
+    value_second.value +
+    ' ' +
+    value_minute.value +
+    ' ' +
+    value_hour.value +
+    ' ' +
+    value_day.value +
+    ' ' +
+    value_month.value +
+    ' ' +
+    value_week.value +
+    year
+  emit('update:modelValue', defaultValue.value)
+  dialogVisible.value = false
+}
+</script>
+<template>
+  <el-input v-model="defaultValue" v-bind="$attrs">
+    <template #append>
+      <el-dropdown split-button trigger="click" @command="handleShortcuts">
+        生成器
+        <template #dropdown>
+          <el-dropdown-menu>
+            <el-dropdown-item command="0 * * * * ?">每分钟</el-dropdown-item>
+            <el-dropdown-item command="0 0 * * * ?">每小时</el-dropdown-item>
+            <el-dropdown-item command="0 0 0 * * ?">每天零点</el-dropdown-item>
+            <el-dropdown-item command="0 0 0 1 * ?">每月一号零点</el-dropdown-item>
+            <el-dropdown-item command="0 0 0 L * ?">每月最后一天零点</el-dropdown-item>
+            <el-dropdown-item command="0 0 0 ? * 1">每周星期日零点</el-dropdown-item>
+            <el-dropdown-item
+              v-for="(item, index) in shortcuts"
+              :key="item.value"
+              :divided="index == 0"
+              :command="item.value"
+            >
+              {{ item.text }}
+            </el-dropdown-item>
+            <el-dropdown-item divided command="custom">
+              <Icon icon="ep:menu" />自定义
+            </el-dropdown-item>
+          </el-dropdown-menu>
+        </template>
+      </el-dropdown>
+    </template>
+  </el-input>
+
+  <el-dialog
+    title="cron规则生成器"
+    v-model="dialogVisible"
+    :width="580"
+    destroy-on-close
+    append-to-body
+  >
+    <div class="sc-cron">
+      <el-tabs>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>秒</h2>
+              <h4>{{ value_second }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form-item label="类型">
+              <el-radio-group v-model="cronValue.second.type">
+                <el-radio-button label="0">任意值</el-radio-button>
+                <el-radio-button label="1">范围</el-radio-button>
+                <el-radio-button label="2">间隔</el-radio-button>
+                <el-radio-button label="3">指定</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="范围" v-if="cronValue.second.type == '1'">
+              <el-input-number
+                v-model="cronValue.second.range.start"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+              <span style="padding: 0 15px">-</span>
+              <el-input-number
+                v-model="cronValue.second.range.end"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+            </el-form-item>
+            <el-form-item label="间隔" v-if="cronValue.second.type == '2'">
+              <el-input-number
+                v-model="cronValue.second.loop.start"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+              秒开始,每
+              <el-input-number
+                v-model="cronValue.second.loop.end"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+              秒执行一次
+            </el-form-item>
+            <el-form-item label="指定" v-if="cronValue.second.type == '3'">
+              <el-select v-model="cronValue.second.appoint" multiple style="width: 100%">
+                <el-option
+                  v-for="(item, index) in data.second"
+                  :key="index"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>分钟</h2>
+              <h4>{{ value_minute }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form-item label="类型">
+              <el-radio-group v-model="cronValue.minute.type">
+                <el-radio-button label="0">任意值</el-radio-button>
+                <el-radio-button label="1">范围</el-radio-button>
+                <el-radio-button label="2">间隔</el-radio-button>
+                <el-radio-button label="3">指定</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="范围" v-if="cronValue.minute.type == '1'">
+              <el-input-number
+                v-model="cronValue.minute.range.start"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+              <span style="padding: 0 15px">-</span>
+              <el-input-number
+                v-model="cronValue.minute.range.end"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+            </el-form-item>
+            <el-form-item label="间隔" v-if="cronValue.minute.type == '2'">
+              <el-input-number
+                v-model="cronValue.minute.loop.start"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+              分钟开始,每
+              <el-input-number
+                v-model="cronValue.minute.loop.end"
+                :min="0"
+                :max="59"
+                controls-position="right"
+              />
+              分钟执行一次
+            </el-form-item>
+            <el-form-item label="指定" v-if="cronValue.minute.type == '3'">
+              <el-select v-model="cronValue.minute.appoint" multiple style="width: 100%">
+                <el-option
+                  v-for="(item, index) in data.minute"
+                  :key="index"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>小时</h2>
+              <h4>{{ value_hour }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form-item label="类型">
+              <el-radio-group v-model="cronValue.hour.type">
+                <el-radio-button label="0">任意值</el-radio-button>
+                <el-radio-button label="1">范围</el-radio-button>
+                <el-radio-button label="2">间隔</el-radio-button>
+                <el-radio-button label="3">指定</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="范围" v-if="cronValue.hour.type == '1'">
+              <el-input-number
+                v-model="cronValue.hour.range.start"
+                :min="0"
+                :max="23"
+                controls-position="right"
+              />
+              <span style="padding: 0 15px">-</span>
+              <el-input-number
+                v-model="cronValue.hour.range.end"
+                :min="0"
+                :max="23"
+                controls-position="right"
+              />
+            </el-form-item>
+            <el-form-item label="间隔" v-if="cronValue.hour.type == '2'">
+              <el-input-number
+                v-model="cronValue.hour.loop.start"
+                :min="0"
+                :max="23"
+                controls-position="right"
+              />
+              小时开始,每
+              <el-input-number
+                v-model="cronValue.hour.loop.end"
+                :min="0"
+                :max="23"
+                controls-position="right"
+              />
+              小时执行一次
+            </el-form-item>
+            <el-form-item label="指定" v-if="cronValue.hour.type == '3'">
+              <el-select v-model="cronValue.hour.appoint" multiple style="width: 100%">
+                <el-option
+                  v-for="(item, index) in data.hour"
+                  :key="index"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>日</h2>
+              <h4>{{ value_day }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form-item label="类型">
+              <el-radio-group v-model="cronValue.day.type">
+                <el-radio-button label="0">任意值</el-radio-button>
+                <el-radio-button label="1">范围</el-radio-button>
+                <el-radio-button label="2">间隔</el-radio-button>
+                <el-radio-button label="3">指定</el-radio-button>
+                <el-radio-button label="4">本月最后一天</el-radio-button>
+                <el-radio-button label="5">不指定</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="范围" v-if="cronValue.day.type == '1'">
+              <el-input-number
+                v-model="cronValue.day.range.start"
+                :min="1"
+                :max="31"
+                controls-position="right"
+              />
+              <span style="padding: 0 15px">-</span>
+              <el-input-number
+                v-model="cronValue.day.range.end"
+                :min="1"
+                :max="31"
+                controls-position="right"
+              />
+            </el-form-item>
+            <el-form-item label="间隔" v-if="cronValue.day.type == '2'">
+              <el-input-number
+                v-model="cronValue.day.loop.start"
+                :min="1"
+                :max="31"
+                controls-position="right"
+              />
+              号开始,每
+              <el-input-number
+                v-model="cronValue.day.loop.end"
+                :min="1"
+                :max="31"
+                controls-position="right"
+              />
+              天执行一次
+            </el-form-item>
+            <el-form-item label="指定" v-if="cronValue.day.type == '3'">
+              <el-select v-model="cronValue.day.appoint" multiple style="width: 100%">
+                <el-option
+                  v-for="(item, index) in data.day"
+                  :key="index"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>月</h2>
+              <h4>{{ value_month }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form-item label="类型">
+              <el-radio-group v-model="cronValue.month.type">
+                <el-radio-button label="0">任意值</el-radio-button>
+                <el-radio-button label="1">范围</el-radio-button>
+                <el-radio-button label="2">间隔</el-radio-button>
+                <el-radio-button label="3">指定</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="范围" v-if="cronValue.month.type == '1'">
+              <el-input-number
+                v-model="cronValue.month.range.start"
+                :min="1"
+                :max="12"
+                controls-position="right"
+              />
+              <span style="padding: 0 15px">-</span>
+              <el-input-number
+                v-model="cronValue.month.range.end"
+                :min="1"
+                :max="12"
+                controls-position="right"
+              />
+            </el-form-item>
+            <el-form-item label="间隔" v-if="cronValue.month.type == '2'">
+              <el-input-number
+                v-model="cronValue.month.loop.start"
+                :min="1"
+                :max="12"
+                controls-position="right"
+              />
+              月开始,每
+              <el-input-number
+                v-model="cronValue.month.loop.end"
+                :min="1"
+                :max="12"
+                controls-position="right"
+              />
+              月执行一次
+            </el-form-item>
+            <el-form-item label="指定" v-if="cronValue.month.type == '3'">
+              <el-select v-model="cronValue.month.appoint" multiple style="width: 100%">
+                <el-option
+                  v-for="(item, index) in data.month"
+                  :key="index"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>周</h2>
+              <h4>{{ value_week }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form>
+              <el-form-item label="类型">
+                <el-radio-group v-model="cronValue.week.type">
+                  <el-radio-button label="0">任意值</el-radio-button>
+                  <el-radio-button label="1">范围</el-radio-button>
+                  <el-radio-button label="2">间隔</el-radio-button>
+                  <el-radio-button label="3">指定</el-radio-button>
+                  <el-radio-button label="4">本月最后一周</el-radio-button>
+                  <el-radio-button label="5">不指定</el-radio-button>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item label="范围" v-if="cronValue.week.type == '1'">
+                <el-select v-model="cronValue.week.range.start">
+                  <el-option
+                    v-for="(item, index) in data.week"
+                    :key="index"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+                <span style="padding: 0 15px">-</span>
+                <el-select v-model="cronValue.week.range.end">
+                  <el-option
+                    v-for="(item, index) in data.week"
+                    :key="index"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="间隔" v-if="cronValue.week.type == '2'">
+                第
+                <el-input-number
+                  v-model="cronValue.week.loop.start"
+                  :min="1"
+                  :max="4"
+                  controls-position="right"
+                />
+                周的星期
+                <el-select v-model="cronValue.week.loop.end">
+                  <el-option
+                    v-for="(item, index) in data.week"
+                    :key="index"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+                执行一次
+              </el-form-item>
+              <el-form-item label="指定" v-if="cronValue.week.type == '3'">
+                <el-select v-model="cronValue.week.appoint" multiple style="width: 100%">
+                  <el-option
+                    v-for="(item, index) in data.week"
+                    :key="index"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="最后一周" v-if="cronValue.week.type == '4'">
+                <el-select v-model="cronValue.week.last">
+                  <el-option
+                    v-for="(item, index) in data.week"
+                    :key="index"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-form>
+          </el-form>
+        </el-tab-pane>
+        <el-tab-pane>
+          <template #label>
+            <div class="sc-cron-num">
+              <h2>年</h2>
+              <h4>{{ value_year }}</h4>
+            </div>
+          </template>
+          <el-form>
+            <el-form-item label="类型">
+              <el-radio-group v-model="cronValue.year.type">
+                <el-radio-button label="-1">忽略</el-radio-button>
+                <el-radio-button label="0">任意值</el-radio-button>
+                <el-radio-button label="1">范围</el-radio-button>
+                <el-radio-button label="2">间隔</el-radio-button>
+                <el-radio-button label="3">指定</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="范围" v-if="cronValue.year.type == '1'">
+              <el-input-number v-model="cronValue.year.range.start" controls-position="right" />
+              <span style="padding: 0 15px">-</span>
+              <el-input-number v-model="cronValue.year.range.end" controls-position="right" />
+            </el-form-item>
+            <el-form-item label="间隔" v-if="cronValue.year.type == '2'">
+              <el-input-number v-model="cronValue.year.loop.start" controls-position="right" />
+              年开始,每
+              <el-input-number
+                v-model="cronValue.year.loop.end"
+                :min="1"
+                controls-position="right"
+              />
+              年执行一次
+            </el-form-item>
+            <el-form-item label="指定" v-if="cronValue.year.type == '3'">
+              <el-select v-model="cronValue.year.appoint" multiple style="width: 100%">
+                <el-option
+                  v-for="(item, index) in data.year"
+                  :key="index"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+
+    <template #footer>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+      <el-button type="primary" @click="submit()">确 认</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<style scoped>
+.sc-cron:deep(.el-tabs__item) {
+  height: auto;
+  line-height: 1;
+  padding: 0 7px;
+  vertical-align: bottom;
+}
+.sc-cron-num {
+  text-align: center;
+  margin-bottom: 15px;
+  width: 100%;
+}
+.sc-cron-num h2 {
+  font-size: 12px;
+  margin-bottom: 15px;
+  font-weight: normal;
+}
+.sc-cron-num h4 {
+  display: block;
+  height: 32px;
+  line-height: 30px;
+  width: 100%;
+  font-size: 12px;
+  padding: 0 15px;
+  background: var(--el-color-primary-light-9);
+  border-radius: 4px;
+}
+.sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 {
+  background: var(--el-color-primary);
+  color: #fff;
+}
+
+[data-theme='dark'] .sc-cron-num h4 {
+  background: var(--el-color-white);
+}
+</style>

+ 0 - 173
yudao-ui-admin-vue3/src/components/Crontab/src/components/day.vue

@@ -1,173 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-
-const emits = defineEmits(['update'])
-
-const radioValue = ref(1)
-const workday = ref(1)
-const cycle01 = ref(1)
-const cycle02 = ref(2)
-const average01 = ref(1)
-const average02 = ref(1)
-
-const checkboxList = ref([])
-
-defineExpose({
-  radioValue,
-  workday,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-/**
- * 计算两个周期值
- * @type {ComputedRef<string>}
- */
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, 1, 30)
-  const cycle2 = props.check(cycle02.value, cycle1 ? cycle1 + 1 : 2, 31, 31)
-  return cycle1 + '-' + cycle2
-})
-
-/**
- * 计算平均用到的值
- */
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, 1, 30)
-  const average2 = props.check(average02.value, 1, 31 - average1 || 0)
-  return average1 + '/' + average2
-})
-
-/**
- * 计算工作日格式
- */
-const workdayCheck = computed(() => props.check(workday, 1, 31))
-
-/**
- * 计算勾选的checkbox值合集
- */
-const checkboxString = computed(() => {
-  const str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(radioValue, () => {
-  if (parseInt(radioValue.value.toString()) !== 2 && props.cron?.week !== '?') {
-    emits('update', 'week', '?', 'day')
-  }
-
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'day', '*')
-      break
-    case 2:
-      emits('update', 'day', '?')
-      break
-    case 3:
-      emits('update', 'day', cycleTotal)
-      break
-    case 4:
-      emits('update', 'day', averageTotal)
-      break
-    case 5:
-      emits('update', 'day', workday.value + 'W')
-      break
-    case 6:
-      emits('update', 'day', 'L')
-      break
-    case 7:
-      emits('update', 'day', checkboxString)
-      break
-  }
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'day', cycleTotal)
-  }
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'day', averageTotal)
-  }
-})
-
-watch(workdayCheck, () => {
-  if (parseInt(radioValue.value.toString()) === 5) {
-    emits('update', 'day', workdayCheck.value + 'W')
-  }
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 7) {
-    emits('update', 'day', checkboxString)
-  }
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="1"> 日,允许的通配符[, - * ? / L W] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="2"> 不指定 </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="3">
-        周期从
-        <el-input-number v-model="cycle01" :min="1" :max="30" /> -
-        <el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 2" :max="31" /> 日
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="4">
-        从
-        <el-input-number v-model="average01" :min="1" :max="30" /> 号开始,每
-        <el-input-number v-model="average02" :min="1" :max="31 - average01 || 1" /> 日执行一次
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="5">
-        每月
-        <el-input-number v-model="workday" :min="1" :max="31" /> 号最近的那个工作日
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="6"> 本月最后一天 </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="7">
-        指定
-        <el-select
-          clearable
-          v-model="checkboxList"
-          placeholder="可多选"
-          multiple
-          style="width: 100%"
-        >
-          <el-option v-for="item in 31" :key="item" :value="item">{{ item }}</el-option>
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 120
yudao-ui-admin-vue3/src/components/Crontab/src/components/hour.vue

@@ -1,120 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-const emits = defineEmits(['update'])
-
-const radioValue = ref(1)
-const cycle01 = ref(0)
-const cycle02 = ref(1)
-const average01 = ref(0)
-const average02 = ref(1)
-const checkboxList = ref([])
-
-defineExpose({
-  radioValue,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, 0, 22)
-  const cycle2 = props.check(cycle02.value, cycle1 ? cycle1 + 1 : 1, 23)
-  return cycle1 + '-' + cycle2
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 2) {
-    emits('update', 'hour', cycleTotal)
-  }
-})
-
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, 0, 22)
-  const average2 = props.check(average02.value, 1, 23 - average1 || 0)
-  return average1 + '/' + average2
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'hour', averageTotal)
-  }
-})
-
-const checkboxString = computed(() => {
-  let str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'hour', checkboxString)
-  }
-})
-
-watch(radioValue, () => {
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'hour', '*')
-      break
-    case 2:
-      emits('update', 'hour', cycleTotal)
-      break
-    case 3:
-      emits('update', 'hour', averageTotal)
-      break
-    case 4:
-      emits('update', 'hour', checkboxString)
-      break
-  }
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="1"> 小时,允许的通配符[, - * /] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="2">
-        周期从
-        <el-input-number v-model="cycle01" :min="0" :max="22" /> -
-        <el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="3">
-        从
-        <el-input-number v-model="average01" :min="0" :max="22" /> 小时开始,每
-        <el-input-number v-model="average02" :min="1" :max="23 - average01 || 0" /> 小时执行一次
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="4">
-        指定
-        <el-select
-          clearable
-          v-model="checkboxList"
-          placeholder="可多选"
-          multiple
-          style="width: 100%"
-        >
-          <el-option v-for="item in 24" :key="item" :value="item - 1">{{ item - 1 }}</el-option>
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 19
yudao-ui-admin-vue3/src/components/Crontab/src/components/index.ts

@@ -1,19 +0,0 @@
-import CrontabSecond from './second.vue'
-import CrontabMin from './min.vue'
-import CrontabHour from './hour.vue'
-import CrontabDay from './day.vue'
-import CrontabMonth from './month.vue'
-import CrontabWeek from './week.vue'
-import CrontabYear from './year.vue'
-import CrontabResult from './result.vue'
-
-export {
-  CrontabSecond,
-  CrontabMin,
-  CrontabHour,
-  CrontabDay,
-  CrontabMonth,
-  CrontabWeek,
-  CrontabYear,
-  CrontabResult
-}

+ 0 - 120
yudao-ui-admin-vue3/src/components/Crontab/src/components/min.vue

@@ -1,120 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-const emits = defineEmits(['update'])
-
-const radioValue = ref(1)
-const cycle01 = ref(0)
-const cycle02 = ref(1)
-const average01 = ref(0)
-const average02 = ref(1)
-const checkboxList = ref([])
-
-defineExpose({
-  radioValue,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, 0, 58)
-  const cycle2 = props.check(cycle02.value, cycle1 ? cycle1 + 1 : 1, 59)
-  return cycle1 + '-' + cycle2
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 2) {
-    emits('update', 'min', cycleTotal, 'min')
-  }
-})
-
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, 0, 58)
-  const average2 = props.check(average02.value, 1, 59 - average1 || 0)
-  return average1 + '/' + average2
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'min', averageTotal, 'min')
-  }
-})
-
-const checkboxString = computed(() => {
-  let str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'min', checkboxString, 'min')
-  }
-})
-
-watch(radioValue, () => {
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'min', '*', 'min')
-      break
-    case 2:
-      emits('update', 'min', cycleTotal, 'min')
-      break
-    case 3:
-      emits('update', 'min', averageTotal, 'min')
-      break
-    case 4:
-      emits('update', 'min', checkboxString, 'min')
-      break
-  }
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="1"> 分钟,允许的通配符[, - * /] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="2">
-        周期从
-        <el-input-number v-model="cycle01" :min="0" :max="58" /> -
-        <el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="3">
-        从
-        <el-input-number v-model="average01" :min="0" :max="58" /> 分钟开始,每
-        <el-input-number v-model="average02" :min="1" :max="59 - average01 || 0" /> 分钟执行一次
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="4">
-        指定
-        <el-select
-          clearable
-          v-model="checkboxList"
-          placeholder="可多选"
-          multiple
-          style="width: 100%"
-        >
-          <el-option v-for="item in 60" :key="item" :value="item - 1">{{ item - 1 }}</el-option>
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 120
yudao-ui-admin-vue3/src/components/Crontab/src/components/month.vue

@@ -1,120 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-const emits = defineEmits(['update'])
-
-const radioValue = ref(1)
-const cycle01 = ref(1)
-const cycle02 = ref(2)
-const average01 = ref(1)
-const average02 = ref(1)
-const checkboxList = ref([])
-
-defineExpose({
-  radioValue,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, 1, 11)
-  const cycle2 = props.check(cycle02.value, cycle1 ? cycle1 + 1 : 2, 12)
-  return cycle1 + '-' + cycle2
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 2) {
-    emits('update', 'month', cycleTotal)
-  }
-})
-
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, 1, 11)
-  const average2 = props.check(average02.value, 1, 12 - average1 || 0)
-  return average1 + '/' + average2
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'month', averageTotal)
-  }
-})
-
-const checkboxString = computed(() => {
-  let str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'month', checkboxString)
-  }
-})
-
-watch(radioValue, () => {
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'month', '*')
-      break
-    case 2:
-      emits('update', 'month', cycleTotal)
-      break
-    case 3:
-      emits('update', 'month', averageTotal)
-      break
-    case 4:
-      emits('update', 'month', checkboxString)
-      break
-  }
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="1"> 月,允许的通配符[, - * /] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="2">
-        周期从
-        <el-input-number v-model="cycle01" :min="1" :max="11" /> -
-        <el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 2" :max="12" /> 月
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="3">
-        从
-        <el-input-number v-model="average01" :min="1" :max="11" /> 月开始,每
-        <el-input-number v-model="average02" :min="1" :max="12 - average01 || 0" /> 月月执行一次
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="4">
-        指定
-        <el-select
-          clearable
-          v-model="checkboxList"
-          placeholder="可多选"
-          multiple
-          style="width: 100%"
-        >
-          <el-option v-for="item in 12" :key="item" :value="item">{{ item }}</el-option>
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 573
yudao-ui-admin-vue3/src/components/Crontab/src/components/result.vue

@@ -1,573 +0,0 @@
-<script setup lang="ts">
-import { onMounted, ref, watch } from 'vue'
-
-const props = defineProps({
-  ex: {
-    type: String,
-    required: true
-  }
-})
-
-watch(() => props.ex, expressionChange)
-
-onMounted(() => {
-  expressionChange()
-})
-
-const dayRule = ref('')
-const dayRuleSup = ref<string | number | any[]>([])
-const dateArr = ref<any[][]>([])
-const resultList = ref<string[]>([])
-const isShow = ref(false)
-
-function expressionChange() {
-  // 计算开始-隐藏结果
-  isShow.value = false
-  // 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
-  let ruleArr = props.ex.split(' ')
-  // 用于记录进入循环的次数
-  let nums = 0
-  // 用于暂时存符号时间规则结果的数组
-  let resultArr: string[] = []
-  // 获取当前时间精确至[年、月、日、时、分、秒]
-  let nTime = new Date()
-  let nYear = nTime.getFullYear()
-  let nMonth = nTime.getMonth() + 1
-  let nDay = nTime.getDate()
-  let nHour = nTime.getHours()
-  let nMin = nTime.getMinutes()
-  let nSecond = nTime.getSeconds()
-  // 根据规则获取到近100年可能年数组、月数组等等
-  getSecondArr(ruleArr[0])
-  getMinArr(ruleArr[1])
-  getHourArr(ruleArr[2])
-  getDayArr(ruleArr[3])
-  getMonthArr(ruleArr[4])
-  getWeekArr(ruleArr[5])
-  getYearArr(ruleArr[6], nYear)
-  // 将获取到的数组赋值-方便使用
-  let sDate = dateArr.value[0]
-  let mDate = dateArr.value[1]
-  let hDate = dateArr.value[2]
-  let DDate = dateArr.value[3]
-  let MDate = dateArr.value[4]
-  let YDate = dateArr.value[5]
-  // 获取当前时间在数组中的索引
-  let sIdx = getIndex(sDate, nSecond)
-  let mIdx = getIndex(mDate, nMin)
-  let hIdx = getIndex(hDate, nHour)
-  let DIdx = getIndex(DDate, nDay)
-  let MIdx = getIndex(MDate, nMonth)
-  let YIdx = getIndex(YDate, nYear)
-  // 重置月日时分秒的函数(后面用的比较多)
-  const resetSecond = function () {
-    sIdx = 0
-    nSecond = sDate[sIdx]
-  }
-  const resetMin = function () {
-    mIdx = 0
-    nMin = mDate[mIdx]
-    resetSecond()
-  }
-  const resetHour = function () {
-    hIdx = 0
-    nHour = hDate[hIdx]
-    resetMin()
-  }
-  const resetDay = function () {
-    DIdx = 0
-    nDay = DDate[DIdx]
-    resetHour()
-  }
-  const resetMonth = function () {
-    MIdx = 0
-    nMonth = MDate[MIdx]
-    resetDay()
-  }
-  // 如果当前年份不为数组中当前值
-  if (nYear !== YDate[YIdx]) {
-    resetMonth()
-  }
-  // 如果当前月份不为数组中当前值
-  if (nMonth !== MDate[MIdx]) {
-    resetDay()
-  }
-  // 如果当前“日”不为数组中当前值
-  if (nDay !== DDate[DIdx]) {
-    resetHour()
-  }
-  // 如果当前“时”不为数组中当前值
-  if (nHour !== hDate[hIdx]) {
-    resetMin()
-  }
-  // 如果当前“分”不为数组中当前值
-  if (nMin !== mDate[mIdx]) {
-    resetSecond()
-  }
-
-  // 循环年份数组
-  goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
-    let YY = YDate[Yi]
-    // 如果到达最大值时
-    if (nMonth > MDate[MDate.length - 1]) {
-      resetMonth()
-      continue
-    }
-    // 循环月份数组
-    goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
-      // 赋值、方便后面运算
-      let MM = MDate[Mi]
-      MM = MM < 10 ? '0' + MM : MM
-      // 如果到达最大值时
-      if (nDay > DDate[DDate.length - 1]) {
-        resetDay()
-        if (Mi == MDate.length - 1) {
-          resetMonth()
-          continue goYear
-        }
-        continue
-      }
-      // 循环日期数组
-      goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
-        // 赋值、方便后面运算
-        let DD = DDate[Di]
-        let thisDD = DD < 10 ? '0' + DD : DD
-
-        // 如果到达最大值时
-        if (nHour > hDate[hDate.length - 1]) {
-          resetHour()
-          if (Di == DDate.length - 1) {
-            resetDay()
-            if (Mi == MDate.length - 1) {
-              resetMonth()
-              continue goYear
-            }
-            continue goMonth
-          }
-          continue
-        }
-
-        // 判断日期的合法性,不合法的话也是跳出当前循环
-        if (
-          checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true &&
-          dayRule.value !== 'workDay' &&
-          dayRule.value !== 'lastWeek' &&
-          dayRule.value !== 'lastDay'
-        ) {
-          resetDay()
-          continue goMonth
-        }
-        // 如果日期规则中有值时
-        if (dayRule.value == 'lastDay') {
-          // 如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
-
-          if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-            while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-              DD--
-
-              thisDD = DD < 10 ? '0' + DD : DD
-            }
-          }
-        } else if (dayRule.value == 'workDay') {
-          // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
-          if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-            while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-              DD--
-              thisDD = DD < 10 ? '0' + DD : DD
-            }
-          }
-          // 获取达到条件的日期是星期X
-          let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week')
-          // 当星期日时
-          if (thisWeek == 1) {
-            // 先找下一个日,并判断是否为月底
-            DD++
-            thisDD = DD < 10 ? '0' + DD : DD
-            // 判断下一日已经不是合法日期
-            if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-              DD -= 3
-            }
-          } else if (thisWeek == 7) {
-            // 当星期6时只需判断不是1号就可进行操作
-            if (dayRuleSup.value !== 1) {
-              DD--
-            } else {
-              DD += 2
-            }
-          }
-        } else if (dayRule.value == 'weekDay') {
-          // 如果指定了是星期几
-          // 获取当前日期是属于星期几
-          let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week')
-          // 校验当前星期是否在星期池(dayRuleSup)中
-          if ((dayRuleSup.value as any[]).indexOf(thisWeek) < 0) {
-            // 如果到达最大值时
-            if (Di == DDate.length - 1) {
-              resetDay()
-              if (Mi == MDate.length - 1) {
-                resetMonth()
-                continue goYear
-              }
-              continue goMonth
-            }
-            continue
-          }
-        } else if (dayRule.value == 'assWeek') {
-          // 如果指定了是第几周的星期几
-          // 获取每月1号是属于星期几
-          let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week')
-          if (dayRuleSup.value[1] >= thisWeek) {
-            DD = (dayRuleSup.value[0] - 1) * 7 + dayRuleSup.value[1] - thisWeek + 1
-          } else {
-            DD = dayRuleSup.value[0] * 7 + dayRuleSup.value[1] - thisWeek + 1
-          }
-        } else if (dayRule.value == 'lastWeek') {
-          // 如果指定了每月最后一个星期几
-          // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
-          if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-            while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
-              DD--
-              thisDD = DD < 10 ? '0' + DD : DD
-            }
-          }
-          // 获取月末最后一天是星期几
-          let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week')
-          // 找到要求中最近的那个星期几
-          if (dayRuleSup.value < thisWeek) {
-            DD -= thisWeek - (dayRuleSup.value as number)
-          } else if (dayRuleSup.value > thisWeek) {
-            DD -= 7 - ((dayRuleSup.value as number) - thisWeek)
-          }
-        }
-        // 判断时间值是否小于10置换成“05”这种格式
-        DD = DD < 10 ? '0' + DD : DD
-
-        // 循环“时”数组
-        goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
-          let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
-
-          // 如果到达最大值时
-          if (nMin > mDate[mDate.length - 1]) {
-            resetMin()
-            if (hi == hDate.length - 1) {
-              resetHour()
-              if (Di == DDate.length - 1) {
-                resetDay()
-                if (Mi == MDate.length - 1) {
-                  resetMonth()
-                  continue goYear
-                }
-                continue goMonth
-              }
-              continue goDay
-            }
-            continue
-          }
-          // 循环"分"数组
-          goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
-            let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi]
-
-            // 如果到达最大值时
-            if (nSecond > sDate[sDate.length - 1]) {
-              resetSecond()
-              if (mi == mDate.length - 1) {
-                resetMin()
-                if (hi == hDate.length - 1) {
-                  resetHour()
-                  if (Di == DDate.length - 1) {
-                    resetDay()
-                    if (Mi == MDate.length - 1) {
-                      resetMonth()
-                      continue goYear
-                    }
-                    continue goMonth
-                  }
-                  continue goDay
-                }
-                continue goHour
-              }
-              continue
-            }
-            // 循环"秒"数组
-            goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
-              let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si]
-              // 添加当前时间(时间合法性在日期循环时已经判断)
-              if (MM !== '00' && DD !== '00') {
-                resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
-                nums++
-              }
-              // 如果条数满了就退出循环
-              if (nums == 5) break goYear
-              // 如果到达最大值时
-              if (si == sDate.length - 1) {
-                resetSecond()
-                if (mi == mDate.length - 1) {
-                  resetMin()
-                  if (hi == hDate.length - 1) {
-                    resetHour()
-                    if (Di == DDate.length - 1) {
-                      resetDay()
-                      if (Mi == MDate.length - 1) {
-                        resetMonth()
-                        continue goYear
-                      }
-                      continue goMonth
-                    }
-                    continue goDay
-                  }
-                  continue goHour
-                }
-                continue goMin
-              }
-            } //goSecond
-          } //goMin
-        } //goHour
-      } //goDay
-    } //goMonth
-  }
-  // 判断100年内的结果条数
-  if (resultArr.length == 0) {
-    resultList.value = ['没有达到条件的结果!']
-  } else {
-    resultList.value = resultArr
-    if (resultArr.length !== 5) {
-      resultList.value.push('最近100年内只有上面' + resultArr.length + '条结果!')
-    }
-  }
-  // 计算完成-显示结果
-  isShow.value = true
-}
-
-/**
- * 用于计算某位数字在数组中的索引
- */
-function getIndex(arr, value): number {
-  if (value <= arr[0] || value > arr[arr.length - 1]) {
-    return 0
-  } else {
-    for (let i = 0; i < arr.length - 1; i++) {
-      if (value > arr[i] && value <= arr[i + 1]) {
-        return i + 1
-      }
-    }
-  }
-  return 0
-}
-
-function getYearArr(rule, year) {
-  dateArr.value[5] = getOrderArr(year, year + 100)
-  if (rule !== undefined) {
-    if (rule.indexOf('-') >= 0) {
-      dateArr.value[5] = getCycleArr(rule, year + 100, false)
-    } else if (rule.indexOf('/') >= 0) {
-      dateArr.value[5] = getAverageArr(rule, year + 100)
-    } else if (rule !== '*') {
-      dateArr.value[5] = getAssignArr(rule)
-    }
-  }
-}
-
-function getMonthArr(rule) {
-  dateArr.value[4] = getOrderArr(1, 12)
-  if (rule.indexOf('-') >= 0) {
-    dateArr.value[4] = getCycleArr(rule, 12, false)
-  } else if (rule.indexOf('/') >= 0) {
-    dateArr.value[4] = getAverageArr(rule, 12)
-  } else if (rule !== '*') {
-    dateArr.value[4] = getAssignArr(rule)
-  }
-}
-
-function getWeekArr(rule) {
-  // 只有当日期规则的两个值均为“”时则表达日期是有选项的
-  if (dayRule.value === '' && dayRuleSup.value === '') {
-    if (rule.indexOf('-') >= 0) {
-      dayRule.value = 'weekDay'
-      dayRuleSup.value = getCycleArr(rule, 7, false)
-    } else if (rule.indexOf('#') >= 0) {
-      dayRule.value = 'assWeek'
-      let matchRule = rule.match(/[0-9]{1}/g)
-      dayRuleSup.value = [Number(matchRule[1]), Number(matchRule[0])]
-      dateArr.value[3] = [1]
-      if (dayRuleSup.value[1] == 7) {
-        dayRuleSup.value[1] = 0
-      }
-    } else if (rule.indexOf('L') >= 0) {
-      dayRule.value = 'lastWeek'
-      dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0])
-      dateArr.value[3] = [31]
-      if (dayRuleSup.value == 7) {
-        dayRuleSup.value = 0
-      }
-    } else if (rule !== '*' && rule !== '?') {
-      dayRule.value = 'weekDay'
-      dayRuleSup.value = getAssignArr(rule)
-    }
-  }
-}
-
-function getDayArr(rule) {
-  dateArr.value[3] = getOrderArr(1, 31)
-  dayRule.value = ''
-  dayRuleSup.value = ''
-  if (rule.indexOf('-') >= 0) {
-    dateArr.value[3] = getCycleArr(rule, 31, false)
-    dayRuleSup.value = 'null'
-  } else if (rule.indexOf('/') >= 0) {
-    dateArr.value[3] = getAverageArr(rule, 31)
-    dayRuleSup.value = 'null'
-  } else if (rule.indexOf('W') >= 0) {
-    dayRule.value = 'workDay'
-    dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0])
-    dateArr.value[3] = [dayRuleSup.value]
-  } else if (rule.indexOf('L') >= 0) {
-    dayRule.value = 'lastDay'
-    dayRuleSup.value = 'null'
-    dateArr.value[3] = [31]
-  } else if (rule !== '*' && rule !== '?') {
-    dateArr.value[3] = getAssignArr(rule)
-    dayRuleSup.value = 'null'
-  } else if (rule == '*') {
-    dayRuleSup.value = 'null'
-  }
-}
-
-function getHourArr(rule) {
-  dateArr.value[2] = getOrderArr(0, 23)
-  if (rule.indexOf('-') >= 0) {
-    dateArr.value[2] = getCycleArr(rule, 24, true)
-  } else if (rule.indexOf('/') >= 0) {
-    dateArr.value[2] = getAverageArr(rule, 23)
-  } else if (rule !== '*') {
-    dateArr.value[2] = getAssignArr(rule)
-  }
-}
-
-function getMinArr(rule) {
-  dateArr.value[1] = getOrderArr(0, 59)
-  if (rule.indexOf('-') >= 0) {
-    dateArr.value[1] = getCycleArr(rule, 60, true)
-  } else if (rule.indexOf('/') >= 0) {
-    dateArr.value[1] = getAverageArr(rule, 59)
-  } else if (rule !== '*') {
-    dateArr.value[1] = getAssignArr(rule)
-  }
-}
-
-function getSecondArr(rule) {
-  dateArr.value[0] = getOrderArr(0, 59)
-  if (rule.indexOf('-') >= 0) {
-    dateArr.value[0] = getCycleArr(rule, 60, true)
-  } else if (rule.indexOf('/') >= 0) {
-    dateArr.value[0] = getAverageArr(rule, 59)
-  } else if (rule !== '*') {
-    dateArr.value[0] = getAssignArr(rule)
-  }
-}
-
-function getOrderArr(min: number, max: number): number[] {
-  let arr: number[] = []
-  for (let i = min; i <= max; i++) {
-    arr.push(i)
-  }
-  return arr
-}
-
-function getAssignArr(rule) {
-  let arr: number[] = []
-  let assiginArr = rule.split(',')
-  for (let i = 0; i < assiginArr.length; i++) {
-    arr[i] = Number(assiginArr[i])
-  }
-  arr.sort(compare)
-  return arr
-}
-
-function compare(value1, value2) {
-  if (value2 - value1 > 0) {
-    return -1
-  } else {
-    return 1
-  }
-}
-
-function getAverageArr(rule, limit): number[] {
-  let arr: number[] = []
-  let agArr = rule.split('/')
-  let min = Number(agArr[0])
-  let step = Number(agArr[1])
-  while (min <= limit) {
-    arr.push(min)
-    min += step
-  }
-  return arr
-}
-
-function getCycleArr(rule, limit: number, status): number[] {
-  // status--表示是否从0开始(则从1开始)
-  let arr: number[] = []
-  let cycleArr = rule.split('-')
-  let min = Number(cycleArr[0])
-  let max = Number(cycleArr[1])
-  if (min > max) {
-    max += limit
-  }
-  for (let i = min; i <= max; i++) {
-    let add = 0
-    if (status == false && i % limit == 0) {
-      add = limit
-    }
-    arr.push(Math.round((i % limit) + add))
-  }
-  arr.sort(compare)
-  return arr
-}
-
-function formatDate(value, type?) {
-  // 计算日期相关值
-  let time = typeof value == 'number' ? new Date(value) : value
-  let Y = time.getFullYear()
-  let M = time.getMonth() + 1
-  let D = time.getDate()
-  let h = time.getHours()
-  let m = time.getMinutes()
-  let s = time.getSeconds()
-  let week = time.getDay()
-  // 如果传递了type的话
-  if (type == undefined) {
-    return (
-      Y +
-      '-' +
-      (M < 10 ? '0' + M : M) +
-      '-' +
-      (D < 10 ? '0' + D : D) +
-      ' ' +
-      (h < 10 ? '0' + h : h) +
-      ':' +
-      (m < 10 ? '0' + m : m) +
-      ':' +
-      (s < 10 ? '0' + s : s)
-    )
-  } else if (type == 'week') {
-    // 在quartz中 1为星期日
-    return week + 1
-  }
-}
-
-function checkDate(value) {
-  let time = new Date(value)
-  let format = formatDate(time)
-  return value === format
-}
-</script>
-<template>
-  <div class="popup-result">
-    <p class="title">最近5次运行时间</p>
-    <ul class="popup-result-scroll">
-      <template v-if="isShow">
-        <li v-for="item in resultList" :key="item">{{ item }}</li>
-      </template>
-      <li v-else>计算结果中...</li>
-    </ul>
-  </div>
-</template>

+ 0 - 120
yudao-ui-admin-vue3/src/components/Crontab/src/components/second.vue

@@ -1,120 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-const emits = defineEmits(['update'])
-
-const radioValue = ref(1)
-const cycle01 = ref(1)
-const cycle02 = ref(2)
-const average01 = ref(0)
-const average02 = ref(1)
-const checkboxList = ref([])
-
-defineExpose({
-  radioValue,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, 0, 58)
-  const cycle2 = props.check(cycle02.value, cycle1 ? cycle1 + 1 : 1, 59)
-  return cycle1 + '-' + cycle2
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 2) {
-    emits('update', 'second', cycleTotal)
-  }
-})
-
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, 0, 58)
-  const average2 = props.check(average02.value, 1, 59 - average1 || 0)
-  return average1 + '/' + average2
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'second', averageTotal)
-  }
-})
-
-const checkboxString = computed(() => {
-  let str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'second', checkboxString)
-  }
-})
-
-watch(radioValue, () => {
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'second', '*', 'second')
-      break
-    case 2:
-      emits('update', 'second', cycleTotal)
-      break
-    case 3:
-      emits('update', 'second', averageTotal)
-      break
-    case 4:
-      emits('update', 'second', checkboxString)
-      break
-  }
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="1"> 秒,允许的通配符[, - * /] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="2">
-        周期从
-        <el-input-number v-model="cycle01" :min="0" :max="58" /> -
-        <el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 秒
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="3">
-        从
-        <el-input-number v-model="average01" :min="0" :max="58" /> 秒开始,每
-        <el-input-number v-model="average02" :min="1" :max="59 - average01 || 0" /> 秒执行一次
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="4">
-        指定
-        <el-select
-          clearable
-          v-model="checkboxList"
-          placeholder="可多选"
-          multiple
-          style="width: 100%"
-        >
-          <el-option v-for="item in 60" :key="item" :value="item - 1">{{ item - 1 }}</el-option>
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 223
yudao-ui-admin-vue3/src/components/Crontab/src/components/week.vue

@@ -1,223 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-const emits = defineEmits(['update'])
-
-const radioValue = ref<number>(2)
-const weekday = ref<number>(2)
-const cycle01 = ref<number>(2)
-const cycle02 = ref<number>(3)
-const average01 = ref<number>(1)
-const average02 = ref<number>(2)
-const checkboxList = ref([])
-const weekList = ref([
-  {
-    key: 2,
-    value: '星期一'
-  },
-  {
-    key: 3,
-    value: '星期二'
-  },
-  {
-    key: 4,
-    value: '星期三'
-  },
-  {
-    key: 5,
-    value: '星期四'
-  },
-  {
-    key: 6,
-    value: '星期五'
-  },
-  {
-    key: 7,
-    value: '星期六'
-  },
-  {
-    key: 1,
-    value: '星期日'
-  }
-])
-
-defineExpose({
-  radioValue,
-  weekday,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, 1, 7)
-  const cycle2 = props.check(cycle02.value, 1, 7)
-  return cycle1 + '-' + cycle2
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'month', cycleTotal)
-  }
-})
-
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, 1, 4)
-  const average2 = props.check(average02.value, 1, 7)
-  return average1 + '#' + average2
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'month', averageTotal)
-  }
-})
-
-const weekdayCheck = computed(() => {
-  return props.check(weekday.value, 1, 7)
-})
-
-watch(weekdayCheck, () => {
-  if (parseInt(radioValue.value.toString()) === 5) {
-    emits('update', 'week', weekday.value + 'L')
-  }
-})
-
-const checkboxString = computed(() => {
-  let str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 6) {
-    emits('update', 'month', checkboxString)
-  }
-})
-
-watch(radioValue, () => {
-  if (parseInt(radioValue.value.toString()) !== 2 && radioValue.value.toString() !== '?') {
-    emits('update', 'day', '?', 'week')
-  }
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'week', '*')
-      break
-    case 2:
-      emits('update', 'week', '?')
-      break
-    case 3:
-      emits('update', 'week', cycleTotal)
-      break
-    case 4:
-      emits('update', 'week', averageTotal)
-      break
-    case 5:
-      emits('update', 'week', weekdayCheck.value + 'L')
-      break
-    case 6:
-      emits('update', 'week', checkboxString)
-      break
-  }
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="1"> 周,允许的通配符[, - * ? / L #] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="2"> 不指定 </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="3">
-        周期从星期
-        <el-select clearable v-model="cycle01">
-          <el-option
-            v-for="(item, index) of weekList"
-            :key="index"
-            :label="item.value"
-            :value="item.key"
-            :disabled="item.key === 1"
-            >{{ item.value }}</el-option
-          >
-        </el-select>
-        -
-        <el-select clearable v-model="cycle02">
-          <el-option
-            v-for="(item, index) of weekList"
-            :key="index"
-            :label="item.value"
-            :value="item.key"
-            :disabled="item.key < cycle01 && item.key !== 1"
-            >{{ item.value }}</el-option
-          >
-        </el-select>
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="4">
-        第
-        <el-input-number v-model="average01" :min="1" :max="4" /> 周的星期
-        <el-select clearable v-model="average02">
-          <el-option
-            v-for="(item, index) of weekList"
-            :key="index"
-            :label="item.value"
-            :value="item.key"
-            >{{ item.value }}</el-option
-          >
-        </el-select>
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="5">
-        本月最后一个星期
-        <el-select clearable v-model="weekday">
-          <el-option
-            v-for="(item, index) of weekList"
-            :key="index"
-            :label="item.value"
-            :value="item.key"
-            >{{ item.value }}</el-option
-          >
-        </el-select>
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio v-model="radioValue" :label="6">
-        指定
-        <el-select
-          clearable
-          v-model="checkboxList"
-          placeholder="可多选"
-          multiple
-          style="width: 100%"
-        >
-          <el-option
-            v-for="(item, index) of weekList"
-            :key="index"
-            :label="item.value"
-            :value="String(item.key)"
-            >{{ item.value }}</el-option
-          >
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 139
yudao-ui-admin-vue3/src/components/Crontab/src/components/year.vue

@@ -1,139 +0,0 @@
-<script setup lang="ts">
-import { computed, onMounted, ref, watch } from 'vue'
-import { ElForm, ElFormItem, ElRadio, ElSelect, ElOption, ElInputNumber } from 'element-plus'
-const props = defineProps({
-  check: {
-    type: Function,
-    required: true
-  },
-  cron: {
-    type: Object
-  }
-})
-const emits = defineEmits(['update'])
-
-const fullYear = ref<number>(0)
-const radioValue = ref<number>(1)
-const cycle01 = ref<number>(0)
-const cycle02 = ref<number>(0)
-const average01 = ref<number>(0)
-const average02 = ref<number>(1)
-const checkboxList = ref([])
-
-defineExpose({
-  fullYear,
-  radioValue,
-  cycle01,
-  cycle02,
-  average01,
-  average02,
-  checkboxList
-})
-
-const cycleTotal = computed(() => {
-  const cycle1 = props.check(cycle01.value, fullYear.value, 2098)
-  const cycle2 = props.check(cycle02.value, cycle1 ? cycle1 + 1 : fullYear.value, 2099)
-  return cycle1 + '-' + cycle2
-})
-
-watch(cycleTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 3) {
-    emits('update', 'year', cycleTotal)
-  }
-})
-
-const averageTotal = computed(() => {
-  const average1 = props.check(average01.value, fullYear.value, 2098)
-  const average2 = props.check(average02.value, 1, 2099 - average1 || fullYear.value)
-  return average1 + '/' + average2
-})
-
-watch(averageTotal, () => {
-  if (parseInt(radioValue.value.toString()) === 4) {
-    emits('update', 'year', averageTotal)
-  }
-})
-
-const checkboxString = computed(() => {
-  let str = checkboxList.value.join()
-  return str.length === 0 ? '*' : str
-})
-
-watch(checkboxString, () => {
-  if (parseInt(radioValue.value.toString()) === 5) {
-    emits('update', 'year', checkboxString)
-  }
-})
-
-watch(radioValue, () => {
-  switch (parseInt(radioValue.value.toString())) {
-    case 1:
-      emits('update', 'year', '')
-      break
-    case 2:
-      emits('update', 'year', '*')
-      break
-    case 3:
-      emits('update', 'year', cycleTotal, 'min')
-      break
-    case 4:
-      emits('update', 'year', averageTotal, 'min')
-      break
-    case 5:
-      emits('update', 'year', checkboxString, 'min')
-      break
-  }
-})
-
-onMounted(() => {
-  fullYear.value = Number(new Date().getFullYear())
-  cycle01.value = fullYear.value
-  average01.value = fullYear.value
-})
-</script>
-<template>
-  <el-form>
-    <el-form-item>
-      <el-radio label="1" v-model="radioValue"> 不填,允许的通配符[, - * /] </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio label="2" v-model="radioValue"> 每年 </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio label="3" v-model="radioValue">
-        周期从
-        <el-input-number v-model="cycle01" :min="fullYear" :max="2098" /> -
-        <el-input-number
-          v-model="cycle02"
-          :min="cycle01 ? cycle01 + 1 : fullYear + 1"
-          :max="2099"
-        />
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio label="4" v-model="radioValue">
-        从
-        <el-input-number v-model="average01" :min="fullYear" :max="2098" /> 年开始,每
-        <el-input-number v-model="average02" :min="1" :max="2099 - average01 || fullYear" />
-        年执行一次
-      </el-radio>
-    </el-form-item>
-
-    <el-form-item>
-      <el-radio label="5" v-model="radioValue">
-        指定
-        <el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
-          <el-option
-            v-for="item in 9"
-            :key="item"
-            :value="item - 1 + fullYear"
-            :label="item - 1 + fullYear"
-          />
-        </el-select>
-      </el-radio>
-    </el-form-item>
-  </el-form>
-</template>

+ 0 - 437
yudao-ui-admin-vue3/src/components/Crontab/src/index.vue

@@ -1,437 +0,0 @@
-<script setup lang="ts">
-import {
-  CrontabSecond,
-  CrontabMin,
-  CrontabHour,
-  CrontabDay,
-  CrontabMonth,
-  CrontabWeek,
-  CrontabYear,
-  CrontabResult
-} from './components'
-import { ElTabs, ElTabPane } from 'element-plus'
-import { computed, defineEmits, defineProps, onMounted, Ref, ref, watch } from 'vue'
-
-const cronsecond = ref(null)
-const cronmin = ref(null)
-const cronhour = ref(null)
-const cronday = ref(null)
-const cronmonth = ref(null)
-const cronweek = ref(null)
-const cronyear = ref(null)
-
-const refs = ref<Record<string, Ref>>({})
-onMounted(() => {
-  refs.value.cronsecond = cronsecond
-  refs.value.cronmin = cronmin
-  refs.value.cronhour = cronhour
-  refs.value.cronday = cronday
-  refs.value.cronmonth = cronmonth
-  refs.value.cronweek = cronweek
-  refs.value.cronyear = cronyear
-})
-
-const props = defineProps({
-  expression: {
-    type: String,
-    required: false
-  },
-  hideComponent: {
-    type: Array
-  }
-})
-
-const emit = defineEmits(['hide', 'fill'])
-
-const tabTitles = ['秒', '分钟', '小时', '日', '月', '周', '年']
-
-const crontabValueObj = ref({
-  second: '*',
-  min: '*',
-  hour: '*',
-  day: '*',
-  month: '*',
-  week: '?',
-  year: ''
-})
-
-function shouldHide(key) {
-  return !(props.hideComponent && props.hideComponent.includes(key))
-}
-
-function resolveExp() {
-  // 反解析 表达式
-  if (props.expression) {
-    let arr = props.expression.split(' ')
-    if (arr.length >= 6) {
-      //6 位以上是合法表达式
-      let obj = {
-        second: arr[0],
-        min: arr[1],
-        hour: arr[2],
-        day: arr[3],
-        month: arr[4],
-        week: arr[5],
-        year: arr[6] ? arr[6] : ''
-      }
-      crontabValueObj.value = {
-        ...obj
-      }
-      for (let i in obj) {
-        if (obj[i]) {
-          changeRadio(i, obj[i])
-        }
-      }
-    }
-  } else {
-    // 没有传入的表达式 则还原
-    clearCron()
-  }
-}
-
-// 由子组件触发,更改表达式组成的字段值
-function updateCrontabValue(name, value, from) {
-  crontabValueObj.value[name] = value
-  if (from && from !== name) {
-    console.log(`来自组件 ${from} 改变了 ${name} ${value}`)
-    changeRadio(name, value)
-  }
-}
-// 赋值到组件
-function changeRadio(name, value) {
-  let arr = ['second', 'min', 'hour', 'month'],
-    refName = 'cron' + name,
-    insValue
-
-  if (!refs.value[refName]) return
-
-  if (arr.includes(name)) {
-    if (value === '*') {
-      insValue = 1
-    } else if (value.indexOf('-') > -1) {
-      let indexArr = value.split('-')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].cycle01 = 0)
-        : (refs.value[refName].cycle01 = indexArr[0])
-      refs.value[refName].cycle02 = indexArr[1]
-      insValue = 2
-    } else if (value.indexOf('/') > -1) {
-      let indexArr = value.split('/')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].average01 = 0)
-        : (refs.value[refName].average01 = indexArr[0])
-      refs.value[refName].average02 = indexArr[1]
-      insValue = 3
-    } else {
-      insValue = 4
-      refs.value[refName].checkboxList = value.split(',')
-    }
-  } else if (name == 'day') {
-    if (value === '*') {
-      insValue = 1
-    } else if (value == '?') {
-      insValue = 2
-    } else if (value.indexOf('-') > -1) {
-      let indexArr = value.split('-')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].cycle01 = 0)
-        : (refs.value[refName].cycle01 = indexArr[0])
-      refs.value[refName].cycle02 = indexArr[1]
-      insValue = 3
-    } else if (value.indexOf('/') > -1) {
-      let indexArr = value.split('/')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].average01 = 0)
-        : (refs.value[refName].average01 = indexArr[0])
-      refs.value[refName].average02 = indexArr[1]
-      insValue = 4
-    } else if (value.indexOf('W') > -1) {
-      let indexArr = value.split('W')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].workday = 0)
-        : (refs.value[refName].workday = indexArr[0])
-      insValue = 5
-    } else if (value === 'L') {
-      insValue = 6
-    } else {
-      refs.value[refName].checkboxList = value.split(',')
-      insValue = 7
-    }
-  } else if (name == 'week') {
-    if (value === '*') {
-      insValue = 1
-    } else if (value == '?') {
-      insValue = 2
-    } else if (value.indexOf('-') > -1) {
-      let indexArr = value.split('-')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].cycle01 = 0)
-        : (refs.value[refName].cycle01 = indexArr[0])
-      refs.value[refName].cycle02 = indexArr[1]
-      insValue = 3
-    } else if (value.indexOf('#') > -1) {
-      let indexArr = value.split('#')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].average01 = 1)
-        : (refs.value[refName].average01 = indexArr[0])
-      refs.value[refName].average02 = indexArr[1]
-      insValue = 4
-    } else if (value.indexOf('L') > -1) {
-      let indexArr = value.split('L')
-      isNaN(indexArr[0])
-        ? (refs.value[refName].weekday = 1)
-        : (refs.value[refName].weekday = indexArr[0])
-      insValue = 5
-    } else {
-      refs.value[refName].checkboxList = value.split(',')
-      insValue = 6
-    }
-  } else if (name == 'year') {
-    if (value == '') {
-      insValue = 1
-    } else if (value == '*') {
-      insValue = 2
-    } else if (value.indexOf('-') > -1) {
-      insValue = 3
-    } else if (value.indexOf('/') > -1) {
-      insValue = 4
-    } else {
-      refs.value[refName].checkboxList = value.split(',')
-      insValue = 5
-    }
-  }
-  refs.value[refName].radioValue = insValue
-}
-
-// 表单选项的子组件校验数字格式(通过-props传递)
-function checkNumber(value, minLimit, maxLimit) {
-  // 检查必须为整数
-  value = Math.floor(value)
-  if (value < minLimit) {
-    value = minLimit
-  } else if (value > maxLimit) {
-    value = maxLimit
-  }
-  return value
-}
-
-// 隐藏弹窗
-function hidePopup() {
-  emit('hide')
-}
-
-// 填充表达式
-function submitFill() {
-  emit('fill', crontabValueString)
-  hidePopup()
-}
-
-const crontabValueString = computed(() => {
-  let obj = crontabValueObj.value
-  return (
-    obj.second +
-    ' ' +
-    obj.min +
-    ' ' +
-    obj.hour +
-    ' ' +
-    obj.day +
-    ' ' +
-    obj.month +
-    ' ' +
-    obj.week +
-    (obj.year === '' ? '' : ' ' + obj.year)
-  )
-})
-
-function clearCron() {
-  // 还原选择项
-  crontabValueObj.value = {
-    second: '*',
-    min: '*',
-    hour: '*',
-    day: '*',
-    month: '*',
-    week: '?',
-    year: ''
-  }
-  for (let j in crontabValueObj.value) {
-    changeRadio(j, crontabValueObj.value[j])
-  }
-}
-
-watch(() => props.expression, resolveExp)
-</script>
-<template>
-  <div>
-    <el-tabs type="border-card">
-      <el-tab-pane label="秒" v-if="shouldHide('second')">
-        <CrontabSecond
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronsecond"
-        />
-      </el-tab-pane>
-
-      <el-tab-pane label="分钟" v-if="shouldHide('min')">
-        <CrontabMin
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronmin"
-        />
-      </el-tab-pane>
-
-      <el-tab-pane label="小时" v-if="shouldHide('hour')">
-        <CrontabHour
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronhour"
-        />
-      </el-tab-pane>
-
-      <el-tab-pane label="日" v-if="shouldHide('day')">
-        <CrontabDay
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronday"
-        />
-      </el-tab-pane>
-
-      <el-tab-pane label="月" v-if="shouldHide('month')">
-        <CrontabMonth
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronmonth"
-        />
-      </el-tab-pane>
-
-      <el-tab-pane label="周" v-if="shouldHide('week')">
-        <CrontabWeek
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronweek"
-        />
-      </el-tab-pane>
-
-      <el-tab-pane label="年" v-if="shouldHide('year')">
-        <CrontabYear
-          @update="updateCrontabValue"
-          :check="checkNumber"
-          :cron="crontabValueObj"
-          ref="cronyear"
-        />
-      </el-tab-pane>
-    </el-tabs>
-
-    <div class="popup-main">
-      <div class="popup-result">
-        <p class="title">时间表达式</p>
-        <table>
-          <thead>
-            <th v-for="item of tabTitles" width="40" :key="item">{{ item }}</th>
-            <th>Cron 表达式</th>
-          </thead>
-          <tbody>
-            <td>
-              <span>{{ crontabValueObj.second }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueObj.min }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueObj.hour }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueObj.day }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueObj.month }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueObj.week }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueObj.year }}</span>
-            </td>
-            <td>
-              <span>{{ crontabValueString }}</span>
-            </td>
-          </tbody>
-        </table>
-      </div>
-      <CrontabResult :ex="crontabValueString" />
-
-      <div class="pop_btn">
-        <el-button type="primary" @click="submitFill">确定</el-button>
-        <el-button type="warning" @click="clearCron">重置</el-button>
-        <el-button @click="hidePopup">取消</el-button>
-      </div>
-    </div>
-  </div>
-</template>
-<style scoped>
-.pop_btn {
-  text-align: center;
-  margin-top: 20px;
-}
-.popup-main {
-  position: relative;
-  margin: 10px auto;
-  background: #fff;
-  border-radius: 5px;
-  font-size: 12px;
-  overflow: hidden;
-}
-.popup-title {
-  overflow: hidden;
-  line-height: 34px;
-  padding-top: 6px;
-  background: #f2f2f2;
-}
-.popup-result {
-  box-sizing: border-box;
-  line-height: 24px;
-  margin: 25px auto;
-  padding: 15px 10px 10px;
-  border: 1px solid #ccc;
-  position: relative;
-}
-.popup-result .title {
-  position: absolute;
-  top: -28px;
-  left: 50%;
-  width: 140px;
-  font-size: 14px;
-  margin-left: -70px;
-  text-align: center;
-  line-height: 30px;
-  background: #fff;
-}
-.popup-result table {
-  text-align: center;
-  width: 100%;
-  margin: 0 auto;
-}
-.popup-result table span {
-  display: block;
-  width: 100%;
-  font-family: arial;
-  line-height: 30px;
-  height: 30px;
-  white-space: nowrap;
-  overflow: hidden;
-  border: 1px solid #e8e8e8;
-}
-.popup-result-scroll {
-  font-size: 12px;
-  line-height: 24px;
-  height: 10em;
-  overflow-y: auto;
-}
-</style>

+ 48 - 2
yudao-ui-admin-vue3/src/views/infra/job/index.vue

@@ -1,4 +1,5 @@
 <script lang="ts" setup>
+import { Crontab } from '@/components/Crontab'
 import { ref, unref } from 'vue'
 import DictTag from '@/components/DictTag/src/DictTag.vue'
 import * as JobApi from '@/api/infra/job'
@@ -11,6 +12,7 @@ import { FormExpose } from '@/components/Form'
 import { rules, allSchemas } from './job.data'
 import { useRouter } from 'vue-router'
 import { useMessage } from '@/hooks/web/useMessage'
+import { InfraJobStatusEnum } from '@/utils/constants'
 const message = useMessage()
 const { t } = useI18n() // 国际化
 const { push } = useRouter()
@@ -28,7 +30,13 @@ const actionType = ref('') // 操作按钮的类型
 const dialogVisible = ref(false) // 是否显示弹出层
 const dialogTitle = ref('edit') // 弹出层标题
 const formRef = ref<FormExpose>() // 表单 Ref
-
+const cronExpression = ref('')
+const shortcuts = ref([
+  {
+    text: '每天8点和12点 (自定义追加)',
+    value: '0 0 8,12 * * ?'
+  }
+])
 // 设置标题
 const setDialogTile = (type: string) => {
   dialogTitle.value = t('action.' + type)
@@ -38,6 +46,7 @@ const setDialogTile = (type: string) => {
 
 // 新增操作
 const handleCreate = () => {
+  cronExpression.value = ''
   setDialogTile('create')
   // 重置表单
   unref(formRef)?.getElFormRef()?.resetFields()
@@ -48,8 +57,31 @@ const handleUpdate = async (row: JobVO) => {
   setDialogTile('update')
   // 设置数据
   const res = await JobApi.getJobApi(row.id)
+  cronExpression.value = res.cronExpression
   unref(formRef)?.setValues(res)
 }
+const handleChangeStatus = async (row: JobVO) => {
+  const text = row.status === InfraJobStatusEnum.STOP ? '开启' : '关闭'
+  const status =
+    row.status === InfraJobStatusEnum.STOP ? InfraJobStatusEnum.NORMAL : InfraJobStatusEnum.STOP
+  message
+    .confirm('确认要' + text + '定时任务编号为"' + row.id + '"的数据项?', t('common.reminder'))
+    .then(async () => {
+      row.status =
+        row.status === InfraJobStatusEnum.NORMAL
+          ? InfraJobStatusEnum.NORMAL
+          : InfraJobStatusEnum.STOP
+      await JobApi.updateJobStatusApi(row.id, status)
+      message.success(text + '成功')
+      await getList()
+    })
+    .catch(() => {
+      row.status =
+        row.status === InfraJobStatusEnum.NORMAL
+          ? InfraJobStatusEnum.STOP
+          : InfraJobStatusEnum.NORMAL
+    })
+}
 // 执行日志
 const handleJobLog = (row: JobVO) => {
   if (row.id) {
@@ -72,6 +104,7 @@ const submitForm = async () => {
   // 提交请求
   try {
     const data = unref(formRef)?.formModel as JobVO
+    data.cronExpression = cronExpression.value
     if (actionType.value === 'create') {
       await JobApi.createJobApi(data)
       message.success(t('common.createSuccess'))
@@ -144,6 +177,15 @@ getList()
         <el-button link type="primary" v-hasPermi="['infra:job:update']" @click="handleUpdate(row)">
           <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
         </el-button>
+        <el-button
+          link
+          type="primary"
+          v-hasPermi="['infra:job:update']"
+          @click="handleChangeStatus(row)"
+        >
+          <Icon icon="ep:edit" class="mr-1px" />
+          {{ row.status === InfraJobStatusEnum.STOP ? '开启' : '暂停' }}
+        </el-button>
         <el-button link type="primary" v-hasPermi="['infra:job:query']" @click="handleDetail(row)">
           <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
         </el-button>
@@ -171,7 +213,11 @@ getList()
       :schema="allSchemas.formSchema"
       :rules="rules"
       ref="formRef"
-    />
+    >
+      <template #cronExpression>
+        <Crontab v-model="cronExpression" :shortcuts="shortcuts" />
+      </template>
+    </Form>
     <!-- 对话框(详情) -->
     <Descriptions
       v-if="actionType === 'detail'"

+ 7 - 1
yudao-ui-admin-vue3/src/views/infra/job/job.data.ts

@@ -36,7 +36,13 @@ const crudSchemas = reactive<CrudSchema[]>([
   {
     label: t('common.status'),
     field: 'status',
-    dictType: DICT_TYPE.INFRA_JOB_STATUS
+    dictType: DICT_TYPE.INFRA_JOB_STATUS,
+    form: {
+      show: false
+    },
+    detail: {
+      show: false
+    }
   },
   {
     label: '处理器的名字',