uniapp会议预约顶部横向滑动日历和时间线

<template>
  <view class="container">
    <view class="swiper" >
      <view 
          v-for="(item, index) in dateList" 
          :key="index" 
          @click ="ClickDateCheng(item.id, index)" 
          :class="{'selected': selectedIndex === index}"   
          class="box">
          <text style="padding-bottom: 4rpx;">{{ item.label }}</text>
          <text >{{ item.day}}</text>
      </view>
    </view>
    <view class="all">
        <text>{{ year }}年</text>
        <view @click="show = true">{{month }}月</view>
    </view>
    <u-calendar :show="show" @close="show = !show" @confirm="confirm"></u-calendar>
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      single: '',
      dateList: [],
      dateListArray: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
      maxCount: 15, // 横向日期默认显示的日期数量
      clientWidthCount: 0, // 每行显示的数量
      selectedIndex: 0,
      year: new Date().getFullYear(),
      month: new Date().getMonth() + 1,
    };
  },
  methods: {
    // 初始化日期数组
    initDates() {
      // { label:"周一",'day':"22", value:"2023-12-22"}
      this.dateList.push(this.formatData(new Date()))
      for (let i = 1; i <= this.maxCount; i++) {
        let now = new Date();
        this.dateList.push(this.formatData(new Date(now.setDate(now.getDate()+i))))
      }
    },
    formatData(date){
      let nowStr=this.$u.timeFormat(date.getTime(), 'yyyy-mm-dd')
      let label=this.dateListArray[date.getDay()]
      return {
        label:label,
        day:date.getDate(),
        value:nowStr
      }
    },
    confirm(e) {
      const date = new Date(e[0]);   
      this.year = date.getFullYear(); 
      this.month = date.getMonth() + 1;
      const selectedIndex = this.dateList.findIndex(item => item.value === this.$u.timeFormat(date.getTime(), 'yyyy-mm-dd'));
      if (selectedIndex !== -1) {
        this.selectedIndex = selectedIndex;
      }
      this.show = false;  
    },
    // 添加日期到数组
    addDate(date, txt) {
      let year = date.getFullYear();
      let mon = (date.getMonth() + 1 < 10 ? '0' : '') + (date.getMonth() + 1);
      let day = (date.getDate() < 10 ? '0' : '') + date.getDate();
      let week = txt !== "" ? txt : this.dateListArray[date.getDay()];
      let newObj = {
        id: year + '-' + mon + '-' + day,
        text: week,
        mon: mon,
        day: day
      };
      this.Dates.push(newObj);
    },
    // 点击日期事件
    ClickDateCheng(id, index) {
      this.selectedIndex = index;
      this.dateCurrentStr = id;
      // uni.showToast({
      //   title: '加载中...',
      //   icon: 'loading',
      //   duration: 1000
      // });
    }
  },
  created() {
    // 初始化日期数组
    this.initDates();
  },

};
</script>

<style lang="scss" scoped>
.container {
  display: flex;
  flex-direction: row;
  width: 100vw;
  .swiper {
    background: #4b9efc;
    color: white;
    display: flex;
    flex-direction: row;
    overflow-x: scroll;
    white-space: nowrap;
    padding: 8rpx 0;
    .box {
      width: calc(100% / 6 - 50rpx);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      font-size: 12px;
      //width: calc( 100% / 7 - 270rpx );
      padding: 8rpx 15rpx;
      margin: 0 10rpx;
    }
    .selected {
      background-color: #fff; 
      color: #54a6f8; 
      border-radius: 10rpx;
    }
  }
  .all {
    width: 180rpx;
    font-size: 12px;
    display: flex;
    padding: 10rpx;
    align-items: center;
    flex-direction: column;
    justify-content: center;
    background: #2e8ff1;
    color: #FFFFFF;
  }
}
</style>

时间线:timeLine

<template>
  <view>
    <view class="item">
      <view v-for="(item,index) in nums" :key="index" >
        <view>
          {{item}}
        </view>
      </view>
    </view>
    <view style="display: flex;">
      <view v-for="(item,index) in nums" :key="index"
            :style="{width:100/nums.length + '%'}" style="background:#fac7c7;height:30rpx">
        <view v-for="(deepitem,dindex) in colorDeeps"
              :key="dindex">
          <view v-if="item>= deepitem.start && item <deepitem.end" class="deep">
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      nums: [
        7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
      ],
      colorDeeps:[
        { start: 12, end: 14},
        { start: 8, end: 9 }
      ],
    }
  },
  methods: {
  }
}
</script>

<style lang="scss" scoped>
.item{
  font-size: 14px;
  display: flex;
  justify-content: space-around;
  align-items: center;
  color: #999999;
  margin-bottom: 6rpx;
}
.deep{
  background: #fc5967;
  height:30rpx;
}
</style>

优化版:

