Crontab.vue 29 KB

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