addTimes.vue 5.0 KB

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