index.vue 9.38 KB
<!--
 * @Date: 2022-09-19 14:11:06
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2024-03-28 13:00:53
 * @FilePath: /meihuaApp/src/pages/detail/index.vue
 * @Description: 房间详情页面
-->
<template>
  <view class="detail-page">
    <nut-swiper :init-page="page" :pagination-visible="true" pagination-color="#426543" auto-play="5000">
      <nut-swiper-item v-for="(item, index) in state.imgData" :key="index">
        <image @tap="showFn" style="width: 100%; height: 200px;" mode="aspectFill" :src="item.src" />
      </nut-swiper-item>
    </nut-swiper>
    <view class="detail-info-wrapper">
      <view class="detail-info-title">{{ state.roomInfo.title }}</view>
      <view class="detail-info-content">{{ state.roomInfo.room_num }}室 宜住{{ state.roomInfo.capacity }}人</view>
    </view>
    <!-- 日历选择器 -->
    <view class="book-cal">
      <calendar-select @on-dates-change="onDatesChange" :start-date="start_date" :end-date="end_date" @on-dates-close="onDatesClose"></calendar-select>
    </view>
    <!-- <view v-else class="no-calendar-border"></view> -->
    <!-- END -->
    <view v-if="state.roomInfo.description" class="detail-introduce-title">房间介绍</view>
    <view class="detail-introduce-html">
      <view id="taro_html" v-html="state.roomInfo.description" class="taro_html"></view>
      <view style="height: 6rem;"></view>
    </view>
    <view class="book-bar">
      <nut-row>
        <nut-col :span="18">
          <view class="book-price">
            <view class="price"><nut-price :price="state.roomInfo.discount_price" size="large" /></view>
            <view class="old-price"><nut-price :price="state.roomInfo.original_price" size="small" strike-through style="color: #7D7C7C;" /></view>
          </view>
        </nut-col>
        <nut-col :span="6">
          <view class="book-btn" @tap="goToConfirm">预定</view>
        </nut-col>
      </nut-row>
    </view>
    <nut-image-preview :show="state.showPreview" :images="state.imgData" :is-Loop="false" @close="hideFn" />
  </view>
</template>

<script setup>
import Taro from '@tarojs/taro'
import { ref, computed, reactive, onMounted } from "vue";
import calendarSelect from '@/components/calendarSelect.vue'
import { getCurrentPageParam } from "@/utils/weapp";
import { getRoomAPI, showMyInfoAPI } from '@/api/index'

