k94314517
2024-05-10 0df3c99a23b6774c39abf16af51cf20bbfefc8a5
h5/components/Li-Calendar/Li-Calendar.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,702 @@
<template>
   <view>
      <view class='calendar-Time-header under_line'>
         <view class="header-left">
            <!-- <image :src="lastDisabled ? disable : nodisable" mode="widthFix" @tap="subMonth"></image> -->
            <image :src="nodisable" mode="widthFix" @tap="subMonth"></image>
            <text>{{title_time}}</text>
            <image src="@/static/meeting/icon/ar_right@2x.png" mode="widthFix" @tap="addMonth"></image>
         </view>
         <view class="header-right" @tap="backToToday">回到今天</view>
         <!-- <text class='calendar-lastMonth' @tap="subMonth" v-bind:class="{'calendar-btn-disabled' : lastDisabled }">{{lastText}}</text>
         <text class='calendar-TimeH'>{{title_time}}</text>
         <text class='calendar-nextMonth' @tap="addMonth" v-bind:class="{'calendar-btn-disabled' : nextDisabled }">{{nextText}}</text>
         <text class='calendar-backToToday' @tap="backToToday">回到今天</text> -->
      </view>
      <view class='ClearBoth'></view>
      <view class="calendar-content">
         <view class="calendar-row calendar-header">
            <view class="calendar-col aligncanter">周日</view>
            <view class="calendar-col aligncanter">周一</view>
            <view class="calendar-col aligncanter">周二</view>
            <view class="calendar-col aligncanter">周三</view>
            <view class="calendar-col aligncanter">周四</view>
            <view class="calendar-col aligncanter">周五</view>
            <view class="calendar-col aligncanter">周六</view>
         </view>
         <view class="calendar-row calendar-day" v-bind:style="{'transform':transformObj, 'transition-duration':transformTimeObj}" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
            <view class="calendar-col aligncanter calendar-col-lastMonth" v-for='item in beforeDateList' v-bind:key='item.key'
             @tap="subMonth" v-bind:class="{'calendar-out-of-Date' : item.outOfDate }">{{item.dateIndex}}
               <text class='calendar-text'>{{item.markText}}</text>
            </view>
            <view class="calendar-col aligncanter currentDays" v-bind:class="{'calendar-active' : item.dateIndex == currentSelectTime
            , 'calendar-today' : item.isToday
            , 'calendar-range' : item.isRanges
            , 'calendar-out-of-Date' : item.outOfDate }"
             v-for='item in dateList' v-bind:key='item.key' @tap="selectedDateFun(item.dateIndex)">
               <view class='dayValue'>
                  <text class='calendar-date calendar-day-6-7' v-if="item.isDaySunOrSat">{{item.dateIndex}}</text>
                  <text v-else class='calendar-date'>{{item.dateIndex}}</text>
                  <text class='calendar-point' v-if="item.pointText" v-bind:style="{'color':item.pointTextColor?item.pointTextColor:maskColor}">{{item.pointText}}</text>
                  <text class='calendar-text' v-bind:style="{'color':item.markTextColor?item.markTextColor:maskColor}">{{item.markText}}</text>
               </view>
            </view>
            <view class="calendar-col aligncanter calendar-col-nextMonth" v-for='item in afterDateList' v-bind:key='item.key'
             @tap="addMonth" v-bind:class="{'calendar-out-of-Date' : item.outOfDate }">{{item.dateIndex}}
               <text class='calendar-text'>{{item.markText}}</text>
            </view>
         </view>
         <view class="ClearBoth"></view>
      </view>
   </view>
