addTimes.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <template>
  2. <a-modal
  3. v-model:visible="visible"
  4. title-align="start"
  5. title="添加时间"
  6. :width="800"
  7. top="10vh"
  8. :align-center="false"
  9. @before-open="modalBeforeOpen"
  10. >
  11. <a-form ref="formRef" :model="formData" auto-label-width>
  12. <a-form-item label="添加方式" required>
  13. <a-radio-group v-model="formData.type" @change="typeChange">
  14. <a-radio value="simple">简单创建</a-radio>
  15. <a-radio value="loop">循环创建</a-radio>
  16. </a-radio-group>
  17. </a-form-item>
  18. <a-form-item
  19. v-if="IS_LOOP"
  20. label="日期范围"
  21. field="date.startTime"
  22. :rules="[
  23. {
  24. required: true,
  25. message: '请选择时间',
  26. },
  27. ]"
  28. >
  29. <select-range-datetime
  30. v-model="formData.date"
  31. :show-time="false"
  32. format="YYYY-MM-DD"
  33. >
  34. </select-range-datetime>
  35. </a-form-item>
  36. <a-form-item
  37. v-for="(time, index) in formData.times"
  38. :key="index"
  39. :field="`times[${index}].startTime`"
  40. :rules="[
  41. {
  42. required: true,
  43. message: '请选择时间',
  44. },
  45. ]"
  46. :label="index + 1 + ''"
  47. >
  48. <select-range-time
  49. v-if="IS_LOOP"
  50. v-model="formData.times[index]"
  51. disable-confirm
  52. :style="{ width: '256px' }"
  53. >
  54. </select-range-time>
  55. <select-range-datetime v-else v-model="formData.times[index]">
  56. </select-range-datetime>
  57. <a-button class="ml-10" @click="toAdd(index)">
  58. <template #icon>
  59. <icon-plus />
  60. </template>
  61. </a-button>
  62. <a-button
  63. status="danger"
  64. :disabled="formData.times.length === 1"
  65. @click="toDelete(index)"
  66. >
  67. <template #icon>
  68. <svg-icon name="icon-delete"></svg-icon>
  69. </template>
  70. </a-button>
  71. </a-form-item>
  72. </a-form>
  73. <template #footer>
  74. <a-button @click="close">取消</a-button>
  75. <a-button type="primary" @click="confirm">确认</a-button>
  76. </template>
  77. </a-modal>
  78. </template>
  79. <script setup lang="ts">
  80. import { computed, nextTick, reactive, ref } from 'vue';
  81. import type { FormInstance } from '@arco-design/web-vue/es/form';
  82. import useModal from '@/hooks/modal';
  83. import { formatDate, objModifyAssign } from '@/utils/utils';
  84. import { Message } from '@arco-design/web-vue';
  85. defineOptions({
  86. name: 'AddTimes',
  87. });
  88. /* modal */
  89. const { visible, open, close } = useModal();
  90. defineExpose({ open, close });
  91. const emit = defineEmits(['confirm']);
  92. function getItemItem() {
  93. return {
  94. id: null,
  95. startTime: null,
  96. endTime: null,
  97. };
  98. }
  99. function getDefaultFormData() {
  100. return {
  101. type: 'simple',
  102. date: {
  103. startTime: null,
  104. endTime: null,
  105. },
  106. times: [getItemItem()],
  107. };
  108. }
  109. const formRef = ref<FormInstance>();
  110. const formData = reactive(getDefaultFormData());
  111. const IS_LOOP = computed(() => {
  112. return formData.type === 'loop';
  113. });
  114. function typeChange() {
  115. formData.times = [getItemItem()];
  116. }
  117. function toAdd(index: number) {
  118. formData.times.splice(index + 1, 0, getItemItem());
  119. }
  120. function toDelete(index: number) {
  121. if (formData.times.length <= 1) {
  122. Message.error('不可再删除!');
  123. return;
  124. }
  125. formData.times.splice(index, 1);
  126. }
  127. /* confirm */
  128. async function confirm() {
  129. const err = await formRef.value?.validate();
  130. if (err) return;
  131. if (!IS_LOOP.value) {
  132. emit('confirm', formData.times);
  133. close();
  134. return;
  135. }
  136. const times = [];
  137. const oneDay = 24 * 60 * 60 * 1000;
  138. for (
  139. let i = formData.date.startTime;
  140. i <= formData.date.endTime;
  141. i += oneDay
  142. ) {
  143. const curDate = formatDate('YYYY/MM/DD', new Date(i));
  144. formData.times.forEach((item) => {
  145. times.push({
  146. id: null,
  147. startTime: new Date(`${curDate} ${item.startTime}`).getTime(),
  148. endTime: new Date(`${curDate} ${item.endTime}`).getTime(),
  149. });
  150. });
  151. }
  152. emit('confirm', times);
  153. close();
  154. }
  155. /* init modal */
  156. function modalBeforeOpen() {
  157. objModifyAssign(formData, getDefaultFormData());
  158. nextTick(() => {
  159. formRef.value?.clearValidate();
  160. });
  161. }
  162. </script>