index.vue 9.45 KB
<!--
 * @Date: 2023-06-21 10:23:09
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2023-08-24 15:11:10
 * @FilePath: /front/src/views/index.vue
 * @Description: 文件描述
-->
<template>
  <div class="index-page">
    <div class="app-time">
      预约时间
    </div>
    <div class="shortcut-wrapper">
      <div @click="selectIndex(0)" :class="['today', 'item', index === 0 ? 'selected' : '']">
        <div class="datetime" style="padding: 1rem 0;">
          <div style="font-size: 2rem;">今天</div>
          <div>{{ shortcut[0]?.date }}</div>
        </div>
        <div class="remain">
          <div>剩余名额</div>
          <div><span style="font-weight: bold; font-size: 1.5rem;">{{ shortcut[0]?.rest_count }}</span>人</div>
        </div>
        <div style="position: absolute; bottom: -1rem; left: calc(50% - 1.5rem)">
          <van-icon size="3rem" name="https://cdn.ipadbiz.cn/bieyuan/hua01@2x.png" />
        </div>
      </div>
      <div @click="selectIndex(1)" :class="['tomorrow', 'item', index === 1 ? 'selected' : '']">
        <div class="datetime" style="padding: 1rem 0;">
          <div style="font-size: 1.5rem;">明天</div>
          <div>{{ shortcut[1]?.date }}</div>
        </div>
        <div class="remain">
          <div>剩余名额</div>
          <div><span style="font-weight: bold; font-size: 1.5rem;">{{ shortcut[1]?.rest_count }}</span>人</div>
        </div>
        <div style="position: absolute; bottom: -0.9rem; left: calc(50% - 1rem)">
          <van-icon size="2rem" name="https://cdn.ipadbiz.cn/bieyuan/hua01@2x.png" />
        </div>
      </div>
      <div @click="selectIndex(2)" :class="['after', 'item', index === 2 ? 'selected' : '']">
        <div class="datetime" style="padding: 0.5rem 0;">
          <div style="font-size: 1.25rem;">后天</div>
          <div style="font-size: 0.85rem;">{{ shortcut[2]?.date }}</div>
        </div>
        <div class="remain" style="font-size: 0.85rem; padding: 0.4rem 0;">
          <div>剩余名额</div>
          <div><span style="font-weight: bold; font-size: 1rem;">{{ shortcut[2]?.rest_count }}</span>人</div>
        </div>
        <div style="position: absolute; bottom: -0.7rem; left: calc(50% - 0.75rem)">
          <van-icon size="1.5rem" name="https://cdn.ipadbiz.cn/bieyuan/hua01@2x.png" />
        </div>
      </div>
      <div :class="['more', 'item', index === -1 ? 'selected' : '']">
        <div style="margin-top: 1rem;">
          <van-icon size="1.25rem" name="https://cdn.ipadbiz.cn/bieyuan/rili@2x.png" />
        </div>
        <div style="color: #93663D;" @click="showMore">更多</div>
        <div style="position: absolute; bottom: -0.7rem; left: calc(50% - 0.6rem)">
          <van-icon size="1.2rem" name="https://cdn.ipadbiz.cn/bieyuan/hua01@2x.png" />
        </div>
      </div>
    </div>
    <div class="shortcut-bottom"></div>

    <div class="bookingBox">
        <van-row>
          <van-col span="6" class="text">预约人数</van-col>
          <van-col span="18" class="control">
            <van-row style="line-height: 3rem;" gutter="10">
              <van-col span="4" style="text-align: center;">
                <div @click="clickMinus" class="minus">
                <van-icon size="0.85rem" name="https://cdn.ipadbiz.cn/bieyuan/-@2x.png" />
              </div>
              </van-col>
              <van-col span="14" style="text-align: center;">
                <input v-model="num" type="number" class="input_num">
              </van-col>
              <van-col span="2" style="text-align: center;">
                <span>人</span>
              </van-col>
              <van-col span="4" style="text-align: center;">
                <div @click="clickPlus" class="plus">
                <van-icon size="0.85rem" name="https://cdn.ipadbiz.cn/bieyuan/+@2x.png" />
              </div>
              </van-col>
            </van-row>
          </van-col>
        </van-row>
      </div>

    <div>
      <div @click="clickNext" class="next-btn">下一步</div>
    </div>

    <van-calendar v-model:show="show" type="multiple" :max-range="7" @confirm="onConfirm" color="#93663D" />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import dayjs from 'dayjs'
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { showSuccessToast, showFailToast } from 'vant';
import { orderRestCountAPI } from '@/api/index'
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);

onMounted(async () => {
  const { data } = await orderRestCountAPI();
  // 获取三天数据
  shortcut.value = data;
  // 上一页选择的预约人数 或者 默认值为 1
  num.value = $route.query.count ? +$route.query.count : 1;
  // 默认勾选今天
  selectedDates.value = shortcut.value[0]['date'];
  // 从上一页退回时处理 选中值只有一个
  const dates = $route.query.dates ? JSON.parse($route.query.dates) : '';
  if (dates.length) {
    // 选中值的索引值
    index.value = shortcut.value.findIndex((item) => {
      if (item.date === dates[0]) {
        return item
      }
    });
    // 默认选中日期
    selectedDates.value = dates[0];
  }
});