/**
 * 获取日期星期几
 * @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 showBook = computed(() => {
  return state.roomInfo.num > 0;
});

const page = ref('1'); // banner图索引

const start_date = ref('');
const end_date = ref('');
const between_date = ref('');
const start_date_week = ref('');
const end_date_week = ref('');

// 日期选择回调
const onDatesChange = async ({ startDate, endDate, betweenDate, startDateWeek, endDateWeek }) => {
  start_date.value = startDate;
  end_date.value = endDate;
  start_date_week.value = startDateWeek;
  end_date_week.value = endDateWeek;
  between_date.value = betweenDate;
  // 获取房间详情
  let params = getCurrentPageParam();
  const { code, data } = await getRoomAPI({ i: params.id, start_date: start_date.value, end_date: end_date.value, room_type: params.room_type });
  if (code) {
    state.roomInfo = data;
    // 轮播图
    if (state.roomInfo.banner.length) {
      state.imgData = [];
      state.roomInfo.banner.forEach(item => {
        state.imgData.push({
          src: item
        })
      });
    }
    if (!state.roomInfo.num) {
      Taro.showToast({
        title: '该时段房间已售罄,请重新选择日期',
        icon: 'none',
        duration: 3000,
      });
    }
  }
}

const onDatesClose = async () => {

}

const state = reactive({
  showPreview: false,
  imgData: [],
  roomInfo: {},
  phone: '',
});

onMounted(async () => {
  let params = getCurrentPageParam();
  // 日历控件日期初始化
  start_date.value = params.start_date;
  end_date.value = params.end_date;
  between_date.value = getDayDifference(params.start_date, params.end_date);
  start_date_week.value = JSON.stringify(getDayOfWeek(params.start_date));
  end_date_week.value = JSON.stringify(getDayOfWeek(params.end_date));
  // 获取房间详情
  const roomData = await getRoomAPI({ i: params.id, start_date: params.start_date, end_date: params.end_date, room_type: params.room_type });
  if (roomData.code) {
    state.roomInfo = roomData.data;
    // 轮播图
    if (state.roomInfo.banner.length) {
      state.imgData = [];
      state.roomInfo.banner.forEach(item => {
        state.imgData.push({
          src: item
        })
      });
    }
    // 给所有 img 标签添加 mode 缩放模式
    Taro.options.html.transformElement = (el) => {
      if (el.nodeName === 'image') {
        el.setAttribute('mode', 'widthFix')
      }
      return el
    }
  }
});

// 预定房间
const goToConfirm = async () => {
  let params = getCurrentPageParam();
  // 获取用户信息
  const myInfoData = await showMyInfoAPI();
  if (myInfoData.code) {
    state.phone = myInfoData.data.wxapp_user_phone;
  }
  if (state.phone) {
    // 查看是否选择日期
    if (!start_date.value || !end_date.value) {
      Taro.showToast({
        title: '请先选择入住时间段',
        icon: 'none',
        duration: 1000,
      });
      return false;
    }
    if (!showBook.value) {
      Taro.showToast({
        title: '该时段房间已售罄,请重新选择日期',
        icon: 'none',
        duration: 1000,
      });
      return false;
    }
    Taro.navigateTo({
      url: `/pages/confirm/index?id=${params.id}&start_date=${start_date.value}&end_date=${end_date.value}&between_date=${between_date.value}&start_date_week=${start_date_week.value}&end_date_week=${end_date_week.value}&room_type=${params.room_type}`,
    });
  } else { // 没有手机号记录,需要绑定手机号后再预定房间
    Taro.showToast({
      title: '请先绑定手机号',
      icon: 'none',
      duration: 2000,
      success: () => {
        setTimeout(() => {
          Taro.navigateTo({
            url: `/pages/login/index?page=detail`,
          });
        }, 1000);
      },
    });
  }
}

const showFn = () => {
  state.showPreview = true;
};

const hideFn = () => {
  state.showPreview = false;
};
</script>

<script>
import "./index.less";
import mixin from '@/utils/mixin';

export default {
  name: "detailPage",
  mixins: [mixin.init],
  onShareAppMessage(options) {
    let params = getCurrentPageParam();
    // 设置菜单中的转发按钮触发转发事件时的转发内容
    var shareObj = {
      title: "梅花岛-房间详情",    // 默认是小程序的名称(可以写slogan等)
      path: `pages/detail/index?id=${params.id}&start_date=${params.start_date}&end_date=${params.end_date}&room_type=${params.room_type}`,    // 默认是当前页面,必须是以‘/'开头的完整路径
      imageUrl: '',   //自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径,支持PNG及JPG,不传入 imageUrl 则使用默认截图。显示图片长宽比是 5:4
      success: function (res) {
        // 转发成功之后的回调
        if (res.errMsg == 'shareAppMessage:ok') {
          //
        }
      },
      fail: function () {
        // 转发失败之后的回调
        if (res.errMsg == 'shareAppMessage:fail cancel') {
          // 用户取消转发
        } else if (res.errMsg == 'shareAppMessage:fail') {
          // 转发失败,其中 detail message 为详细失败信息
        }
      },
      complete: function () {
        // 转发结束之后的回调(转发成不成功都会执行)
      }
    }
    // 来自页面内的按钮的转发
    // if (options.from == 'button') {
    //   var eData = options.target.dataset;
    //   // 此处可以修改 shareObj 中的内容
    //   shareObj.path = '/pages/goods/goods?goodId=' + eData.id;
    // }
    // 返回shareObj
    return shareObj;
  }
};
</script>