微信小程序实现酒店预订选择日期功能

小程序选择酒店入住时间及离店时间功能开发,带节假日及选择高亮功能,日期格式: ‘2020-07-23’附上效果图

wxml:

<view style="position:fixed;top:0;background:#F5F5F5;font-size: 30rpx; padding-top: 10rpx;padding-bottom: 10rpx;">
	<view class="layout-flex row" style="background-color: #F5F5F5;">
		<text class="date-week" style="width:87rpx; height:40rpx" wx:for="{{weekStr}}" wx:key="index">
                 <text wx:if="{{item !=='日' && item !=='六'}}">{{item}}</text>
		<text wx:if="{{item ==='日' || item ==='六'}}" class="week">{{item}}</text>
		</text>
	</view>
</view>
<view style="margin-top: 100rpx"></view>
<view wx:for="{{dateList}}" wx:key="index" wx:for-item="dateItem" style="padding: 16rpx 0">
	<view class="date-year-month" style="text-align: center;font-size:35rpx;">{{dateItem.year}}年{{dateItem.month}}月</view>
	<view class="layout-flex row" style="flex-wrap: wrap;margin-top:30rpx;">
		<view class="date-day {{item.day<=0?'bgwhite':item.class}}" style="width:87rpx; height:107rpx;" data-year="{{dateItem.year}}" data-month="{{dateItem.month}}" data-day="{{item.day}}" bindtap="onPressDate" wx:for="{{dateItem.days}}" wx:key="index">
			<view class='item-days'>
				<text style='font-size:28rpx;'>{{item.day>0?(item.daytext?item.daytext:item.day):''}}</text>
				<text style='font-size:30rpx;' wx:if="{{item.inday}}">入住</text>
				<text style='font-size:30rpx;' wx:if="{{item.outday}}">离店</text>
			</view>
		</view>
	</view>
</view>

wxss:

/* pages/dateSelect/dateSelect.wxss */
.date-day{
  display: flex;
  padding:5px;
  text-align:center;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
.date-day.bgitem{
background-color: #dfbb92;
}
.date-day.active{
  background: #daab75;
  color:#FFF;
  
}
.date-day.unavailable{
  color:#aaa;
}

.date-week{
  display: flex;
  justify-content: center;
  align-content: center;
  margin:5px;
}
.row{
display: flex;
flex-direction: row;
}
.item-days{
display: flex;
flex-direction:column;
justify-content: center;
align-items: center;
font-size: 35rpx;
} 
.bgwhite{
background-color: #fff;
}

js:

const app = getApp().globalData;
const dateChange = require('../../utils/dateChange');
let Moment = require("../../utils/moment.js");
let DATE_LIST = [];
let DATE_YEAR = new Date().getFullYear();
let DATE_MONTH = new Date().getMonth() + 1;
let DATE_DAY = new Date().getDate();
Page({
  data: {
    maxMonth: 3, //最多渲染月数
    dateList: [],
    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();
    let _this = this;
    // 页面初始化 options为页面跳转所带来的参数
 
    let checkInDate = options.checkInDate ? options.checkInDate : Moment(new Date()).format('YYYY-MM-DD');
    let checkOutDate = options.checkOutDate ? options.checkOutDate : Moment(new Date()).add(1, 'day').format('YYYY-MM-DD');
    _this.setData({ checkInDate, 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 () {
    let dateList = [];
    let 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 (let i = 0; i < this.data.maxMonth; i++) {
      let momentDate = Moment(now).add(this.data.maxMonth - (this.data.maxMonth - i), 'month').date;
      let year = momentDate.getFullYear();
      let month = momentDate.getMonth() + 1;

      let days = [];
      let totalDay = this.getTotalDayByMonth(year, month);
      let week = this.getWeek(year, month, 1);
      //-week是为了使当月第一天的日期可以正确的显示到对应的周几位置上,比如星期三(week = 2),
      //则当月的1号是从列的第三个位置开始渲染的,前面会占用-2,-1,0的位置,从1开正常渲染
      for (let j = -week + 1; j <= totalDay; j++) {
        let tempWeek = -1;
        if (j > 0)
          tempWeek = this.getWeek(year, month, j);
        let 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 })
      }
      let dateItem = {
        id: year + '-' + month,
        year: year,
        month: month,
        days: days
      }

      dateList.push(dateItem);
    }
    let 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);
    let d = new Date(year, month, 0);
    return d.getDate();
  },
	/*
	 * 获取月的第一天是星期几
	 */
  getWeek: function (year, month, day) {
    let d = new Date(year, month - 1, day);
    return d.getDay();
  },
  /**
   * 点击日期事件
   */
  onPressDate: function (e) {
    let { year, month, day } = e.currentTarget.dataset;
    //当前选择的日期为同一个月并小于今天,或者点击了空白处(即day<0),不执行
    if ((day < DATE_DAY && month == DATE_MONTH) || day <= 0) return;

    let tempMonth = month;
    let tempDay = day;

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

    let 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,
      });

      //  入店,离店日期都必须在30天内
      let today = Date.parse(wx.getStorageSync('today'));
      let inDate=(Date.parse(this.data.checkInDate) - today)/(1*24*60*60*1000);
      let outDate=(Date.parse(this.data.checkOutDate) - today)/(1*24*60*60*1000);
      if(inDate > 30 || outDate> 30) {
        wx.showModal({ title: '提示', content: '抱歉,只接受30天之内的预定', showCancel: false })
        this.setData({ markcheckOutDate: false })
        return;
      }

      //设缓存,返回页面时,可在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();//重新点击时数据初始化
    let dateList = this.data.dateList;
    //渲染点击样式
    for (let i = 0; i < dateList.length; i++) {
      let dateItem = dateList[i];
      let id = dateItem.id;
      if (id === year + '-' + month) {
        let days = dateItem.days;
        for (let j = 0; j < days.length; j++) {
          let tempDay = days[j].day;
          if (tempDay == day) {
            days[j].class = days[j].class + ' active';
            days[j].inday = true;
            break;
          }
        }
        break;
      }
    }
    this.setData({
      dateList: dateList
    });
  }
})

