Crontab.vue 29 KB

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