template>
  <view class="line-box">
    <view  :data-time="timeIntervals[item]"  v-for="item in itemCount" :class="item <disableNumber?'disable':hasBook(item)?'book':''" :key="item" class="line-item">
      <view class="line-time" v-show="isShow(item)">{{ timeIntervals[item].split(":")[0] }}</view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    date: {
      type: String,
      default: ""
    },
    startTime: {
      type: String,
      default: '7:30'
    },
    endTime: {
      type: String,
      default: '22:30'
    },
    bookTime: {
      type: Array,
      default: []
    }
  },
  data() {
    return {
      now: new Date().toISOString().slice(0, 10), // 假设格式为YYYY-MM-DD  
      itemCount: 0,
      timeIntervals: [],
      bookIndex: []
    };
  },
  computed: {
    disableNumber() {
      let date = this.date || this.now;
      if (this.now === date) {
        let nowTime = this.formatTime(new Date(), '{h}:{i}');
        return this.getTimeCount(date, this.startTime, nowTime);
      }
      return -1;
    }
  },
  watch: {
    bookTime(newVal) {
      this.init();
    },
  },
  methods: {
    formatTime(date, format) {
      // 这里你需要一个函数来格式化时间,因为Vue 2没有内置的parseTime
      let hours = date.getHours();
      let minutes = date.getMinutes();
      let formatted = format.replace('{h}', hours.toString().padStart(2, '0'))
          .replace('{i}', minutes.toString().padStart(2, '0'));
      return formatted;
    },
    getTimeCount(dateStr, startTime, endTime) {
      // 假设 dateStr 已经是 "yyyy-MM-dd" 格式  
      // 如果不是,你需要在这里转换它  
      let start = new Date(dateStr.replace(/-/g, '/') + " " + startTime);
      let end = new Date(dateStr.replace(/-/g, '/') + " " + endTime);
      let time = end - start;
      return time / 1000 / 60 / 30;
    },
    // getTimeCount(dateStr, startTime, endTime) {
    //   let start = new Date(dateStr + " " + startTime);
    //   let end = new Date(dateStr + " " + endTime);
    //   let time = end - start;
    //   return time / 1000 / 60 / 30;
    // },
    // getHalfHourIntervals(dateStr, startTime, endTime) {
    //   const intervals = [];
    //   let currentTime = new Date(dateStr + " " + startTime);
    //   let entTime = new Date(dateStr + " " + endTime);
    //   while (currentTime <= entTime) {
    //     intervals.push(this.formatTime(currentTime, '{h}:{i}'));
    //     currentTime.setMinutes(currentTime.getMinutes() + 30);
    //   }
    //   return intervals;
    // },
    getHalfHourIntervals(dateStr, startTime, endTime) {
      const intervals = [];
      let currentTime = new Date(dateStr.replace(/-/g, '/') + " " + startTime);
      let entTime = new Date(dateStr.replace(/-/g, '/') + " " + endTime);
      while (currentTime <= entTime) {
        intervals.push(this.formatTime(currentTime, '{h}:{i}'));
        currentTime.setMinutes(currentTime.getMinutes() + 30);
      }
      return intervals;
    },
    hasBook(item) {
      for (let i = 0; i < this.bookIndex.length; i++) {
        if (item >= this.bookIndex[i][0] && item < this.bookIndex[i][1]) {
          return true;
        }
      }
      return false;
    },
    isShow(item) {
      let time = this.timeIntervals[item].split(':')[0];
      return item % 2 === 1 && parseInt(time, 10) % 2 === 0;
    },
    init() {
      let date = this.date || this.now;
      this.itemCount = this.getTimeCount(date, this.startTime, this.endTime);
      this.timeIntervals = this.getHalfHourIntervals(date, this.startTime, this.endTime);
      this.updateBookIndex();
    },
    updateBookIndex() {
      this.bookIndex = [];
      this.bookTime.forEach(item => {
        let ret = [];
        item.forEach(e => {
          let dataStr = e.split(' ')[0];
          let entTime = e.split(' ')[1];
          ret.push(this.getTimeCount(dataStr, this.startTime, entTime) + 1);
        });
        this.bookIndex.push(ret);
      });
    }
  },
  mounted() {
    this.init();
  }
}
</script>

<style scoped lang="scss">
.line-box {
  height: calc(100vw / 28);
  border: 1px solid silver;
  border-radius: 4px;
  width: 100%;
  display: flex;

  .line-item {
    flex: 1;
    height: 100%;
    position: relative;

    &:nth-child(odd) {
      border-right: 1px silver solid;
    }

    .line-time {
      position: absolute;
      font-size: 8px;
      right: -7px;
      bottom: -18px;
    }
  }
  .book{
    background-color: #fd8888 ;
  }
  .disable {
    //background-color: #b6d2e8;
    background-color: #cbe2fc;
  }
}
</style>
  <view class="buttom" style="height: 50rpx;">
        <timeLine  ref="timeLineRef" :date="date" :book-time="item.reserves?item.reserves.map(v=>
      [v.reserveStartTime, v.reserveEndTime.substring(11, 16) == '00:00'? v.reserveEndTime.substring(0,9)  + (+(v.reserveEndTime.substring(9,10))-1) + ' 24:00:00': v.reserveEndTime]
      ):''"  />
      </view>
    </view>       
//item.reserves: [ {
                reserveStartTime: '2023-09-01 09:00:00',
                reserveEndTime: '2023-09-01 10:00:00'
              },
              {
                reserveStartTime: '2023-09-01 11:00:00',
                reserveEndTime: '2023-09-01 12:00:00'}
]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值