渲染的月份数量在这做控制
控制显示的月份数量

选择日期后回到上个页面,在返回的页面onshow中,通过getStorageSync就能获取选择的日期!

补充moment.js:

var Moment = function (date) {
  var date;
  if (date)
    this.date = new Date(date);
  else
    this.date = new Date();
  return this;
};
/**       
 * 对Date的扩展,将 Date 转化为指定格式的String       
 * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符       
 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)       
 * eg:       
 * "yyyy-MM-dd hh:mm:ss.S" ==> 2006-07-02 08:09:04.423    
 * "yyyy-M-d h:m:s.S" ==> 2006-7-2 8:9:4.18       
 * "yyyy-MM-dd E HH:mm:ss" ==> 2009-03-10 二 20:09:04       
 * "yyyy-MM-dd EE hh:mm:ss" ==> 2009-03-10 周二 08:09:04       
 * "yyyy-MM-dd EEE hh:mm:ss" ==> 2009-03-10 星期二 08:09:04  
 */
Moment.prototype.format = function (format) {
  var date = this.date;
  /*
      var r= /^(\d{4})-(\d{1,2})-(\d{1,2})$/; //正则表达式 匹配出生日期(简单匹配)     
      r.exec('1985-10-15');
      s1=RegExp.$1;s2=RegExp.$2;s3=RegExp.$3;//结果为1985 10 15
      */
  if (typeof date === 'string')
    date = this.parse(date);
  var o = {
    "M+": date.getMonth() + 1, //月份 
    "(d+|D+)": date.getDate(), //日 
    "(h+|H+)": date.getHours(), //小时 
    "m+": date.getMinutes(), //分 
    "s+": date.getSeconds(), //秒 
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度 
    "S": date.getMilliseconds() //毫秒 
  };
  var week = {
    "0": "/u65e5",
    "1": "/u4e00",
    "2": "/u4e8c",
    "3": "/u4e09",
    "4": "/u56db",
    "5": "/u4e94",
    "6": "/u516d"
  };
  if (/(y+|Y+)/.test(format))
    format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  if (/(E+)/.test(format))
    format = format.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[date.getDay() + ""]);
  for (var k in o) {
    if (new RegExp("(" + k + ")").test(format))
      format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  }
  return format;
}

Moment.prototype.parse = function () {
  return this.date;
}
/**
 * 计算两个日期差差
 * return day
 */
Moment.prototype.differ = function (date) {
  var time1 = this.date.getTime();
  if (typeof date === 'string')
    date = new Date(date);
  var time1 = this.date.getTime();
  var time2 = date.getTime();
  var differ = Math.ceil((time1 - time2) / (1000 * 3600 * 24));//除不尽时,向上取整
  return differ;
}

Moment.prototype.add = function (num, optionType) {
  var date = this.date;
  if ('day' === optionType) {
    date.setDate(date.getDate() + num);
  }
  if ('month' === optionType) {
    date.setMonth(date.getMonth() + num);
  }
  if ('year' === optionType) {
    date.setFullYear(date.getFullYear() + num);
  }
  this.date = date;
  return this;
}

Moment.prototype.before = function (date) {
  return this.date.getTime() < new Date(date).getTime()
}
Moment.prototype.after = function (date) {
  return this.date.getTime() > date.getTime()
}

module.exports = function (date) {
  return new Moment(date);
}```

希望能帮助正在成长的你!



  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值