calendarSelect.vue 6.93 KB
<!--
 * @Date: 2023-12-14 10:04:23
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2023-12-21 13:59:23
 * @FilePath: /meihuaApp/src/components/calendarSelect.vue
 * @Description: 文件描述
-->
<template>
  <view class="calendar-select-page" @tap="openCalendar">
    <nut-row gutter="10">
      <nut-col span="9">
        <view style="color: #7D7C7C; font-size: 0.8rem;">入住日期</view>
        <view style="color: #6A4925; font-size: 0.85rem; font-weight: bold; margin-top: 0.1rem;">{{ state.checkinDate}} {{ getDayOfWeek(state.checkinDate) }}</view>
      </nut-col>
      <nut-col span="5">
        <view style="color: #6A4925; margin-top: 15%; font-size: 0.8rem; text-align: center; background-color: #fff; padding: 0.25rem 0; border-radius: 0.5rem;">
          共{{ state.betweenDate }}晚
        </view>
      </nut-col>
      <nut-col span="9">
        <view style="color: #7D7C7C; font-size: 0.8rem;">退房日期</view>
        <view style="color: #6A4925; font-size: 0.85rem; font-weight: bold; margin-top: 0.1rem;">{{ state.checkoutDate }} {{ getDayOfWeek(state.checkoutDate) }}</view>
      </nut-col>
    </nut-row>
  </view>
  <nut-config-provider :theme-vars="themeVars">
    <nut-calendar
      v-model:visible="state.isVisible"
      :default-value="state.defaultDate"
      type="range"
      :start-date="state.startDate"
      :end-date="state.endDate"
      start-text="入住"
      end-text="退房"
      @close="closeSwitch('isVisible')"
      @choose="setChooseValue"
      @select="select"
    >
    </nut-calendar>
  </nut-config-provider>
</template>

<script setup>
import { ref, reactive, onMounted, watch } from 'vue'

/**
 * 获取今天和明天日期
 */
const getTodayAndTomorrow = () => {
  var today = new Date(); // 获取当前日期

  var todayYear = today.getFullYear();
  var todayMonth = today.getMonth() + 1; // 月份从0开始,所以要加1
  var todayDay = today.getDate();

  var tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000); // 获取明天日期

  var tomorrowYear = tomorrow.getFullYear();
  var tomorrowMonth = tomorrow.getMonth() + 1; // 月份从0开始,所以要加1
  var tomorrowDay = tomorrow.getDate();

  // 跨年处理
  if (tomorrowYear > todayYear) {
    tomorrowMonth = '01';
    tomorrowDay = '01';
  }

  // 跨月处理
  if (tomorrowMonth > 12) {
    tomorrowMonth = '01';
    tomorrowYear = todayYear + 1;
  }

  // 格式化为两位数
  todayMonth = todayMonth < 10 ? '0' + todayMonth : todayMonth;
  todayDay = todayDay < 10 ? '0' + todayDay : todayDay;
  tomorrowMonth = tomorrowMonth < 10 ? '0' + tomorrowMonth : tomorrowMonth;
  tomorrowDay = tomorrowDay < 10 ? '0' + tomorrowDay : tomorrowDay;

  return {
    today: todayYear + '-' + todayMonth + '-' + todayDay,
    tomorrow: tomorrowYear + '-' + tomorrowMonth + '-' + tomorrowDay
  };
}

/**
 * 获取日期星期几
 * @param {String} dateString 日期字符串
 */
const getDayOfWeek = (dateString) => {
  var dateParts = dateString.split('-');
  var year = parseInt(dateParts[0]);
  var month = parseInt(dateParts[1]) - 1; // 月份从 0 开始,所以要减去 1
  var day = parseInt(dateParts[2]);

  var date = new Date(year, month, day);
  var dayOfWeek = date.getDay();

  // 定义星期几的名称数组
  var days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];

  return days[dayOfWeek];
}

/**
 * 计算日期间隔
 * @param {*} startDate
 * @param {*} endDate
 */
