Crontab.vue 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. <!--
  2. * @Descripttion: cron规则生成器
  3. * @version: 1.0
  4. * @Author: sakuya
  5. * @Date: 2021年12月29日15:23:54
  6. * @LastEditors:
  7. * @LastEditTime:
  8. -->
  9. <script setup lang="ts">
  10. import { ElMessage } from 'element-plus'
  11. import { ref, computed, onMounted, reactive, watch, PropType } from 'vue'
  12. interface shortcutsType {
  13. text: string
  14. value: string
  15. }
  16. const props = defineProps({
  17. modelValue: { type: String, default: '* * * * * ?' },
  18. shortcuts: { type: Array as PropType<shortcutsType[]>, default: () => [] }
  19. })
  20. const defaultValue = ref('')
  21. const dialogVisible = ref(false)
  22. const getYear = () => {
  23. let v: number[] = []
  24. let y = new Date().getFullYear()
  25. for (let i = 0; i < 11; i++) {
  26. v.push(y + i)
  27. }
  28. return v
  29. }
  30. const cronValue = reactive({
  31. second: {
  32. type: '0',
  33. range: {
  34. start: 1,
  35. end: 2
  36. },
  37. loop: {
  38. start: 0,
  39. end: 1
  40. },
  41. appoint: [] as string[]
  42. },
  43. minute: {
  44. type: '0',
  45. range: {
  46. start: 1,
  47. end: 2
  48. },
  49. loop: {
  50. start: 0,
  51. end: 1
  52. },
  53. appoint: [] as string[]
  54. },
  55. hour: {
  56. type: '0',
  57. range: {
  58. start: 1,
  59. end: 2
  60. },
  61. loop: {
  62. start: 0,
  63. end: 1
  64. },
  65. appoint: [] as string[]
  66. },
  67. day: {
  68. type: '0',
  69. range: {
  70. start: 1,
  71. end: 2
  72. },
  73. loop: {
  74. start: 1,
  75. end: 1
  76. },
  77. appoint: [] as string[]
  78. },
  79. month: {
  80. type: '0',
  81. range: {
  82. start: 1,
  83. end: 2
  84. },
  85. loop: {
  86. start: 1,
  87. end: 1
  88. },
  89. appoint: [] as string[]
  90. },
  91. week: {
  92. type: '5',
  93. range: {
  94. start: '2',
  95. end: '3'
  96. },
  97. loop: {
  98. start: 0,
  99. end: '2'
  100. },
  101. last: '2',
  102. appoint: [] as string[]
  103. },
  104. year: {
  105. type: '-1',
  106. range: {
  107. start: getYear()[0],
  108. end: getYear()[1]
  109. },
  110. loop: {
  111. start: getYear()[0],
  112. end: 1
  113. },
  114. appoint: [] as string[]
  115. }
  116. })
  117. const data = reactive({
  118. second: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
  119. minute: ['0', '5', '15', '20', '25', '30', '35', '40', '45', '50', '55', '59'],
  120. hour: [
  121. '0',
  122. '1',
  123. '2',
  124. '3',
  125. '4',
  126. '5',
  127. '6',
  128. '7',
  129. '8',
  130. '9',
  131. '10',
  132. '11',
  133. '12',
  134. '13',
  135. '14',
  136. '15',
  137. '16',
  138. '17',
  139. '18',
  140. '19',
  141. '20',
  142. '21',
  143. '22',
  144. '23'
  145. ],
  146. day: [
  147. '1',
  148. '2',
  149. '3',
  150. '4',
  151. '5',
  152. '6',
  153. '7',
  154. '8',
  155. '9',
  156. '10',
  157. '11',
  158. '12',
  159. '13',
  160. '14',
  161. '15',
  162. '16',
  163. '17',
  164. '18',
  165. '19',
  166. '20',
  167. '21',
  168. '22',
  169. '23',
  170. '24',
  171. '25',
  172. '26',
  173. '27',
  174. '28',
  175. '29',
  176. '30',
  177. '31'
  178. ],
  179. month: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
  180. week: [
  181. {
  182. value: '1',
  183. label: '周日'
  184. },
  185. {
  186. value: '2',
  187. label: '周一'
  188. },
  189. {
  190. value: '3',
  191. label: '周二'
  192. },
  193. {
  194. value: '4',
  195. label: '周三'
  196. },
  197. {
  198. value: '5',
  199. label: '周四'
  200. },
  201. {
  202. value: '6',
  203. label: '周五'
  204. },
  205. {
  206. value: '7',
  207. label: '周六'
  208. }
  209. ],
  210. year: getYear()
  211. })
  212. const value_second = computed(() => {
  213. let v = cronValue.second
  214. if (v.type == '0') {
  215. return '*'
  216. } else if (v.type == '1') {
  217. return v.range.start + '-' + v.range.end
  218. } else if (v.type == '2') {
  219. return v.loop.start + '/' + v.loop.end
  220. } else if (v.type == '3') {
  221. return v.appoint.length > 0 ? v.appoint.join(',') : '*'
  222. } else {
  223. return '*'
  224. }
  225. })
  226. const value_minute = computed(() => {
  227. let v = cronValue.minute
  228. if (v.type == '0') {
  229. return '*'
  230. } else if (v.type == '1') {
  231. return v.range.start + '-' + v.range.end
  232. } else if (v.type == '2') {
  233. return v.loop.start + '/' + v.loop.end
  234. } else if (v.type == '3') {
  235. return v.appoint.length > 0 ? v.appoint.join(',') : '*'
  236. } else {
  237. return '*'
  238. }
  239. })
  240. const value_hour = computed(() => {
  241. let v = cronValue.hour
  242. if (v.type == '0') {
  243. return '*'
  244. } else if (v.type == '1') {
  245. return v.range.start + '-' + v.range.end
  246. } else if (v.type == '2') {
  247. return v.loop.start + '/' + v.loop.end
  248. } else if (v.type == '3') {
  249. return v.appoint.length > 0 ? v.appoint.join(',') : '*'
  250. } else {
  251. return '*'
  252. }
  253. })
  254. const value_day = computed(() => {
  255. let v = cronValue.day
  256. if (v.type == '0') {
  257. return '*'
  258. } else if (v.type == '1') {
  259. return v.range.start + '-' + v.range.end
  260. } else if (v.type == '2') {
  261. return v.loop.start + '/' + v.loop.end
  262. } else if (v.type == '3') {
  263. return v.appoint.length > 0 ? v.appoint.join(',') : '*'
  264. } else if (v.type == '4') {
  265. return 'L'
  266. } else if (v.type == '5') {
  267. return '?'
  268. } else {
  269. return '*'
  270. }
  271. })
  272. const value_month = computed(() => {
  273. let v = cronValue.month
  274. if (v.type == '0') {
  275. return '*'
  276. } else if (v.type == '1') {
  277. return v.range.start + '-' + v.range.end
  278. } else if (v.type == '2') {
  279. return v.loop.start + '/' + v.loop.end
  280. } else if (v.type == '3') {
  281. return v.appoint.length > 0 ? v.appoint.join(',') : '*'
  282. } else {
  283. return '*'
  284. }
  285. })
  286. const value_week = computed(() => {
  287. let v = cronValue.week
  288. if (v.type == '0') {
  289. return '*'
  290. } else if (v.type == '1') {
  291. return v.range.start + '-' + v.range.end
  292. } else if (v.type == '2') {
  293. return v.loop.end + '#' + v.loop.start
  294. } else if (v.type == '3') {
  295. return v.appoint.length > 0 ? v.appoint.join(',') : '*'
  296. } else if (v.type == '4') {
  297. return v.last + 'L'
  298. } else if (v.type == '5') {
  299. return '?'
  300. } else {
  301. return '*'
  302. }
  303. })
  304. const value_year = computed(() => {
  305. let v = cronValue.year
  306. if (v.type == '-1') {
  307. return ''
  308. } else if (v.type == '0') {
  309. return '*'
  310. } else if (v.type == '1') {
  311. return v.range.start + '-' + v.range.end
  312. } else if (v.type == '2') {
  313. return v.loop.start + '/' + v.loop.end
  314. } else if (v.type == '3') {
  315. return v.appoint.length > 0 ? v.appoint.join(',') : ''
  316. } else {
  317. return ''
  318. }
  319. })
  320. watch(
  321. () => cronValue.week.type,
  322. (val) => {
  323. if (val != '5') {
  324. cronValue.day.type = '5'
  325. }
  326. }
  327. )
  328. watch(
  329. () => cronValue.day.type,
  330. (val) => {
  331. if (val != '5') {
  332. cronValue.week.type = '5'
  333. }
  334. }
  335. )
  336. watch(
  337. () => props.modelValue,
  338. () => {
  339. defaultValue.value = props.modelValue
  340. }
  341. )
  342. onMounted(() => {
  343. defaultValue.value = props.modelValue
  344. })
  345. const emit = defineEmits(['update:modelValue'])
  346. const handleShortcuts = (command) => {
  347. if (command == 'custom') {
  348. open()
  349. } else {
  350. defaultValue.value = command
  351. emit('update:modelValue', defaultValue.value)
  352. }
  353. }
  354. const open = () => {
  355. set()
  356. dialogVisible.value = true
  357. }
  358. const set = () => {
  359. defaultValue.value = props.modelValue
  360. let arr = (props.modelValue || '* * * * * ?').split(' ')
  361. //简单检查
  362. if (arr.length < 6) {
  363. ElMessage.warning('cron表达式错误,已转换为默认表达式')
  364. arr = '* * * * * ?'.split(' ')
  365. }
  366. //秒
  367. if (arr[0] == '*') {
  368. cronValue.second.type = '0'
  369. } else if (arr[0].includes('-')) {
  370. cronValue.second.type = '1'
  371. cronValue.second.range.start = Number(arr[0].split('-')[0])
  372. cronValue.second.range.end = Number(arr[0].split('-')[1])
  373. } else if (arr[0].includes('/')) {
  374. cronValue.second.type = '2'
  375. cronValue.second.loop.start = Number(arr[0].split('/')[0])
  376. cronValue.second.loop.end = Number(arr[0].split('/')[1])
  377. } else {
  378. cronValue.second.type = '3'
  379. cronValue.second.appoint = arr[0].split(',')
  380. }
  381. //分
  382. if (arr[1] == '*') {
  383. cronValue.minute.type = '0'
  384. } else if (arr[1].includes('-')) {
  385. cronValue.minute.type = '1'
  386. cronValue.minute.range.start = Number(arr[1].split('-')[0])
  387. cronValue.minute.range.end = Number(arr[1].split('-')[1])
  388. } else if (arr[1].includes('/')) {
  389. cronValue.minute.type = '2'
  390. cronValue.minute.loop.start = Number(arr[1].split('/')[0])
  391. cronValue.minute.loop.end = Number(arr[1].split('/')[1])
  392. } else {
  393. cronValue.minute.type = '3'
  394. cronValue.minute.appoint = arr[1].split(',')
  395. }
  396. //小时
  397. if (arr[2] == '*') {
  398. cronValue.hour.type = '0'
  399. } else if (arr[2].includes('-')) {
  400. cronValue.hour.type = '1'
  401. cronValue.hour.range.start = Number(arr[2].split('-')[0])
  402. cronValue.hour.range.end = Number(arr[2].split('-')[1])
  403. } else if (arr[2].includes('/')) {
  404. cronValue.hour.type = '2'
  405. cronValue.hour.loop.start = Number(arr[2].split('/')[0])
  406. cronValue.hour.loop.end = Number(arr[2].split('/')[1])
  407. } else {
  408. cronValue.hour.type = '3'
  409. cronValue.hour.appoint = arr[2].split(',')
  410. }
  411. //日
  412. if (arr[3] == '*') {
  413. cronValue.day.type = '0'
  414. } else if (arr[3] == 'L') {
  415. cronValue.day.type = '4'
  416. } else if (arr[3] == '?') {
  417. cronValue.day.type = '5'
  418. } else if (arr[3].includes('-')) {
  419. cronValue.day.type = '1'
  420. cronValue.day.range.start = Number(arr[3].split('-')[0])
  421. cronValue.day.range.end = Number(arr[3].split('-')[1])
  422. } else if (arr[3].includes('/')) {
  423. cronValue.day.type = '2'
  424. cronValue.day.loop.start = Number(arr[3].split('/')[0])
  425. cronValue.day.loop.end = Number(arr[3].split('/')[1])
  426. } else {
  427. cronValue.day.type = '3'
  428. cronValue.day.appoint = arr[3].split(',')
  429. }
  430. //月
  431. if (arr[4] == '*') {
  432. cronValue.month.type = '0'
  433. } else if (arr[4].includes('-')) {
  434. cronValue.month.type = '1'
  435. cronValue.month.range.start = Number(arr[4].split('-')[0])
  436. cronValue.month.range.end = Number(arr[4].split('-')[1])
  437. } else if (arr[4].includes('/')) {
  438. cronValue.month.type = '2'
  439. cronValue.month.loop.start = Number(arr[4].split('/')[0])
  440. cronValue.month.loop.end = Number(arr[4].split('/')[1])
  441. } else {
  442. cronValue.month.type = '3'
  443. cronValue.month.appoint = arr[4].split(',')
  444. }
  445. //周
  446. if (arr[5] == '*') {
  447. cronValue.week.type = '0'
  448. } else if (arr[5] == '?') {
  449. cronValue.week.type = '5'
  450. } else if (arr[5].includes('-')) {
  451. cronValue.week.type = '1'
  452. cronValue.week.range.start = arr[5].split('-')[0]
  453. cronValue.week.range.end = arr[5].split('-')[1]
  454. } else if (arr[5].includes('#')) {
  455. cronValue.week.type = '2'
  456. cronValue.week.loop.start = Number(arr[5].split('#')[1])
  457. cronValue.week.loop.end = arr[5].split('#')[0]
  458. } else if (arr[5].includes('L')) {
  459. cronValue.week.type = '4'
  460. cronValue.week.last = arr[5].split('L')[0]
  461. } else {
  462. cronValue.week.type = '3'
  463. cronValue.week.appoint = arr[5].split(',')
  464. }
  465. //年
  466. if (!arr[6]) {
  467. cronValue.year.type = '-1'
  468. } else if (arr[6] == '*') {
  469. cronValue.year.type = '0'
  470. } else if (arr[6].includes('-')) {
  471. cronValue.year.type = '1'
  472. cronValue.year.range.start = Number(arr[6].split('-')[0])
  473. cronValue.year.range.end = Number(arr[6].split('-')[1])
  474. } else if (arr[6].includes('/')) {
  475. cronValue.year.type = '2'
  476. cronValue.year.loop.start = Number(arr[6].split('/')[1])
  477. cronValue.year.loop.end = Number(arr[6].split('/')[0])
  478. } else {
  479. cronValue.year.type = '3'
  480. cronValue.year.appoint = arr[6].split(',')
  481. }
  482. }
  483. const submit = () => {
  484. let year = value_year.value ? ' ' + value_year.value : ''
  485. defaultValue.value =
  486. value_second.value +
  487. ' ' +
  488. value_minute.value +
  489. ' ' +
  490. value_hour.value +
  491. ' ' +
  492. value_day.value +
  493. ' ' +
  494. value_month.value +
  495. ' ' +
  496. value_week.value +
  497. year
  498. emit('update:modelValue', defaultValue.value)
  499. dialogVisible.value = false
  500. }
  501. </script>
  502. <template>
  503. <el-input v-model="defaultValue" v-bind="$attrs">
  504. <template #append>
  505. <el-dropdown split-button trigger="click" @command="handleShortcuts">
  506. 生成器
  507. <template #dropdown>
  508. <el-dropdown-menu>
  509. <el-dropdown-item command="0 * * * * ?">每分钟</el-dropdown-item>
  510. <el-dropdown-item command="0 0 * * * ?">每小时</el-dropdown-item>
  511. <el-dropdown-item command="0 0 0 * * ?">每天零点</el-dropdown-item>
  512. <el-dropdown-item command="0 0 0 1 * ?">每月一号零点</el-dropdown-item>
  513. <el-dropdown-item command="0 0 0 L * ?">每月最后一天零点</el-dropdown-item>
  514. <el-dropdown-item command="0 0 0 ? * 1">每周星期日零点</el-dropdown-item>
  515. <el-dropdown-item
  516. v-for="(item, index) in shortcuts"
  517. :key="item.value"
  518. :divided="index == 0"
  519. :command="item.value"
  520. >
  521. {{ item.text }}
  522. </el-dropdown-item>
  523. <el-dropdown-item divided command="custom">
  524. <Icon icon="ep:menu" />自定义
  525. </el-dropdown-item>
  526. </el-dropdown-menu>
  527. </template>
  528. </el-dropdown>
  529. </template>
  530. </el-input>
  531. <el-dialog
  532. title="cron规则生成器"
  533. v-model="dialogVisible"
  534. :width="580"
  535. destroy-on-close
  536. append-to-body
  537. >
  538. <div class="sc-cron">
  539. <el-tabs>
  540. <el-tab-pane>
  541. <template #label>
  542. <div class="sc-cron-num">
  543. <h2>秒</h2>
  544. <h4>{{ value_second }}</h4>
  545. </div>
  546. </template>
  547. <el-form>
  548. <el-form-item label="类型">
  549. <el-radio-group v-model="cronValue.second.type">
  550. <el-radio-button label="0">任意值</el-radio-button>
  551. <el-radio-button label="1">范围</el-radio-button>
  552. <el-radio-button label="2">间隔</el-radio-button>
  553. <el-radio-button label="3">指定</el-radio-button>
  554. </el-radio-group>
  555. </el-form-item>
  556. <el-form-item label="范围" v-if="cronValue.second.type == '1'">
  557. <el-input-number
  558. v-model="cronValue.second.range.start"
  559. :min="0"
  560. :max="59"
  561. controls-position="right"
  562. />
  563. <span style="padding: 0 15px">-</span>
  564. <el-input-number
  565. v-model="cronValue.second.range.end"
  566. :min="0"
  567. :max="59"
  568. controls-position="right"
  569. />
  570. </el-form-item>
  571. <el-form-item label="间隔" v-if="cronValue.second.type == '2'">
  572. <el-input-number
  573. v-model="cronValue.second.loop.start"
  574. :min="0"
  575. :max="59"
  576. controls-position="right"
  577. />
  578. 秒开始,每
  579. <el-input-number
  580. v-model="cronValue.second.loop.end"
  581. :min="0"
  582. :max="59"
  583. controls-position="right"
  584. />
  585. 秒执行一次
  586. </el-form-item>
  587. <el-form-item label="指定" v-if="cronValue.second.type == '3'">
  588. <el-select v-model="cronValue.second.appoint" multiple style="width: 100%">
  589. <el-option
  590. v-for="(item, index) in data.second"
  591. :key="index"
  592. :label="item"
  593. :value="item"
  594. />
  595. </el-select>
  596. </el-form-item>
  597. </el-form>
  598. </el-tab-pane>
  599. <el-tab-pane>
  600. <template #label>
  601. <div class="sc-cron-num">
  602. <h2>分钟</h2>
  603. <h4>{{ value_minute }}</h4>
  604. </div>
  605. </template>
  606. <el-form>
  607. <el-form-item label="类型">
  608. <el-radio-group v-model="cronValue.minute.type">
  609. <el-radio-button label="0">任意值</el-radio-button>
  610. <el-radio-button label="1">范围</el-radio-button>
  611. <el-radio-button label="2">间隔</el-radio-button>
  612. <el-radio-button label="3">指定</el-radio-button>
  613. </el-radio-group>
  614. </el-form-item>
  615. <el-form-item label="范围" v-if="cronValue.minute.type == '1'">
  616. <el-input-number
  617. v-model="cronValue.minute.range.start"
  618. :min="0"
  619. :max="59"
  620. controls-position="right"
  621. />
  622. <span style="padding: 0 15px">-</span>
  623. <el-input-number
  624. v-model="cronValue.minute.range.end"
  625. :min="0"
  626. :max="59"
  627. controls-position="right"
  628. />
  629. </el-form-item>
  630. <el-form-item label="间隔" v-if="cronValue.minute.type == '2'">
  631. <el-input-number
  632. v-model="cronValue.minute.loop.start"
  633. :min="0"
  634. :max="59"
  635. controls-position="right"
  636. />
  637. 分钟开始,每
  638. <el-input-number
  639. v-model="cronValue.minute.loop.end"
  640. :min="0"
  641. :max="59"
  642. controls-position="right"
  643. />
  644. 分钟执行一次
  645. </el-form-item>
  646. <el-form-item label="指定" v-if="cronValue.minute.type == '3'">
  647. <el-select v-model="cronValue.minute.appoint" multiple style="width: 100%">
  648. <el-option
  649. v-for="(item, index) in data.minute"
  650. :key="index"
  651. :label="item"
  652. :value="item"
  653. />
  654. </el-select>
  655. </el-form-item>
  656. </el-form>
  657. </el-tab-pane>
  658. <el-tab-pane>
  659. <template #label>
  660. <div class="sc-cron-num">
  661. <h2>小时</h2>
  662. <h4>{{ value_hour }}</h4>
  663. </div>
  664. </template>
  665. <el-form>
  666. <el-form-item label="类型">
  667. <el-radio-group v-model="cronValue.hour.type">
  668. <el-radio-button label="0">任意值</el-radio-button>
  669. <el-radio-button label="1">范围</el-radio-button>
  670. <el-radio-button label="2">间隔</el-radio-button>
  671. <el-radio-button label="3">指定</el-radio-button>
  672. </el-radio-group>
  673. </el-form-item>
  674. <el-form-item label="范围" v-if="cronValue.hour.type == '1'">
  675. <el-input-number
  676. v-model="cronValue.hour.range.start"
  677. :min="0"
  678. :max="23"
  679. controls-position="right"
  680. />
  681. <span style="padding: 0 15px">-</span>
  682. <el-input-number
  683. v-model="cronValue.hour.range.end"
  684. :min="0"
  685. :max="23"
  686. controls-position="right"
  687. />
  688. </el-form-item>
  689. <el-form-item label="间隔" v-if="cronValue.hour.type == '2'">
  690. <el-input-number
  691. v-model="cronValue.hour.loop.start"
  692. :min="0"
  693. :max="23"
  694. controls-position="right"
  695. />
  696. 小时开始,每
  697. <el-input-number
  698. v-model="cronValue.hour.loop.end"
  699. :min="0"
  700. :max="23"
  701. controls-position="right"
  702. />
  703. 小时执行一次
  704. </el-form-item>
  705. <el-form-item label="指定" v-if="cronValue.hour.type == '3'">
  706. <el-select v-model="cronValue.hour.appoint" multiple style="width: 100%">
  707. <el-option
  708. v-for="(item, index) in data.hour"
  709. :key="index"
  710. :label="item"
  711. :value="item"
  712. />
  713. </el-select>
  714. </el-form-item>
  715. </el-form>
  716. </el-tab-pane>
  717. <el-tab-pane>
  718. <template #label>
  719. <div class="sc-cron-num">
  720. <h2>日</h2>
  721. <h4>{{ value_day }}</h4>
  722. </div>
  723. </template>
  724. <el-form>
  725. <el-form-item label="类型">
  726. <el-radio-group v-model="cronValue.day.type">
  727. <el-radio-button label="0">任意值</el-radio-button>
  728. <el-radio-button label="1">范围</el-radio-button>
  729. <el-radio-button label="2">间隔</el-radio-button>
  730. <el-radio-button label="3">指定</el-radio-button>
  731. <el-radio-button label="4">本月最后一天</el-radio-button>
  732. <el-radio-button label="5">不指定</el-radio-button>
  733. </el-radio-group>
  734. </el-form-item>
  735. <el-form-item label="范围" v-if="cronValue.day.type == '1'">
  736. <el-input-number
  737. v-model="cronValue.day.range.start"
  738. :min="1"
  739. :max="31"
  740. controls-position="right"
  741. />
  742. <span style="padding: 0 15px">-</span>
  743. <el-input-number
  744. v-model="cronValue.day.range.end"
  745. :min="1"
  746. :max="31"
  747. controls-position="right"
  748. />
  749. </el-form-item>
  750. <el-form-item label="间隔" v-if="cronValue.day.type == '2'">
  751. <el-input-number
  752. v-model="cronValue.day.loop.start"
  753. :min="1"
  754. :max="31"
  755. controls-position="right"
  756. />
  757. 号开始,每
  758. <el-input-number
  759. v-model="cronValue.day.loop.end"
  760. :min="1"
  761. :max="31"
  762. controls-position="right"
  763. />
  764. 天执行一次
  765. </el-form-item>
  766. <el-form-item label="指定" v-if="cronValue.day.type == '3'">
  767. <el-select v-model="cronValue.day.appoint" multiple style="width: 100%">
  768. <el-option
  769. v-for="(item, index) in data.day"
  770. :key="index"
  771. :label="item"
  772. :value="item"
  773. />
  774. </el-select>
  775. </el-form-item>
  776. </el-form>
  777. </el-tab-pane>
  778. <el-tab-pane>
  779. <template #label>
  780. <div class="sc-cron-num">
  781. <h2>月</h2>
  782. <h4>{{ value_month }}</h4>
  783. </div>
  784. </template>
  785. <el-form>
  786. <el-form-item label="类型">
  787. <el-radio-group v-model="cronValue.month.type">
  788. <el-radio-button label="0">任意值</el-radio-button>
  789. <el-radio-button label="1">范围</el-radio-button>
  790. <el-radio-button label="2">间隔</el-radio-button>
  791. <el-radio-button label="3">指定</el-radio-button>
  792. </el-radio-group>
  793. </el-form-item>
  794. <el-form-item label="范围" v-if="cronValue.month.type == '1'">
  795. <el-input-number
  796. v-model="cronValue.month.range.start"
  797. :min="1"
  798. :max="12"
  799. controls-position="right"
  800. />
  801. <span style="padding: 0 15px">-</span>
  802. <el-input-number
  803. v-model="cronValue.month.range.end"
  804. :min="1"
  805. :max="12"
  806. controls-position="right"
  807. />
  808. </el-form-item>
  809. <el-form-item label="间隔" v-if="cronValue.month.type == '2'">
  810. <el-input-number
  811. v-model="cronValue.month.loop.start"
  812. :min="1"
  813. :max="12"
  814. controls-position="right"
  815. />
  816. 月开始,每
  817. <el-input-number
  818. v-model="cronValue.month.loop.end"
  819. :min="1"
  820. :max="12"
  821. controls-position="right"
  822. />
  823. 月执行一次
  824. </el-form-item>
  825. <el-form-item label="指定" v-if="cronValue.month.type == '3'">
  826. <el-select v-model="cronValue.month.appoint" multiple style="width: 100%">
  827. <el-option
  828. v-for="(item, index) in data.month"
  829. :key="index"
  830. :label="item"
  831. :value="item"
  832. />
  833. </el-select>
  834. </el-form-item>
  835. </el-form>
  836. </el-tab-pane>
  837. <el-tab-pane>
  838. <template #label>
  839. <div class="sc-cron-num">
  840. <h2>周</h2>
  841. <h4>{{ value_week }}</h4>
  842. </div>
  843. </template>
  844. <el-form>
  845. <el-form>
  846. <el-form-item label="类型">
  847. <el-radio-group v-model="cronValue.week.type">
  848. <el-radio-button label="0">任意值</el-radio-button>
  849. <el-radio-button label="1">范围</el-radio-button>
  850. <el-radio-button label="2">间隔</el-radio-button>
  851. <el-radio-button label="3">指定</el-radio-button>
  852. <el-radio-button label="4">本月最后一周</el-radio-button>
  853. <el-radio-button label="5">不指定</el-radio-button>
  854. </el-radio-group>
  855. </el-form-item>
  856. <el-form-item label="范围" v-if="cronValue.week.type == '1'">
  857. <el-select v-model="cronValue.week.range.start">
  858. <el-option
  859. v-for="(item, index) in data.week"
  860. :key="index"
  861. :label="item.label"
  862. :value="item.value"
  863. />
  864. </el-select>
  865. <span style="padding: 0 15px">-</span>
  866. <el-select v-model="cronValue.week.range.end">
  867. <el-option
  868. v-for="(item, index) in data.week"
  869. :key="index"
  870. :label="item.label"
  871. :value="item.value"
  872. />
  873. </el-select>
  874. </el-form-item>
  875. <el-form-item label="间隔" v-if="cronValue.week.type == '2'">
  876. <el-input-number
  877. v-model="cronValue.week.loop.start"
  878. :min="1"
  879. :max="4"
  880. controls-position="right"
  881. />
  882. 周的星期
  883. <el-select v-model="cronValue.week.loop.end">
  884. <el-option
  885. v-for="(item, index) in data.week"
  886. :key="index"
  887. :label="item.label"
  888. :value="item.value"
  889. />
  890. </el-select>
  891. 执行一次
  892. </el-form-item>
  893. <el-form-item label="指定" v-if="cronValue.week.type == '3'">
  894. <el-select v-model="cronValue.week.appoint" multiple style="width: 100%">
  895. <el-option
  896. v-for="(item, index) in data.week"
  897. :key="index"
  898. :label="item.label"
  899. :value="item.value"
  900. />
  901. </el-select>
  902. </el-form-item>
  903. <el-form-item label="最后一周" v-if="cronValue.week.type == '4'">
  904. <el-select v-model="cronValue.week.last">
  905. <el-option
  906. v-for="(item, index) in data.week"
  907. :key="index"
  908. :label="item.label"
  909. :value="item.value"
  910. />
  911. </el-select>
  912. </el-form-item>
  913. </el-form>
  914. </el-form>
  915. </el-tab-pane>
  916. <el-tab-pane>
  917. <template #label>
  918. <div class="sc-cron-num">
  919. <h2>年</h2>
  920. <h4>{{ value_year }}</h4>
  921. </div>
  922. </template>
  923. <el-form>
  924. <el-form-item label="类型">
  925. <el-radio-group v-model="cronValue.year.type">
  926. <el-radio-button label="-1">忽略</el-radio-button>
  927. <el-radio-button label="0">任意值</el-radio-button>
  928. <el-radio-button label="1">范围</el-radio-button>
  929. <el-radio-button label="2">间隔</el-radio-button>
  930. <el-radio-button label="3">指定</el-radio-button>
  931. </el-radio-group>
  932. </el-form-item>
  933. <el-form-item label="范围" v-if="cronValue.year.type == '1'">
  934. <el-input-number v-model="cronValue.year.range.start" controls-position="right" />
  935. <span style="padding: 0 15px">-</span>
  936. <el-input-number v-model="cronValue.year.range.end" controls-position="right" />
  937. </el-form-item>
  938. <el-form-item label="间隔" v-if="cronValue.year.type == '2'">
  939. <el-input-number v-model="cronValue.year.loop.start" controls-position="right" />
  940. 年开始,每
  941. <el-input-number
  942. v-model="cronValue.year.loop.end"
  943. :min="1"
  944. controls-position="right"
  945. />
  946. 年执行一次
  947. </el-form-item>
  948. <el-form-item label="指定" v-if="cronValue.year.type == '3'">
  949. <el-select v-model="cronValue.year.appoint" multiple style="width: 100%">
  950. <el-option
  951. v-for="(item, index) in data.year"
  952. :key="index"
  953. :label="item"
  954. :value="item"
  955. />
  956. </el-select>
  957. </el-form-item>
  958. </el-form>
  959. </el-tab-pane>
  960. </el-tabs>
  961. </div>
  962. <template #footer>
  963. <el-button @click="dialogVisible = false">取 消</el-button>
  964. <el-button type="primary" @click="submit()">确 认</el-button>
  965. </template>
  966. </el-dialog>
  967. </template>
  968. <style scoped>
  969. .sc-cron:deep(.el-tabs__item) {
  970. height: auto;
  971. line-height: 1;
  972. padding: 0 7px;
  973. vertical-align: bottom;
  974. }
  975. .sc-cron-num {
  976. text-align: center;
  977. margin-bottom: 15px;
  978. width: 100%;
  979. }
  980. .sc-cron-num h2 {
  981. font-size: 12px;
  982. margin-bottom: 15px;
  983. font-weight: normal;
  984. }
  985. .sc-cron-num h4 {
  986. display: block;
  987. height: 32px;
  988. line-height: 30px;
  989. width: 100%;
  990. font-size: 12px;
  991. padding: 0 15px;
  992. background: var(--el-color-primary-light-9);
  993. border-radius: 4px;
  994. }
  995. .sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 {
  996. background: var(--el-color-primary);
  997. color: #fff;
  998. }
  999. [data-theme='dark'] .sc-cron-num h4 {
  1000. background: var(--el-color-white);
  1001. }
  1002. </style>