CustomDate.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <a-popconfirm placement="bottom" overlayClassName="custom-date-time" @confirm="submit" @cancel="cancel" v-model="visible">
  3. <template v-slot:icon><i /></template>
  4. <template v-slot:title>
  5. <a-alert v-if="diffHours < 1" class="mb-2" :message="$t('common_587')" type="error" show-icon />
  6. <a-form-model hideRequiredMark ref="ruleForm" :model="formData" :rules="rules" v-bind="layout">
  7. <a-form-model-item :label="$t('common.text00119')" prop="startValue">
  8. <a-date-picker
  9. v-model="formData.startValue"
  10. :disabled-date="disabledStartDate"
  11. :disabled-time="disabledDateTime"
  12. :show-time="{ defaultValue: $moment('00:00:00', 'HH:mm:ss') }"
  13. format="YYYY-MM-DD HH:mm"
  14. :open="startOpen"
  15. :placeholder="$t('common.text00119')"
  16. @openChange="handleStartOpenChange" />
  17. </a-form-model-item>
  18. <a-form-model-item :label="$t('common.text00120')" prop="endValue">
  19. <a-date-picker
  20. v-model="formData.endValue"
  21. :disabled-date="disabledEndDate"
  22. :disabled-time="disabledDateTime"
  23. :show-time="{ defaultValue: $moment('00:00:00', 'HH:mm:ss') }"
  24. format="YYYY-MM-DD HH:mm"
  25. :placeholder="$t('common.text00120')"
  26. :open="endOpen"
  27. @openChange="handleEndOpenChange" />
  28. </a-form-model-item>
  29. </a-form-model>
  30. </template>
  31. <a-radio-button value="custom">{{ $t('common.text00121') }}</a-radio-button>
  32. </a-popconfirm>
  33. </template>
  34. <script>
  35. import * as R from 'ramda'
  36. import moment from 'moment'
  37. export default {
  38. name: 'CustomDate',
  39. props: {
  40. endTime: {
  41. type: Object,
  42. default: () => moment(),
  43. },
  44. customTime: {
  45. type: Object,
  46. validator: val => val.from,
  47. },
  48. },
  49. data () {
  50. return {
  51. formData: {
  52. startValue: null,
  53. endValue: this.endTime,
  54. },
  55. visible: false,
  56. startOpen: false,
  57. endOpen: false,
  58. layout: {
  59. labelCol: { span: 6 },
  60. wrapperCol: { span: 18 },
  61. },
  62. rules: {
  63. startValue: [
  64. { required: true, message: this.$t('common.select') },
  65. ],
  66. endValue: [
  67. { required: true, message: this.$t('common.select') },
  68. ],
  69. },
  70. diffHours: 1,
  71. }
  72. },
  73. watch: {
  74. customTime (val) {
  75. if (val && val.from) {
  76. const hours = +val.from.replace(/^now-(\w+)h$/, '$1')
  77. if (R.is(Number, hours) && !Number.isNaN(hours)) this.formData.startValue = this.$moment().subtract(hours, 'hours')
  78. }
  79. if (val && val.to) {
  80. const hours = +val.to.replace(/^now-(\w+)h$/, '$1')
  81. if (R.is(Number, hours) && !Number.isNaN(hours)) this.formData.endValue = this.$moment().subtract(hours, 'hours')
  82. }
  83. },
  84. },
  85. methods: {
  86. cancel () {
  87. this.visible = false
  88. },
  89. getCustomTime () {
  90. const from = this.formData.startValue.diff(this.$moment(), 'hours')
  91. const to = this.formData.endValue.diff(this.$moment(), 'hours')
  92. return {
  93. from: from === 0 ? 'now' : `now${from}h`, // from 是负数
  94. to: to === 0 ? 'now' : `now${to}h`, // to 是负数
  95. }
  96. },
  97. async submit () {
  98. try {
  99. const valid = await this.$refs.ruleForm.validate()
  100. this.diffHours = this.formData.endValue.diff(this.formData.startValue, 'hours')
  101. if (this.diffHours < 1) {
  102. this.visible = true
  103. return false
  104. }
  105. if (valid) {
  106. this.$emit('update:time', 'custom')
  107. this.$emit('update:customTime', this.getCustomTime())
  108. this.visible = false
  109. } else {
  110. this.visible = true
  111. }
  112. } catch (error) {
  113. this.visible = true
  114. throw error
  115. }
  116. },
  117. disabledStartDate (startValue) {
  118. const endValue = this.formData.endValue
  119. if (!startValue || !endValue) {
  120. return startValue && (startValue > this.$moment().endOf('day'))
  121. }
  122. return (startValue && (startValue > this.$moment().endOf('day'))) || (startValue.valueOf() > endValue.valueOf())
  123. },
  124. disabledEndDate (endValue) {
  125. const startValue = this.formData.startValue
  126. if (!endValue || !startValue) {
  127. return endValue && (endValue > this.$moment().endOf('day'))
  128. }
  129. return (endValue && (endValue > this.$moment().endOf('day'))) || (startValue.valueOf() >= endValue.valueOf())
  130. },
  131. handleStartOpenChange (open) {
  132. this.startOpen = open
  133. },
  134. handleEndOpenChange (open) {
  135. this.endOpen = open
  136. },
  137. _range (start, end) {
  138. const result = []
  139. for (let i = start; i < end; i++) {
  140. result.push(i)
  141. }
  142. return result
  143. },
  144. disabledDateTime () {
  145. const currentHour = this.$moment().hour()
  146. return {
  147. disabledHours: () => this._range(currentHour + 1, 24),
  148. }
  149. },
  150. },
  151. }
  152. </script>