微信小程序—仿美團酒店入住日期時段選擇

美團市值突飛猛進,確實霸佔了我們的喫喝玩樂,所以想做什麼東西,研究一下美團也是不錯的。最近需要用到一個酒店入住日期選擇的組件,看了一下美團的設計,很好用,在此實現一下。

效果圖如下:

在這裏插入圖片描述

體驗路徑(並獲取源碼):

在這裏插入圖片描述

代碼邏輯:

var Moment = require("../../utils/moment.js");
var DATE_LIST = [];
var DATE_YEAR = new Date().getFullYear();
var DATE_MONTH = new Date().getMonth() + 1;
var DATE_DAY = new Date().getDate();
Page({
  data: {
    maxMonth: 7, //最多渲染月數
    dateList: [],
    systemInfo: {},
    weekStr: ['日', '一', '二', '三', '四', '五', '六'],
    checkInDate: Moment(new Date()).format('YYYY-MM-DD'),
    checkOutDate: Moment(new Date()).add(1, 'day').format('YYYY-MM-DD'),
    markcheckInDate: false, //標記開始時間是否已經選擇
    markcheckOutDate: false,   //標記結束時間是否已經選擇
    sFtv: [
      {
        month:1,
        day:1,
        name:"元旦"
      },
      {
        month: 2,
        day: 14,
        name: "情人節"
      },
      {
        month: 3,
        day: 8,
        name: "婦女節"
      },
      {
        month: 3,
        day: 12,
        name: "植樹節"
      },
      {
        month: 3,
        day: 15,
        name: "消費者權益日"
      },
      {
        month: 4,
        day: 1,
        name: "愚人節"
      },
      {
        month: 5,
        day: 1,
        name: "勞動節"
      },
      {
        month: 5,
        day: 4,
        name: "青年節"
      },
      {
        month: 5,
        day: 12,
        name: "護士節"
      },
      {
        month: 6,
        day: 1,
        name: "兒童節"
      },
      {
        month: 7,
        day: 1,
        name: "建黨節"
      },
      {
        month: 8,
        day: 1,
        name: "建軍節"
      },
      {
        month: 9,
        day: 10,
        name: "教師節"
      },
      {
        month: 9,
        day: 28,
        name: "孔子誕辰"
      },
      {
        month: 10,
        day: 1,
        name: "國慶節"
      },
      {
        month: 10,
        day: 6,
        name: "老人節"
      },
      {
        month: 10,
        day: 24,
        name: "聯合國日"
      },
      {
        month: 12,
        day: 24,
        name: "平安夜"
      },
      {
        month: 12,
        day: 25,
        name: "聖誕節"
      }
    ]
  },
  onLoad: function (options) {
    // 頁面初始化 options爲頁面跳轉所帶來的參數
    this.createDateListData();
    var _this = this;
    // 頁面初始化 options爲頁面跳轉所帶來的參數

    var checkInDate = options.checkInDate ? options.checkInDate : Moment(new Date()).format('YYYY-MM-DD');
    var checkOutDate = options.checkOutDate ? options.checkOutDate : Moment(new Date()).add(1, 'day').format('YYYY-MM-DD');
    wx.getSystemInfo({
      success: function (res) {
        _this.setData({ systemInfo: res, checkInDate: checkInDate, checkOutDate: checkOutDate });
      }
    })
  },
  onReady: function () {
    // 頁面渲染完成
  },
  onShow: function () {
    this.selectDataMarkLine()
  },
  onHide: function () {
    // 頁面隱藏
  },
  onUnload: function () {
    // 頁面關閉
  },

  //選擇的入住與離店時間段
  selectDataMarkLine: function () {
    let dateList = this.data.dateList;
    let { checkInDate, checkOutDate } = wx.getStorageSync("ROOM_SOURCE_DATE");
    let curreInid = checkInDate.substr(0, 4) + "-" + (checkInDate.substr(5, 2) < 10 ? checkInDate.substr(6, 1) : checkInDate.substr(5, 2));//選擇入住的id
    let curreOutid = checkOutDate.substr(0, 4) + "-" + (checkOutDate.substr(5, 2) < 10 ? checkOutDate.substr(6, 1) : checkOutDate.substr(5, 2));//選擇離店的id
    let dayIn = checkInDate.substr(8, 2) >= 10 ? checkInDate.substr(8, 2) : checkInDate.substr(9, 1);//選擇入住的天id
    let dayOut = checkOutDate.substr(8, 2) >= 10 ? checkOutDate.substr(8, 2) : checkOutDate.substr(9, 1);//選擇離店的天id
    let monthIn = checkInDate.substr(5, 2) >= 10 ? checkInDate.substr(5, 2) : checkInDate.substr(6, 1);//選擇入店的月id
    let monthOut = checkOutDate.substr(5, 2) >= 10 ? checkOutDate.substr(5, 2) : checkOutDate.substr(6, 1);//選擇離店的月id
    if (curreInid == curreOutid) {//入住與離店是當月的情況
      for (let i = 0; i < dateList.length; i++) {
        if (dateList[i].id == curreInid) {
          let days = dateList[i].days;
          for (let k = 0; k < days.length; k++) {
            if (days[k].day >= dayIn && days[k].day <= dayOut) {
              days[k].class = days[k].class + ' bgitem';
            }
            if (days[k].day == dayIn) {
              days[k].class = days[k].class + ' active';
              days[k].inday = true;
            }
            if (days[k].day == dayOut) {
              days[k].class = days[k].class + ' active';
              days[k].outday = true;
            }
          }
        }
      }
    } else {//跨月
      for (let j = 0; j < dateList.length; j++) {
        if (dateList[j].month == monthIn) {//入住的開始月份
          let days = dateList[j].days;
          for (let k = 0; k < days.length; k++) {
            if (days[k].day >= dayIn) {
              days[k].class = days[k].class + ' bgitem';
            }
            if (days[k].day == dayIn) {
              days[k].class = days[k].class + ' active';
              days[k].inday = true;
            }
          }
        } else {//入住跨月月份
          if (dateList[j].month < monthOut && dateList[j].month > monthIn) {//離店中間的月份
            let days = dateList[j].days;
            for (let k = 0; k < days.length; k++) {
              days[k].class = days[k].class + ' bgitem';
            }
          } else if (dateList[j].month == monthOut) {//離店最後的月份
            let days = dateList[j].days;
            for (let k = 0; k < days.length; k++) {
              if (days[k].day <= dayOut) {
                days[k].class = days[k].class + ' bgitem';
              }
              if (days[k].day == dayOut) {
                days[k].class = days[k].class + ' active';
                days[k].outday = true;
              }
            }
          }
        }
      }
    }
    this.setData({
      dateList: dateList
    })
  },

  createDateListData: function () {
    var dateList = [];
    var now = new Date();
    /*
      設置日期爲 年-月-01,否則可能會出現跨月的問題
      比如:2017-01-31爲now ,月份直接+1(now.setMonth(now.getMonth()+1)),則會直接跳到跳到2017-03-03月份.
        原因是由於2月份沒有31號,順推下去變成了了03-03
    */
    now = new Date(now.getFullYear(), now.getMonth(), 1);
    for (var i = 0; i < this.data.maxMonth; i++) {
      var momentDate = Moment(now).add(this.data.maxMonth - (this.data.maxMonth - i), 'month').date;
      var year = momentDate.getFullYear();
      var month = momentDate.getMonth() + 1;

      var days = [];
      var totalDay = this.getTotalDayByMonth(year, month);
      var week = this.getWeek(year, month, 1);
      //-week是爲了使當月第一天的日期可以正確的顯示到對應的周幾位置上,比如星期三(week = 2),
      //則當月的1號是從列的第三個位置開始渲染的,前面會佔用-2,-1,0的位置,從1開正常渲染
      for (var j = -week + 1; j <= totalDay; j++) {
        var tempWeek = -1;
        if (j > 0)
          tempWeek = this.getWeek(year, month, j);
        var clazz = '';
        if (tempWeek == 0 || tempWeek == 6)
          clazz = 'week'
        if (j < DATE_DAY && year == DATE_YEAR && month == DATE_MONTH)
          //當天之前的日期不可用
          clazz = 'unavailable ' + clazz;
        else
          clazz = '' + clazz
        days.push({ day: j, class: clazz })
      }
      var dateItem = {
        id: year + '-' + month,
        year: year,
        month: month,
        days: days
      }

      dateList.push(dateItem);
    }
    var sFtv = this.data.sFtv;
    for (let i = 0; i < dateList.length; i++){//加入公曆節日
       for(let k = 0; k < sFtv.length; k++){
         if (dateList[i].month == sFtv[k].month){
           let days = dateList[i].days;
           for (let j = 0; j < days.length; j++){
             if (days[j].day == sFtv[k].day){
               days[j].daytext = sFtv[k].name
             }
           }
         }
       }
    }
    this.setData({
      dateList: dateList
    });
    DATE_LIST = dateList;
  },

  /*
	 * 獲取月的總天數
	 */
  getTotalDayByMonth: function (year, month) {
    month = parseInt(month, 10);
    var d = new Date(year, month, 0);
    return d.getDate();
  },
	/*
	 * 獲取月的第一天是星期幾
	 */
  getWeek: function (year, month, day) {
    var d = new Date(year, month - 1, day);
    return d.getDay();
  },
  /**
   * 點擊日期事件
   */
  onPressDate: function (e) {
    var { year, month, day } = e.currentTarget.dataset;
    //當前選擇的日期爲同一個月並小於今天,或者點擊了空白處(即day<0),不執行
    if ((day < DATE_DAY && month == DATE_MONTH) || day <= 0) return;

    var tempMonth = month;
    var tempDay = day;

    if (month < 10) tempMonth = '0' + month
    if (day < 10) tempDay = '0' + day

    var date = year + '-' + tempMonth + '-' + tempDay;

    //如果點擊選擇的日期A小於入住時間,則重新渲染入住時間爲A
    if ((this.data.markcheckInDate && Moment(date).before(this.data.checkInDate) || this.data.checkInDate === date)) {
      this.setData({
        markcheckInDate: false,
        markcheckOutDate: false,
        dateList: DATE_LIST.concat()
      });
    };

    if (!this.data.markcheckInDate) {
      this.setData({
        checkInDate: date,
        markcheckInDate: true,
        dateList: DATE_LIST.concat()
      });
    } else if (!this.data.markcheckOutDate) {
      this.setData({
        checkOutDate: date,
        markcheckOutDate: true,
      });
      //設緩存,返回頁面時,可在onShow時獲取緩存起來的日期
      wx.setStorage({
        key: 'ROOM_SOURCE_DATE',
        data: {
          checkInDate: this.data.checkInDate,
          checkOutDate: this.data.checkOutDate
        }
      });
      wx.navigateBack({
        delta: 1, // 回退前 delta(默認爲1) 頁面
      });
    }

    this.renderPressStyle(year, month, day);
  },
  renderPressStyle: function (year, month, day) {
    this.createDateListData();//重新點擊時數據初始化
    var dateList = this.data.dateList;
    //渲染點擊樣式
    for (var i = 0; i < dateList.length; i++) {
      var dateItem = dateList[i];
      var id = dateItem.id;
      if (id === year + '-' + month) {
        var days = dateItem.days;
        for (var j = 0; j < days.length; j++) {
          var tempDay = days[j].day;
          if (tempDay == day) {
            days[j].class = days[j].class + ' active';
            days[j].inday = true;
            break;
          }
        }
        break;
      }
    }
    this.setData({
      dateList: dateList
    });
  }
})

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章