AlarmSchedule.vue 6.17 KB
<template>
  <BasicModal v-bind="$attrs" :width="600" title="编辑报警日程" centered @register="registerModal" @ok="handleOk"
    @cancel="handleCancel">
    <BasicForm @register="registerForm" ref="basicFormRef">
      <template #customEnable>
        <template v-for="(item, optionIndex) in options" :key="item.flag">
          <div :class="optionIndex >= 1 ? 'mt-4' : ''" class="flex">
            <div class="ml-4 mr-4 flex items-center">
              <Checkbox v-model:checked="item.enabled">星期{{ item.flag }}</Checkbox>
            </div>
            <TimePicker placeholder="开始时间" v-model:value="item.startsOn" value-format="x" format="HH:mm"
              :disabled="!item.enabled" />
            <span class="ml-4 mr-4 flex items-center">~</span>
            <TimePicker @change="handleBlur(item.startsOn,item.endsOn)" placeholder="结束时间" v-model:value="item.endsOn"
              value-format="x" format="HH:mm" :disabled="!item.enabled" />
          </div>
        </template>
      </template>
      <template #timing>
        <TimePicker placeholder="开始时间" v-model:value="timeState.startsOn" value-format="x" format="HH:mm" />
        <span class="ml-4 mr-4">~</span>
        <TimePicker @change="handleTimeBlur(timeState.startsOn,timeState.endsOn)" placeholder="结束时间"
          v-model:value="timeState.endsOn" value-format="x" format="HH:mm" />
      </template>
    </BasicForm>
  </BasicModal>
</template>

<script lang="ts" setup>
import { reactive, ref, watch, nextTick } from 'vue';
import { useModalInner, BasicModal } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form';
import { alarmScheduleSchemas } from '../config/config.data.ts';
import { Checkbox, TimePicker } from 'ant-design-vue';
import { useMessage } from '/@/hooks/web/useMessage';

const emit = defineEmits(['register', 'cancel']);
const { createMessage } = useMessage();
const [registerForm, { setFieldsValue, getFieldsValue }] = useForm({
  showActionButtonGroup: false,
  schemas: alarmScheduleSchemas,
});
const timeState = reactive({
  startsOn: null,
  endsOn: null,
});

const options = ref([
  {
    enabled: false,
    dayOfWeek: 1,
    flag: '一',
    endsOn: null,
    startsOn: null,
  },
  {
    enabled: false,
    dayOfWeek: 2,
    flag: '二',
    endsOn: null,
    startsOn: null,
  },
  {
    enabled: false,
    dayOfWeek: 3,
    flag: '三',
    endsOn: null,
    startsOn: null,
  },
  {
    enabled: false,
    dayOfWeek: 4,
    flag: '四',
    endsOn: null,
    startsOn: null,
  },
  {
    enabled: false,
    dayOfWeek: 5,
    flag: '五',
    endsOn: null,
    startsOn: null,
  },
  {
    enabled: false,
    dayOfWeek: 6,
    flag: '六',
    endsOn: null,
    startsOn: null,
  },
  {
    enabled: false,
    dayOfWeek: 7,
    flag: '日',
    endsOn: null,
    startsOn: null,
  },
]);
const basicFormRef = ref<InstanceType<typeof BasicForm>>();
let index = ref(null);
watch(
  options,
  (newValue) => {
    const arr = [];
    for (let item of newValue) {
      if (item.enabled && item.startsOn && item.endsOn) {
        arr.push(true);
      } else if ((!item.enabled && item.startsOn && item.endsOn) || item.enabled) {
        arr.push(false);
      }
    }
    const flag = arr.length ? !arr.every((item) => item) : true;
    nextTick(() => {
      setModalProps({
        okButtonProps: {
          disabled: flag,
        },
      });
    });
  },
  {
    deep: true,
  }
);

const [registerModal, { closeModal, setModalProps }] = useModalInner((data) => {
  watch([timeState, basicFormRef.value.formModel], ([timeState, formModel]) => {
    setModalProps({
      okButtonProps: {
        disabled:
          timeState.startsOn === null ||
          timeState.endsOn === null ||
          !formModel.daysOfWeek?.length,
      },
    });
    watch(
      () => formModel.schedule,
      () => {
        timeState.startsOn = null;
        timeState.endsOn = null;
      }
    );
  });
  const { value, currentIndex, isUpdate, scheduleData } = data;
  index.value = currentIndex;
  const dayZenoTime = Math.round(new Date(new Date().toLocaleDateString()).getTime());
  // 编辑
  setFieldsValue({
    schedule: value,
  });
  if (isUpdate) {
    nextTick(() => {
      // 回显定时启用
      if (scheduleData.type === 'SPECIFIC_TIME') {
        setFieldsValue({
          daysOfWeek: scheduleData.daysOfWeek,
        });
        timeState.startsOn = scheduleData.startsOn + dayZenoTime + '';
        timeState.endsOn = scheduleData.endsOn + dayZenoTime + '';
      }
      // 回显自定义启用
      if (scheduleData.type === 'CUSTOM') {
        for (let [index, item] of scheduleData?.items.entries()) {
          if (item.enabled) {
            options.value[index].enabled = item.enabled;
            options.value[index].startsOn = item.startsOn + dayZenoTime + '';
            options.value[index].endsOn = item.endsOn + dayZenoTime + '';
          }
        }
      }
    });
  }
});
const scheduleData = ref({
  type: 'ANY_TIME',
});
const handleBlur = (eS, eE) => {
  if (eS > eE) {
    return createMessage.warn('开始时间不能大于结束时间')
  }
}
const handleTimeBlur = (eS, eE) => {
  if (eS > eE) {
    return createMessage.warn('开始时间不能大于结束时间')
  }
}
const handleOk = () => {
  const { schedule: type, timezone, daysOfWeek } = getFieldsValue();
  // 获取当天0时时间戳
  const dayZenoTime = Math.round(new Date(new Date().toLocaleDateString()).getTime());
  if (type === 'CUSTOM') {
    const items = options.value.map((item) => {
      return {
        startsOn: item.startsOn ? item.startsOn - dayZenoTime : 0,
        endsOn: item.endsOn ? item.endsOn - dayZenoTime : 0,
        dayOfWeek: item.dayOfWeek,
        enabled: item.enabled,
      };
    });
    scheduleData.value = {
      type,
      timezone,
      items,
    };
  } else if (type === 'SPECIFIC_TIME') {
    scheduleData.value = {
      type,
      timezone,
      daysOfWeek,
      startsOn: timeState.startsOn - dayZenoTime,
      endsOn: timeState.endsOn - dayZenoTime,
    };
  }
  closeModal();
};
const handleCancel = () => {
  emit('cancel', index.value);
};

defineExpose({
  scheduleData,
});
</script>

<style lang="less" scoped>
:deep(.ant-time-picker) {
  width: 12rem;
}
</style>