</template>
<script>
   import lunarYearTool from './sloarToLunar.js'
   import { getDay } from '@/utils/utils.js'
   export default {
      name: 'Li-Calendar',
      props: {
         /**
          * @description å½“前时间 yyyy-MM-dd
          */
         currentTime: {
            type: String,
            default: function() {
               let timeObj = new Date();
               return timeObj.getFullYear() + "-" + (timeObj.getMonth() + 1) + "-" + timeObj.getDate();
            }
         },
         /**
          * @description æ ‡è®°ç‚¹åˆ—表
          * time   æ ‡è®°æ—¶é—´   yyyy-MM-dd
          * text   æ ‡è®°å†…容
          * markPoint æ˜¯å¦æ˜¾ç¤ºæ ‡è®°ç‚¹ é»˜è®¤false
          * markTextColor æ ‡è®°å†…容颜色
          * pointText å·¦ä¸Šè§’标记点内容
          * pointTextColor æ ‡è®°ç‚¹é¢œè‰²
          */
         mark: {
            type: Array,
            default: function() {
               return undefined;
            }
         },
         /**
          * @description ä¸Šæœˆæ–‡å­—
          */
         lastText: {
            type: String,
            default: '〈'
         },
         /**
          * @description ä¸‹æœˆæ–‡å­—
          */
         nextText: {
            type: String,
            default: '〉'
         },
         /**
          * @description å…¨å±€æ ‡è®°ç‚¹é¢œè‰²ï¼ŒåŒ…括点和文字
          */
         maskColor: {
            type: String,
            default: '#01AAED'
         },
         /**
          * @description æ˜¯å¦æ˜¾ç¤ºå†œåŽ†ï¼Œmask优先级高
          */
         showLunar: {
            type: Boolean,
            default: true
         },
         /**
          * @description è®¾ç½®æ ‡è®°èŒƒå›´
          */
         range: {
            type: Object,
            default: function() {
               return {
                  rangeStart: undefined, //设置标记范围开始,yyyy-MM-dd
                  rangeEnd: undefined //设置标记范围结束,yyyy-MM-dd
               }
            }
         },
         /**
          * @description æ˜¯å¦å¼€å¯èŒƒå›´é€‰æ‹©æ¨¡å¼
          */
         rangeMode: {
            type: Boolean,
            default: false
         },
         /**
          * @description æ—¥åŽ†èµ·å§‹æ—¶é—´ yyyy-MM-dd
          */
         dateStart: {
            type: String,
            default: '1970-01-01'
         },
         /**
          * @description æ—¥åŽ†ç»“æŸæ—¶é—´ yyyy-MM-dd
          */
         dateEnd: {
            type: String,
            default: '2100-12-31'
         },
         /**
          * @description æ˜¯å¦å¯ä»¥æ»šåЍ
          */
         canDrag:{
            type: Boolean,
            default: true
         },
      },
      created() {
         this.render();
      },
      data() {
         return {
            nodisable: require('@/static/meeting/icon/ar_left@2x.png'),
            disable: require('@/static/meeting/icon/ar_left_disable.png'),
            nextDisabled: false,
            lastDisabled: true,
            currentSelectTime: undefined, //点击时保存的dateIndex
            title_time: '', //顶头文本
            year: undefined, //当前年
            month: undefined, //当前月
            beforeDateList: [], //上个月的日期列表
            dateList: [], //本月的日期列表
            afterDateList: [], //下个月的日期列表
            firstRangeSelected: false, // èŒƒå›´å¼€å§‹æ—¶é—´æ˜¯å¦å·²ç»é€‰æ‹©
            rangeStart_: undefined, //标记范围开始,yyyyMM-dd
            rangeEnd_: undefined, //标记范围结束,yyyyMM-dd
            transform_x:0,
            transform_time:0,
         };
      },
      methods: {
         render(setTimeStr) { //初始化
            let that = this;
            let currentTimeStr = setTimeStr ? setTimeStr : that.currentTime;
            let timeObj = this.toDateByStr(currentTimeStr); //当前选定的时间
            //计算头部显示的年月
            let _tempTileMonth = (timeObj.getMonth() + 1);
            if (_tempTileMonth < 10)
               _tempTileMonth = '0' + _tempTileMonth;
            this.title_time = timeObj.getFullYear() + "å¹´" + _tempTileMonth + "月";
            //获取当前时间月份1号
            let firstDayStr = timeObj.getFullYear() + "/" + (timeObj.getMonth() + 1) + "/01";
            let date = that.toDateByStr(firstDayStr);
            that.year = date.getFullYear();
            that.month = date.getMonth() + 1;
            let firstDayWeek = date.getDay(); //第一天是星期几
            let grid_sum = 0; //总格子数 ï¼Œç”¨äºŽåŽé¢å¡«æ»¡æ ¼å­
            //获取上一个月的天数
            let TempMonth;
            let TempYear;
            if (that.month == 1) { //跨年
               TempMonth = 12;
               TempYear = that.year - 1;
            } else {
               TempYear = that.year;
               TempMonth = that.month - 1;
            }
            let TempLastMonthStr = TempYear + "/" + TempMonth + "/01";
            let lastMonthTotalDay = that.getTotalDay(TempLastMonthStr);
            let lastMonthStartDay = lastMonthTotalDay - firstDayWeek;
            let _dateStart = that.toDateByStr1(that.dateStart);
            let _dateEnd = that.toDateByStr1(that.dateEnd);
            // åˆ›å»ºå‰é¢çš„æ—¥æœŸ
            that.beforeDateList = [];
            for (let i = 0; i < firstDayWeek; i++) {
               grid_sum++;
               lastMonthStartDay++;
               let tempObj = {
                  dateIndex: lastMonthStartDay,
                  key: 'before_' + i
               };
               //判断是否超出日期范围
               let _tempBeforeDate = new Date(TempYear + "/" + TempMonth + "/" + lastMonthStartDay);
               if (_dateStart > _tempBeforeDate || _tempBeforeDate > _dateEnd) {
                  tempObj.outOfDate = true;
               }
               //获取农历
               if (that.showLunar) {
                  let LunarDate = that.sloarToLunar(TempYear, TempMonth, lastMonthStartDay);
                  let tempLunarDay = LunarDate.lunarDay == '初一' ? LunarDate.lunarMonth + '月' : LunarDate.lunarDay;
                  tempObj.markText = tempLunarDay;
               }
               that.beforeDateList.push(tempObj);
            }
            //获取一个月的天数
            let totalDay = that.getTotalDay(currentTimeStr);
            //生成本月日历
            let today = new Date();
            let today_year = today.getFullYear();
            let today_month = today.getMonth() + 1;
            let today_day = today.getDate();
            that.dateList = [];
            for (let i = 1; i <= totalDay; i++) { //循环日
               grid_sum++;
               let tempObj = {
                  dateIndex: i,
                  key: 'date_' + i,
                  isRanges: false,
                  isToday: false
               };
               //当前日期变量
               let tempDay = that.toDateByStr(that.year + "/" + that.month + "/" + i);
               //判断是否为当天
               if (today_year == that.year && today_month == that.month && today_day == i)
                  tempObj.isToday = true;
               //周六和周日,特殊处理
               let tempCurrWeek = tempDay.getDay();
               if (tempCurrWeek == 0 || tempCurrWeek == 6)
                  tempObj.isDaySunOrSat = true;
               //判断是否超出日期范围
               if (_dateStart > tempDay || tempDay > _dateEnd) {
                  tempObj.outOfDate = true;
               }
               //获取农历
               if (that.showLunar) {
                  let LunarDate = that.sloarToLunar(that.year, that.month, i);
                  that.lunarMonth = LunarDate.lunarMonth;
                  that.lunarYear = LunarDate.lunarYear;
                  let tempLunarDay = LunarDate.lunarDay == '初一' ? LunarDate.lunarMonth + '月' : LunarDate.lunarDay;
                  tempObj.lunarMonth = LunarDate.lunarMonth;
                  tempObj.lunarYear = LunarDate.lunarYear;
                  tempObj.lunarDay = LunarDate.lunarDay;
                  tempObj.markText = tempLunarDay;
                  tempObj.markTextColor = '#454545';
               }
               //设置了标记点
               if (that.mark) {
                  for (let z = 0; z < that.mark.length; z++) { //判断是否为标记点
                     let tempDayMark = that.toDateByStr1(that.mark[z].time.trim())
                     if (tempDay.getTime() == tempDayMark.getTime()) {
                        let tempTextStr = that.mark[z].text
                        if (that.mark[z].markPoint != false) { // æ˜¯å¦æ˜¾ç¤ºç‚¹
                           tempObj.pointText = that.mark[z].pointText ? that.mark[z].pointText : '●';
                           tempObj.pointTextColor = that.mark[z].pointTextColor ? that.mark[z].pointTextColor : undefined;
                        }
                        if (tempTextStr != undefined && tempTextStr != "") { // æ˜¯å¦æ˜¾ç¤ºæ–‡å­—
                           tempObj.markText = tempTextStr;
                           tempObj.markTextColor = that.mark[z].markTextColor ? that.mark[z].markTextColor : undefined;
                        }
                        break;
                     }
                  }
               }
               that.dateList.push(tempObj);
            }
            that.setRange();
            // åˆ›å»ºåŽé¢çš„空白,补够五行
            that.afterDateList = [];
            if (grid_sum < 42) { // åˆ›å»ºåŽé¢çš„空白,补够五行
               let j = 0;
               //获取下一月
               let TempMonthNext;
               let TempYearNext;
               if (that.month == 12) { //跨年
                  TempMonthNext = 1;
                  TempYearNext = that.year + 1;
               } else {
                  TempYearNext = that.year;
                  TempMonthNext = that.month + 1;
               }
               for (let i = grid_sum; i < 42; i++) {
                  j++;
                  let tempObj = {
                     dateIndex: j,
                     key: 'after_' + j
                  };
                  //获取农历
                  if (that.showLunar) {
                     let LunarDate = that.sloarToLunar(TempYearNext, TempMonthNext, j);
                     let tempLunarDay = LunarDate.lunarDay == '初一' ? LunarDate.lunarMonth + '月' : LunarDate.lunarDay;
                     tempObj.markText = tempLunarDay;
                  }
                  //判断是否超出日期范围
                  let _tempAfterDate = new Date(TempYearNext + "/" + TempMonthNext + "/" + j);
                  if (_dateStart > _tempAfterDate || _tempAfterDate > _dateEnd) {
                     tempObj.outOfDate = true;
                  }
                  that.afterDateList.push(tempObj);
               }
            }
         },
         sloarToLunar(year,month,day){
            // console.log('----')
            // console.log(year + "--" +month+ "--" + day)
            let result = lunarYearTool.sloarToLunar(year,month,day);
            //console.log(result)
            return result;
         },
         getTotalDay(time) { //获取月 æ—¥æœŸæ€»æ•°
            time = time.replace(/-/g, "/");
            let selectedDate = new Date(time);
            if (selectedDate == "Invalid Date") {
               selectedDate = new Date(time + "/01");
            }
            let dayMany = new Date(selectedDate.getFullYear(),(selectedDate.getMonth() + 1), 0).getDate()
            return dayMany;
         },
         toDateByStr(timeStr) { //字符串转换时间,转换失败或者不传字符串则返回当前
            let timeObj;
            if (timeStr) {
               timeObj = new Date(timeStr.replace(/-/g, "/"));
            }
            if (!timeStr || timeObj == "Invalid Date")
               timeObj = new Date();
            return timeObj;
         },
         toDateByStr1(timeStr) { //字符串转换时间,转换失败或者不传字符串则null
            try {
               let timeObj;
               if (timeStr) {
                  timeObj = new Date(timeStr.replace(/-/g, "/"));
               }
               if (!timeStr || timeObj == "Invalid Date")
                  return null;
               return timeObj;
            } catch (e) {
               return null;
            }
         },
         getTimeStrFormat(timeStr) { //获取格式化的时间 yyyy-MM-dd
            let timeObj;
            if (timeStr) {
               timeObj = new Date(timeStr.replace(/-/g, "/"));
            }
            if (!timeStr || timeObj == "Invalid Date")
               timeObj = new Date();
            return timeObj.getFullYear() + "-" + (timeObj.getMonth() + 1) + "-" + timeObj.getDate();
         },
         selectedDateFun(index) { //点击日期
            let that = this;
            let selectObj = that.dateList[index - 1];
            selectObj.year = that.year;
            selectObj.month = that.month;
            selectObj.day = index;
            selectObj.time = that.year + "-" + that.month + "-" + index;
            that.$emit('dayChange', selectObj);
            //判断是否超出日期范围
            if (that.checkOutOfDate(selectObj.time)) {
               return;
            }
            that.currentSelectTime = index;
            console.log(index)
            //开启了范围选择模式
            if (that.rangeMode) {
               if (!that.firstRangeSelected) { //选择开始时间
                  that.firstRangeSelected = !that.firstRangeSelected
                  that.rangeStart_ = selectObj.time;
                  that.rangeEnd_ = undefined;
                  that.clearRange();
               } else { //选择了结束时间
                  that.rangeEnd_ = selectObj.time;
                  that.firstRangeSelected = !that.firstRangeSelected
                  that.$emit('rangeChange', {
                     start: that.rangeStart_,
                     end: that.rangeEnd_,
                  });
                  that.setRange();
               }
            }
         },
         addMonth() { //加一个月
            let that = this;
            that.currentSelectTime = ''
            let _Month = that.month;
            let _Year = that.year;
            if (that.month == 12) { //跨年
               _Month = 1;
               _Year += 1;
            } else {
               _Month += 1;
            }
            let str = _Year + "/" + _Month + "/01";
            //判断是否超出日期范围
            if (that.checkOutOfDate(str)) {
               that.nextDisabled = true;
               return;
            }
            that.month = _Month;
            that.year = _Year;
            that.lastDisabled = false;
            //检查日期上限值是否在当月内,如果在则不能再切换下个月
            if (that.checkDateRange(that.year, that.month, 1)) {
               that.nextDisabled = true;
            }
            if (that.rangeMode) { //开启了范围模式
               that.currentSelectTime = undefined;
            }
            that.$emit('monthChange', {
               date: str
            });
            that.render(str);
         },
         subMonth() { //减一个月
            let that = this;
            that.currentSelectTime = ''
            let _Month = that.month;
            let _Year = that.year;
            if (that.month == 1) { //跨年
               _Month = 12;
               _Year -= 1;
            } else {
               _Month -= 1;
            }
            let str = _Year + "/" + _Month + "/01";
            //判断是否超出日期范围
            let _totalDay = that.getTotalDay(str);
            if (that.checkOutOfDate(_Year + "/" + _Month + "/" + _totalDay)) {
               that.lastDisabled = true;
               return;
            }
            that.month = _Month;
            that.year = _Year;
            that.nextDisabled = false;
            //检查日期下限值是否在当月内,如果在则不能再切换上个月
            if (that.checkDateRange(that.year, that.month)) {
               that.lastDisabled = true;
            }
            if (that.rangeMode) { //开启了范围模式
               that.currentSelectTime = undefined;
            }
            that.$emit('monthChange', {
               date: str
            });
            that.render(str);
         },
         backToToday() { //回到今天
            let currDate = new Date();
            let _year = currDate.getFullYear();
            let _month = currDate.getMonth() + 1;
            this.currentSelectTime = getDay().day
            this.$emit('dayChange', { time: getDay().date });
            //如果已经是当月
            if (_year == this.year && _month == this.month) {
               return;
            }
            let value = _year + "/" + _month + "/" + currDate.getDate();
            this.$emit('monthChange', {
               date: value
            });
            this.lastDisabled = true
            this.render(value);
         },
         setRange() { //设置范围
            let that = this;
            let rangeStartDate = that.toDateByStr1(that.rangeStart_);
            let rangeEndDate = that.toDateByStr1(that.rangeEnd_);
            if (!rangeStartDate || !rangeEndDate)
               return;
            if (rangeStartDate > rangeEndDate) { //防止范围出错
               let tempD = rangeEndDate;
               rangeEndDate = rangeStartDate;
               rangeStartDate = tempD;
            }
            //循环判断范围
            for (let i = 0; i < that.dateList.length; i++) {
               let _TempDtStr = that.year + "/" + that.month + "/" + that.dateList[i].dateIndex;
               let _TempDt = that.toDateByStr1(_TempDtStr);
               that.dateList[i].isRanges = false;
               if (rangeStartDate <= _TempDt && _TempDt <= rangeEndDate) //时间在范围内
                  that.dateList[i].isRanges = true;
            }
         },
         clearRange() { //关闭范围模式范围
            let that = this;
            //循环判断范围
            for (let i = 0; i < that.dateList.length; i++) {
               that.dateList[i].isRanges = false;
            }
         },
         checkOutOfDate(time) { //判断是否超出日期范围,yyyy-MM-dd
            let that = this;
            let _dateStart = that.toDateByStr1(that.dateStart);
            let _dateEnd = that.toDateByStr1(that.dateEnd);
            let _tempDate = that.toDateByStr1(time);
            if (_dateStart > _tempDate || _tempDate > _dateEnd) {
               return true;
            } else
               return false;
         },
         checkDateRange(year, month, type) { //判断范围界限值是否在当月内,yyyy-MM-dd,type;1 ä¸Šé™å€¼,其他:下限值
            let that = this;
            let totalDay = that.getTotalDay(year + '/' + month + '/01');
            let firstD = that.toDateByStr1(year + '/' + month + '/01');
            let lastD = that.toDateByStr1(year + '/' + month + '/' + totalDay);
            if (type == 1) { //上限值
               let _dateEnd = that.toDateByStr1(that.dateEnd);
               if (firstD <= _dateEnd && _dateEnd <= lastD) {
                  return true;
               } else
                  return false;
            } else { //下限值
               let _dateStart = that.toDateByStr1(that.dateStart);
               if (firstD <= _dateStart && _dateStart <= lastD) {
                  return true;
               } else
                  return false;
            }
         },
         calendarTransform(x,time){  //日历滑动动画
            this.transform_x = x;
            this.transform_time = time;
         },
         touchstart(event) {
            if(!this.canDrag)
               return;
            this.startPageX = event.touches[0].pageX;
            this.startPageY = event.touches[0].pageY;
         },
         touchmove(event) {
            if(!this.canDrag)
               return;
            let touchmovePageX = event.touches[0].pageX;
            let result = touchmovePageX - this.startPageX;
            this.calendarTransform(result,0);
         },
         touchend(event) {
            if(!this.canDrag)
               return;
            let that = this;
            let endPageX = event.changedTouches[0].pageX;
            let endPageY = event.changedTouches[0].pageY;
            let x = Math.abs(that.startPageX - endPageX); //横坐标之差
            let y = Math.abs(that.startPageY - endPageY); //纵坐标之差
            let screenX = 0;
            try {
                const res = uni.getSystemInfoSync();
                screenX = res.windowWidth;
            } catch (e) {
               console.error(e)
               return;
            }
            if (that.startPageX > endPageX) { //左滑
               let a = Math.atan(y / x);
               let Rate = x / screenX;
               if (a < Math.PI / 6 && Rate > 0.3) {
                  screenX = -screenX;
                  that.calendarTransform(screenX,300);
                  setTimeout(function(){
                     that.addMonth();
                     that.calendarTransform(0,0);
                  },300);
               }
               else{
                  that.calendarTransform(0,300);
               }
            } else {
               let a = Math.atan(y / x);
               let Rate = x / screenX;
               if (a < Math.PI / 6 && Rate > 0.3) {
                  that.calendarTransform(screenX,300);
                  setTimeout(function(){
                     that.subMonth();
                     that.calendarTransform(0,0);
                  },300);
               }
               else{
                  that.calendarTransform(0,300);
               }
            }
         }
      },
      watch: {
         currentTime: function(val, oldVal) { //时间改变
            let dateNew = this.toDateByStr1(val);
            if (dateNew.getFullYear() == this.year && (dateNew.getMonth() + 1) == this.month) {
               console.log('time is not change')
            } else {
               this.currentSelectTime = dateNew.getDate();
               this.render();
            }
         },
         range: function(val, oldVal) { //范围改变
            if (val.rangeStart != oldVal.rangeStart || val.rangeEnd != oldVal.rangeEnd) {
               this.rangeStart_ = val.rangeStart;
               this.rangeEnd_ = val.rangeEnd;
               this.setRange();
            }
         },
         mark: function(val, oldVal) { //标记改变
            this.render();
         },
         rangeMode: function(val, oldVal) { //范围改变
            if (!val) { //如果是关闭范围模式
               this.rangeStart_ = undefined; //标记范围开始,yyyyMM-dd
               this.rangeEnd_ = undefined; //标记范围结束,yyyyMM-dd
               this.firstRangeSelected = false;
               this.clearRange()
            }
         },
      },
      computed: {
         transformObj:function () {
            return 'translate3d(' + this.transform_x + 'px, 0px, 0px) translateZ(0px)';
         },
         transformTimeObj:function () {
            return this.transform_time + 'ms';
         }
      },
   }
</script>
<style>
   @import url("./Li-Calendar.css");
</style>