const getDayDifference = (startDate, endDate) => {
  var startParts = startDate.split('-');
  var startYear = parseInt(startParts[0]);
  var startMonth = parseInt(startParts[1]) - 1; // 月份从 0 开始,所以要减去 1
  var startDay = parseInt(startParts[2]);

  var endParts = endDate.split('-');
  var endYear = parseInt(endParts[0]);
  var endMonth = parseInt(endParts[1]) - 1; // 月份从 0 开始,所以要减去 1
  var endDay = parseInt(endParts[2]);

  var startDateObj = new Date(startYear, startMonth, startDay);
  var endDateObj = new Date(endYear, endMonth, endDay);

  // 跨年处理
  if (endYear > startYear) {
    endDateObj.setFullYear(endYear);
  }

  // 跨月处理
  if (endMonth > startMonth || (endMonth === startMonth && endDay > startDay)) {
    endDateObj.setMonth(endMonth);
  }

  // 计算两个日期之间的时间差(毫秒数)
  var timeDiff = endDateObj.getTime() - startDateObj.getTime();

  // 将时间差转换为天数
  var dayDiff = Math.floor(timeDiff / (1000 * 3600 * 24));

  return dayDiff;
}

// 调用方法获取今天和明天的日期
const dates = getTodayAndTomorrow();

const emit = defineEmits(['on-dates-change', 'on-dates-close']);

const props = defineProps({
  startDate: {
    type: String,
    default: '',
  },
  endDate: {
    type: String,
    default: '',
  },
});

const state = reactive({
  startDate: dates.today,
  endDate: '',
  checkinDate: dates.today,
  checkoutDate: dates.tomorrow,
  defaultDate: [dates.today, dates.tomorrow],
  betweenDate: getDayDifference(dates.today, dates.tomorrow),
  isVisible: false
});

const themeVars = reactive({
  primaryColor: '#6A4925',
  primaryColorEnd: '#6A4925'
});

watch(
  () => props,
  (val) => {
    // 如果传入了默认日期,则设置默认日期
    if (val.startDate) {
      state.checkinDate = val.startDate;
    }
    if (val.endDate) {
      state.checkoutDate = val.endDate;
    }
    if (val.startDate && val.endDate) {
      state.defaultDate = [val.startDate, val.endDate];
      state.betweenDate = getDayDifference(val.startDate, val.endDate);
    }
  },
  {
    deep: true,
    immediate: true
  }
);

onMounted(() => {
  // 触发日期改变事件
  emit('on-dates-change', { startDate: state.checkinDate, endDate: state.checkoutDate, betweenDate: state.betweenDate, startDateWeek: JSON.stringify(getDayOfWeek(state.checkinDate)), endDateWeek: JSON.stringify(getDayOfWeek(state.checkoutDate)) });
})

const openSwitch = (param) => {
  state[`${param}`] = true;
};
const closeSwitch = (param) => {
  state[`${param}`] = false;
  emit('on-dates-close');
};

/**
 * 日历控件选择日期确认回调
 * @param {*} param
 */

const setChooseValue = (param) => {
  state.checkinDate = param[0][3];
  state.checkoutDate = param[1][3];
  state.defaultDate = [state.checkinDate, state.checkoutDate];
  state.betweenDate = getDayDifference(state.checkinDate, state.checkoutDate);
  emit('on-dates-change', { startDate: state.checkinDate, endDate: state.checkoutDate, betweenDate: state.betweenDate, startDateWeek: JSON.stringify(getDayOfWeek(state.checkinDate)), endDateWeek: JSON.stringify(getDayOfWeek(state.checkoutDate)) });
};


const select = (param) => {
};

const show = ref(false);

const openCalendar = () => {
  show.value = true;
  state.isVisible = true;
}

const onClose = () => {
  show.value = false
}

const onConfirm = (event) => {
  console.warn(event);
}
</script>

<style lang="less">
.calendar-select-page {
  background-color: #F6ECE1;
  border-radius: 0.5rem;
  padding: 1rem 0;
  padding-left: 0.5rem;
}
</style>