05bf65c6708478c544595c996048d04d5adad5fb.svn-base 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <div class="j-easy-cron">
  3. <div class="content">
  4. <div>
  5. <a-tabs size="small" v-model="curtab">
  6. <a-tab-pane tab="秒" key="second" v-if="!hideSecond">
  7. <second-ui v-model="second" :disabled="disabled"></second-ui>
  8. </a-tab-pane>
  9. <a-tab-pane tab="分" key="minute">
  10. <minute-ui v-model="minute" :disabled="disabled"></minute-ui>
  11. </a-tab-pane>
  12. <a-tab-pane tab="时" key="hour">
  13. <hour-ui v-model="hour" :disabled="disabled"></hour-ui>
  14. </a-tab-pane>
  15. <a-tab-pane tab="日" key="day">
  16. <day-ui v-model="day" :week="week" :disabled="disabled"></day-ui>
  17. </a-tab-pane>
  18. <a-tab-pane tab="月" key="month">
  19. <month-ui v-model="month" :disabled="disabled"></month-ui>
  20. </a-tab-pane>
  21. <a-tab-pane tab="周" key="week">
  22. <week-ui v-model="week" :day="day" :disabled="disabled"></week-ui>
  23. </a-tab-pane>
  24. <a-tab-pane tab="年" key="year" v-if="!hideYear && !hideSecond">
  25. <year-ui v-model="year" :disabled="disabled"></year-ui>
  26. </a-tab-pane>
  27. </a-tabs>
  28. </div>
  29. <a-divider/>
  30. <!-- 执行时间预览 -->
  31. <a-row :gutter="8">
  32. <a-col :span="18" style="margin-top: 22px;">
  33. <a-row :gutter="8">
  34. <a-col :span="8" style="margin-bottom: 8px;">
  35. <a-input addon-before="秒" v-model="inputValues.second" @blur="onInputBlur"/>
  36. </a-col>
  37. <a-col :span="8" style="margin-bottom: 8px;">
  38. <a-input addon-before="分" v-model="inputValues.minute" @blur="onInputBlur"/>
  39. </a-col>
  40. <a-col :span="8" style="margin-bottom: 8px;">
  41. <a-input addon-before="时" v-model="inputValues.hour" @blur="onInputBlur"/>
  42. </a-col>
  43. <a-col :span="8" style="margin-bottom: 8px;">
  44. <a-input addon-before="日" v-model="inputValues.day" @blur="onInputBlur"/>
  45. </a-col>
  46. <a-col :span="8" style="margin-bottom: 8px;">
  47. <a-input addon-before="月" v-model="inputValues.month" @blur="onInputBlur"/>
  48. </a-col>
  49. <a-col :span="8" style="margin-bottom: 8px;">
  50. <a-input addon-before="周" v-model="inputValues.week" @blur="onInputBlur"/>
  51. </a-col>
  52. <a-col :span="8" style="margin-bottom: 8px;">
  53. <a-input addon-before="年" v-model="inputValues.year" @blur="onInputBlur"/>
  54. </a-col>
  55. <a-col :span="16" style="margin-bottom: 8px;">
  56. <a-input addon-before="Cron" v-model="inputValues.cron" @blur="onInputCronBlur"/>
  57. </a-col>
  58. </a-row>
  59. </a-col>
  60. <a-col :span="6">
  61. <div>近十次执行时间(不含年)</div>
  62. <a-textarea type="textarea" :value="preTimeList" :rows="5"/>
  63. </a-col>
  64. </a-row>
  65. </div>
  66. </div>
  67. </template>
  68. <script>
  69. import SecondUi from './tabs/second'
  70. import MinuteUi from './tabs/minute'
  71. import HourUi from './tabs/hour'
  72. import DayUi from './tabs/day'
  73. import WeekUi from './tabs/week'
  74. import MonthUi from './tabs/month'
  75. import YearUi from './tabs/year'
  76. import CronParser from 'cron-parser'
  77. import dateFormat from './format-date'
  78. import { simpleDebounce } from '@/utils/util'
  79. import ACol from 'ant-design-vue/es/grid/Col'
  80. export default {
  81. name: 'easy-cron',
  82. components: {
  83. ACol,
  84. SecondUi,
  85. MinuteUi,
  86. HourUi,
  87. DayUi,
  88. WeekUi,
  89. MonthUi,
  90. YearUi
  91. },
  92. props: {
  93. cronValue: {
  94. type: String,
  95. default: ''
  96. },
  97. disabled: {
  98. type: Boolean,
  99. default: false
  100. },
  101. hideSecond: {
  102. type: Boolean,
  103. default: false
  104. },
  105. hideYear: {
  106. type: Boolean,
  107. default: false
  108. },
  109. remote: {
  110. type: Function,
  111. default: null
  112. }
  113. },
  114. data() {
  115. return {
  116. curtab: this.hideSecond ? 'minute' : 'second',
  117. second: '*',
  118. minute: '*',
  119. hour: '*',
  120. day: '*',
  121. month: '*',
  122. week: '?',
  123. year: '*',
  124. inputValues: {second: '', minute: '', hour: '', day: '', month: '', week: '', year: '', cron: ''},
  125. preTimeList: '执行预览,会忽略年份参数',
  126. }
  127. },
  128. computed: {
  129. cronValue_c() {
  130. let result = []
  131. if (!this.hideSecond) result.push(this.second ? this.second : '*')
  132. result.push(this.minute ? this.minute : '*')
  133. result.push(this.hour ? this.hour : '*')
  134. result.push(this.day ? this.day : '*')
  135. result.push(this.month ? this.month : '*')
  136. result.push(this.week ? this.week : '?')
  137. if (!this.hideYear && !this.hideSecond) result.push(this.year ? this.year : '*')
  138. return result.join(' ')
  139. },
  140. cronValue_c2() {
  141. const v = this.cronValue_c
  142. if (this.hideYear || this.hideSecond) return v
  143. const vs = v.split(' ')
  144. return vs.slice(0, vs.length - 1).join(' ')
  145. }
  146. },
  147. watch: {
  148. cronValue(newVal, oldVal) {
  149. if (newVal === this.cronValue_c) {
  150. // console.info('same cron value: ' + newVal)
  151. return
  152. }
  153. this.formatValue()
  154. },
  155. cronValue_c(newVal, oldVal) {
  156. this.calTriggerList()
  157. this.$emit('change', newVal)
  158. this.assignInput()
  159. },
  160. minute() {
  161. if (this.second === '*') {
  162. this.second = '0'
  163. }
  164. },
  165. hour() {
  166. if (this.minute === '*') {
  167. this.minute = '0'
  168. }
  169. },
  170. day(day) {
  171. if (day !== '?' && this.hour === '*') {
  172. this.hour = '0'
  173. }
  174. },
  175. week(week) {
  176. if (week !== '?' && this.hour === '*') {
  177. this.hour = '0'
  178. }
  179. },
  180. month() {
  181. if (this.day === '?' && this.week === '*') {
  182. this.week = '1'
  183. } else if (this.week === '?' && this.day === '*') {
  184. this.day = '1'
  185. }
  186. },
  187. year() {
  188. if (this.month === '*') {
  189. this.month = '1'
  190. }
  191. },
  192. },
  193. created() {
  194. this.formatValue()
  195. this.$nextTick(() => {
  196. this.calTriggerListInner()
  197. })
  198. },
  199. methods: {
  200. assignInput() {
  201. Object.assign(this.inputValues, {
  202. second: this.second,
  203. minute: this.minute,
  204. hour: this.hour,
  205. day: this.day,
  206. month: this.month,
  207. week: this.week,
  208. year: this.year,
  209. cron: this.cronValue_c,
  210. })
  211. },
  212. formatValue() {
  213. if (!this.cronValue) return
  214. const values = this.cronValue.split(' ').filter(item => !!item)
  215. if (!values || values.length <= 0) return
  216. let i = 0
  217. if (!this.hideSecond) this.second = values[i++]
  218. if (values.length > i) this.minute = values[i++]
  219. if (values.length > i) this.hour = values[i++]
  220. if (values.length > i) this.day = values[i++]
  221. if (values.length > i) this.month = values[i++]
  222. if (values.length > i) this.week = values[i++]
  223. if (values.length > i) this.year = values[i]
  224. this.assignInput()
  225. },
  226. calTriggerList: simpleDebounce(function () {
  227. this.calTriggerListInner()
  228. }, 500),
  229. calTriggerListInner() {
  230. // 设置了回调函数
  231. if (this.remote) {
  232. this.remote(this.cronValue_c, +new Date(), v => {
  233. this.preTimeList = v
  234. })
  235. return
  236. }
  237. const format = 'yyyy-MM-dd hh:mm:ss'
  238. const options = {
  239. currentDate: dateFormat(new Date(), format)
  240. }
  241. const iter = CronParser.parseExpression(this.cronValue_c2, options)
  242. const result = []
  243. for (let i = 1; i <= 10; i++) {
  244. result.push(dateFormat(new Date(iter.next()), format))
  245. }
  246. this.preTimeList = result.length > 0 ? result.join('\n') : '无执行时间'
  247. },
  248. onInputBlur(){
  249. this.second = this.inputValues.second
  250. this.minute = this.inputValues.minute
  251. this.hour = this.inputValues.hour
  252. this.day = this.inputValues.day
  253. this.month = this.inputValues.month
  254. this.week = this.inputValues.week
  255. this.year = this.inputValues.year
  256. },
  257. onInputCronBlur(event){
  258. this.$emit('change', event.target.value)
  259. },
  260. },
  261. model: {
  262. prop: 'cronValue',
  263. event: 'change'
  264. },
  265. }
  266. </script>
  267. <style scoped lang="less">
  268. .j-easy-cron {
  269. /deep/ .content {
  270. .ant-checkbox-wrapper + .ant-checkbox-wrapper {
  271. margin-left: 0;
  272. }
  273. }
  274. }
  275. </style>