const num = ref(1);
const show = ref(false);
const selectedDates = ref([]);
const index = ref(0);
const shortcut = ref([]);

const showMore = () => {
  show.value = true;
}

const onConfirm = (dates) => { // 选择日历确定回调
  show.value = false;
  index.value = -1;
  selectedDates.value = [];
  // 保存选中的日期
  dates.forEach((date) => {
    selectedDates.value.push(dayjs(date).format('YYYY-MM-DD'));
  });
};

const selectIndex = (idx) => { // 保存手动点击的索引值
  index.value = idx;
}

const clickMinus = () => { // 减少预约数
  num.value = num.value > 1 ? num.value - 1 : 1;
}
const clickPlus = () => { // 新增预约数
  num.value = num.value + 1;
}

const clickNext = () => { // 点击下一步按钮
  if (!isPositiveInteger(num.value)) { // 判断是否是非零整数
    showFailToast('请检查预约人数输入!');
    return false;
  }
  if (isMinValue(shortcut.value, num.value)) {
    showFailToast('剩余名额小于预约人数!');
    return false;
  }

  let dates = [];
  if (index.value > -1) { // 选择快捷方式
    dates.push(shortcut.value[index.value]['date']);
    // 跳转确认页
    $router.push({
      path: '/next',
      query: {
        dates: JSON.stringify(dates),
        count: num.value,
        page: 'single'
      }
    });
  } else { // 选择日历
    dates = selectedDates.value;
    // 跳转更多确认页
    $router.push({
      path: '/preview',
      query: {
        dates: JSON.stringify(dates),
        count: num.value
      }
    });
  }
}

const isPositiveInteger = (value) => {
  // 判断是否为数字
  if (typeof value !== 'number') {
    return false;
  }

  // 判断是否为正整数
  return Number.isInteger(value) && value > 0;
}

const isMinValue = (array, value) => { // 判断输入值是否小于数组中剩余名额数
  let result = array.filter((item) => item.rest_count < value);
  return result.length > 0;
}

</script>

<style lang="less" scoped>
.index-page {
  padding: 1rem 1rem 0;
  .app-time {
    padding-bottom: 0.5rem;
    border-bottom: 1px solid #D7D7D7;
    font-weight: bold;
    font-size: 1.05rem;
  }
  .shortcut-wrapper {
    padding-top: 2rem;
    display: flex;
    align-items: flex-end;
  }
  .shortcut-bottom {
    width: 100%;
    height: 4px;
    background-color: #93663D;
  }

  .item {
    position: relative;
    overflow: hidden;
    border: 1px solid #D7D7D7;
    border-radius: 10px 10px 0px 0px;
    text-align: center;

    .datetime {
      div:first-child {
        font-weight: bold;
        color: #93663D;
        margin-bottom: 0.25rem;
      }

      div:last-child {
        color: #B79679;
      }
    }

    .remain {
      color: #93663D;
      font-size: 1.15rem;
      padding: 1rem 0;

      div:first-child {
        margin-bottom: 0.25rem;
      }
    }
  }

  .selected {
    border: 2px solid #93663D;
    border-bottom: 0;
  }

  .today {
    flex: 1.5;
    height: 15rem;
    background: #FBF8F4;
  }

  .tomorrow {
    flex: 1.5;
    height: 13rem;
    background: #F3F7F0;
  }

  .after {
    flex: 1;
    height: 10rem;
    background: #F3F7FB;
  }

  .more {
    flex: 1/2;
    height: 4rem;
    background: #FBF3F4;
    padding: 0.5rem;
  }

  .bookingBox {
    padding: 2rem 0 1rem;
    border-bottom: 1px solid #D7D7D7;

    .text {
      line-height: 3.1rem;
      font-weight: bold;
      font-size: 1.05rem;
    }

    .control {
      text-align: right;
    }

    .minus,
    .plus {
      width: 2rem;
      height: 2rem;
      background: #FFFFFF;
      border: 1px solid #D7D7D7;
      border-radius: 50%;
      text-align: center;
      line-height: 2rem;
      display: inline-block;

    }
    // .input-box {
    //   width: 40%;
    //   display: inline-block;
    // }
    .input_num {
      border: 0;
      background-color: #F7F7F7;
      height: 2.5rem;
      width: 6.5rem;
      color: #976C46;
      text-align: center;
      font-weight: bold;
      font-size: 1.5rem;
      margin: 0 1rem;
    }
  }

  .next-btn {
    background-color: #93663D;
    width: 70%;
    height: 3rem;
    color: white;
    line-height: 3rem;
    text-align: center;
    font-size: 1.25rem;
    margin-left: calc(20% - 1rem);
    margin-top: 5rem;
  }
}
</style>