浏览代码

feat: 日历组件新增 周选择功能 (#2102)

Co-authored-by: lkjh3214 <13121007159@163.com>
lkjh3214 2 年之前
父节点
当前提交
34294f9c3b

+ 33 - 2
src/packages/__VUE/calendar/demo.vue

@@ -60,7 +60,27 @@
       >
       </nut-calendar>
     </div>
-
+    <div>
+      <nut-cell
+        :show-icon="true"
+        :title="translate('week')"
+        :desc="date9 ? `${date9[0]}${translate('conjunction')}${date9[1]}` : translate('please')"
+        @click="openSwitch('isVisible9')"
+      >
+      </nut-cell>
+      <nut-calendar
+        v-model:visible="isVisible9"
+        :default-value="date9"
+        type="week"
+        :start-date="`2019-12-22`"
+        :end-date="`2021-01-08`"
+        @close="closeSwitch('isVisible9')"
+        @choose="setChooseValue9"
+        @select="select"
+        :first-day-of-week="1"
+      >
+      </nut-calendar>
+    </div>
     <h2>{{ translate('title1') }}</h2>
     <div>
       <nut-cell
@@ -219,6 +239,7 @@ const initTranslate = () =>
       single: '选择单个日期',
       range: '选择日期区间',
       multiple: '选择多个日期',
+      week: '选择周',
 
       conjunction: '至',
       custom_btn: '自定义按钮',
@@ -243,6 +264,7 @@ const initTranslate = () =>
       single: 'Select Single Date',
       range: 'Select Date Range',
       multiple: 'Select Multiple Date',
+      week: 'Select Week',
 
       conjunction: '-',
       custom_btn: 'Custom Button',
@@ -270,6 +292,7 @@ interface TestCalendarState extends TestCalendarStateVisible {
   date6: string[];
   date7: string[];
   date8: string;
+  date9: string[];
 }
 interface TestCalendarStateVisible {
   isVisible: boolean;
@@ -281,6 +304,7 @@ interface TestCalendarStateVisible {
   isVisible6: boolean;
   isVisible7: boolean;
   isVisible8: boolean;
+  isVisible9: boolean;
 }
 export default createDemo({
   props: {},
@@ -299,6 +323,7 @@ export default createDemo({
       date6: [],
       date7: [],
       date8: '',
+      date9: ['2020-01-23', '2020-01-26'],
       isVisible1: false,
       isVisible2: false,
       isVisible3: false,
@@ -306,7 +331,8 @@ export default createDemo({
       isVisible5: false,
       isVisible6: false,
       isVisible7: false,
-      isVisible8: false
+      isVisible8: false,
+      isVisible9: false
     });
     const openSwitch = (param: keyof TestCalendarStateVisible) => {
       state[`${param}`] = true;
@@ -356,6 +382,10 @@ export default createDemo({
     const setChooseValue8 = (param: string) => {
       state.date8 = param[3];
     };
+    const setChooseValue9 = (param: any) => {
+      let { weekDate } = param;
+      state.date9 = [weekDate[0].date[3], weekDate[1].date[3]];
+    };
     const clickBtn = () => {
       let date = [Utils.date2Str(new Date()), Utils.getDay(6)];
       state.date5 = date;
@@ -392,6 +422,7 @@ export default createDemo({
       setChooseValue5,
       setChooseValue6,
       setChooseValue8,
+      setChooseValue9,
       clickBtn,
       clickBtn1,
       goDate,

+ 63 - 1
src/packages/__VUE/calendar/doc.en-US.md

@@ -184,7 +184,69 @@ export default {
 </script>
 ```
 :::
+### Select Week
+When set to week selection, the start and end dates of the week will be determined according to `first-day-of-week`. For example, when `first-day-of-week` is 0, the start date of a week is Sunday. In other cases, the start date of the week is Monday.
+:::demo
+```html
+<template>
+  <nut-cell
+    :showIcon="true"
+    title="Select Week"
+    :desc="date && date[0] ? `${date[0]}-${date[1]}` : 'Please Select Date'"
+    @click="openSwitch('isVisible')"
+  >
+  </nut-cell>
+  <nut-calendar
+    v-model:visible="isVisible"
+    :default-value="date"
+    type="week"
+    :start-date="`2019-12-22`"
+    :end-date="`2021-01-08`"
+    @close="closeSwitch('isVisible')"
+    @choose="setChooseValue"
+    @select="select"
+  >
+  </nut-calendar>
+</template>
+<script lang="ts">
+import { reactive, toRefs } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      date: ['2019-12-23', '2019-12-26'],
+      isVisible: false
+    });
+    const openSwitch = param => {
+      state[`${param}`] = true;
+    };
+    const closeSwitch = param => {
+      state[`${param}`] = false;
+    };
+    const setChooseValue= param => {
+      let { weekDate } = param;
+      state.date = [weekDate[0].date[3], weekDate[1].date[3]];
 
+    };
+    const select = (param: string) => {
+      console.log(param);
+    };
+    return {
+      ...toRefs(state),
+      openSwitch,
+      closeSwitch,
+      setChooseValue,
+      select,
+    };
+  }  
+};
+</script>
+<style lang="scss">
+.nut-cell__value {
+  flex: initial;
+}
+</style>
+```
+:::
 ### Quick Select Single Date
 :::demo
 ```html
@@ -609,7 +671,7 @@ export default {
 | Attribute              | Description                                  | Type            | Default  |
 |-------------------|---------------------------------------------------|-----------------|-----------------|
 | v-model:visible   | whether to show                  | boolean         | `false`           |
-| type              | Calendar type :`one` `range` `multiple`    | string          | `one`           |
+| type              | Calendar type :`one` `range` `multiple` `week(V4.0.1)`     | string          | `one`           |
 | poppable          | Whether to display the pop-up window                                  | boolean         | `true`            |
 | is-auto-back-fill | Automatic backfill                                          | boolean         | `false`           |
 | title             | whether to show title                                          | string          | `Calendar`      |

+ 65 - 1
src/packages/__VUE/calendar/doc.md

@@ -184,6 +184,70 @@ export default {
 </script>
 ```
 :::
+
+### 选择周
+当设置为周选择时,会根据`first-day-of-week` 判断周的起始与结束日期。如`first-day-of-week`为0时,一周的起始日期为星期日。其他情况时,一周的起始日期为星期一。
+:::demo
+```html
+<template>
+  <nut-cell
+    :showIcon="true"
+    title="选择周"
+    :desc="date && date[0] ? `${date[0]}至${date[1]}` : '请选择'"
+    @click="openSwitch('isVisible')"
+  >
+  </nut-cell>
+  <nut-calendar
+    v-model:visible="isVisible"
+    :default-value="date"
+    type="week"
+    :start-date="`2019-12-22`"
+    :end-date="`2021-01-08`"
+    @close="closeSwitch('isVisible')"
+    @choose="setChooseValue"
+    @select="select"
+  >
+  </nut-calendar>
+</template>
+<script lang="ts">
+import { reactive, toRefs } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      date: ['2019-12-23', '2019-12-26'],
+      isVisible: false
+    });
+    const openSwitch = param => {
+      state[`${param}`] = true;
+    };
+    const closeSwitch = param => {
+      state[`${param}`] = false;
+    };
+    const setChooseValue= param => {
+      let { weekDate } = param;
+      state.date = [weekDate[0].date[3], weekDate[1].date[3]];
+
+    };
+    const select = (param: string) => {
+      console.log(param);
+    };
+    return {
+      ...toRefs(state),
+      openSwitch,
+      closeSwitch,
+      setChooseValue,
+      select,
+    };
+  }  
+};
+</script>
+<style lang="scss">
+.nut-cell__value {
+  flex: initial;
+}
+</style>
+```
+:::
 ### 快捷选择-单选
 :::demo
 ```html
@@ -624,7 +688,7 @@ export default {
 | 参数              | 说明                                              | 类型            | 默认值          |
 |-------------------|---------------------------------------------------|-----------------|-----------------|
 | v-model:visible   | 是否可见                                          | boolean         | `false`           |
-| type              | 类型,日期单择`one`,区间选择`range`,日期多选`multiple`    | string       | '`one`'           |
+| type              | 类型,日期单择`one`,区间选择`range`,日期多选`multiple`,周选择`week`(`v4.0.1`)     | string       | '`one`'           |
 | poppable          | 是否弹窗状态展示                                  | boolean         | `true`            |
 | is-auto-back-fill | 自动回填                                          | boolean         | `false`           |
 | title             | 显示标题                                          | string          | `日期选择`      |

+ 66 - 1
src/packages/__VUE/calendar/doc.taro.md

@@ -184,6 +184,71 @@ export default {
 </script>
 ```
 :::
+
+### 选择周
+当设置为周选择时,会根据`first-day-of-week` 判断周的起始与结束日期。如`first-day-of-week`为0时,一周的起始日期为星期日。其他情况时,一周的起始日期为星期一。
+
+:::demo
+```html
+<template>
+  <nut-cell
+    :showIcon="true"
+    title="选择周"
+    :desc="date && date[0] ? `${date[0]}至${date[1]}` : '请选择'"
+    @click="openSwitch('isVisible')"
+  >
+  </nut-cell>
+  <nut-calendar
+    v-model:visible="isVisible"
+    :default-value="date"
+    type="week"
+    :start-date="`2019-12-22`"
+    :end-date="`2021-01-08`"
+    @close="closeSwitch('isVisible')"
+    @choose="setChooseValue"
+    @select="select"
+  >
+  </nut-calendar>
+</template>
+<script lang="ts">
+import { reactive, toRefs } from 'vue';
+export default {
+  setup() {
+    const state = reactive({
+      date: ['2019-12-23', '2019-12-26'],
+      isVisible: false
+    });
+    const openSwitch = param => {
+      state[`${param}`] = true;
+    };
+    const closeSwitch = param => {
+      state[`${param}`] = false;
+    };
+    const setChooseValue= param => {
+      let { weekDate } = param;
+      state.date = [weekDate[0].date[3], weekDate[1].date[3]];
+
+    };
+    const select = (param: string) => {
+      console.log(param);
+    };
+    return {
+      ...toRefs(state),
+      openSwitch,
+      closeSwitch,
+      setChooseValue,
+      select,
+    };
+  }  
+};
+</script>
+<style lang="scss">
+.nut-cell__value {
+  flex: initial;
+}
+</style>
+```
+:::
 ### 快捷选择-单选
 :::demo
 ```html
@@ -614,7 +679,7 @@ export default {
 | 参数              | 说明                                              | 类型            | 默认值          |
 |-------------------|---------------------------------------------------|-----------------|-----------------|
 | v-model:visible   | 是否可见                                          | boolean         | `false`           |
-| type              | 类型,日期单择`one`,区间选择`range`,日期多选`multiple`    | string       | '`one`'           |
+| type   `v4.0.1`           | 类型,日期单择`one`,区间选择`range`,日期多选`multiple`,周选择`week`(`v4.0.1`)     | string       | '`one`'           |
 | poppable          | 是否弹窗状态展示                                  | boolean         | `true`            |
 | is-auto-back-fill | 自动回填                                          | boolean         | `false`           |
 | title             | 显示标题                                          | string          | `日期选择`      |

+ 62 - 46
src/packages/__VUE/calendaritem/index.taro.vue

@@ -236,7 +236,7 @@ export default create({
       if (day.type == 'curr') {
         if (
           Utils.isEqual(state.currDate as string, currDate) ||
-          (type == 'range' && (isStart(currDate) || isEnd(currDate))) ||
+          ((type == 'range' || type == 'week') && (isStart(currDate) || isEnd(currDate))) ||
           (type == 'multiple' && isMultiple(currDate))
         ) {
           return `${state.dayPrefix}--active`;
@@ -246,7 +246,7 @@ export default create({
         ) {
           return `${state.dayPrefix}--disabled`;
         } else if (
-          type == 'range' &&
+          (type == 'range' || type == 'week') &&
           Array.isArray(state.currDate) &&
           Object.values(state.currDate).length == 2 &&
           Utils.compareDate(state.currDate[0], currDate) &&
@@ -264,8 +264,15 @@ export default create({
     const confirm = () => {
       const { type } = props;
       if ((type == 'range' && state.chooseData.length == 2) || type != 'range') {
-        let chooseData = state.chooseData.slice(0);
-        emit('choose', chooseData);
+        // let chooseData = state.chooseData.slice(0);
+        // emit('choose', chooseData);
+        let selectData: any = state.chooseData.slice(0);
+        if (type == 'week') {
+          selectData = {
+            weekDate: [handleWeekDate(state.chooseData[0] as string[]), handleWeekDate(state.chooseData[1] as string[])]
+          };
+        }
+        emit('choose', selectData);
         if (props.poppable) {
           emit('update');
         }
@@ -276,6 +283,7 @@ export default create({
     const chooseDay = (day: Day, month: MonthInfo, isFirst = false) => {
       if (getClass(day, month) != `${state.dayPrefix}--disabled`) {
         const { type } = props;
+        let [y, m] = month.curData;
         let days = [...month.curData];
         days[2] = Utils.getNumTwoBit(Number(day.day));
         days[3] = `${days[0]}-${days[1]}-${days[2]}`;
@@ -324,21 +332,48 @@ export default create({
               state.chooseData = [[...days], ...state.chooseData];
             }
           }
+        } else if (type == 'week') {
+          let weekArr = Utils.getWeekDate(y, m, day.day, props.firstDayOfWeek);
+          if (state.propStartDate && Utils.compareDate(weekArr[0], state.propStartDate)) {
+            weekArr.splice(0, 1, state.propStartDate);
+          }
+          if (state.propEndDate && Utils.compareDate(state.propEndDate, weekArr[1])) {
+            weekArr.splice(1, 1, state.propEndDate);
+          }
+          state.currDate = weekArr;
+          state.chooseData = [Utils.formatResultDate(weekArr[0]), Utils.formatResultDate(weekArr[1])];
         } else {
           state.currDate = days[3];
           state.chooseData = [...days];
         }
 
         if (!isFirst) {
+          let selectData: any = state.chooseData;
+          if (type == 'week') {
+            selectData = {
+              weekDate: [
+                handleWeekDate(state.chooseData[0] as string[]),
+                handleWeekDate(state.chooseData[1] as string[])
+              ]
+            };
+          }
           // 点击日期 触发
-          emit('select', state.chooseData);
+          emit('select', selectData);
           if (props.isAutoBackFill || !props.poppable) {
             confirm();
           }
         }
       }
     };
-
+    const handleWeekDate = (weekDate: string[]) => {
+      let [y, m, d] = weekDate;
+      let obj = {
+        date: weekDate,
+        monthWeekNum: Utils.getMonthWeek(y, m, d, props.firstDayOfWeek),
+        yearWeekNum: Utils.getYearWeek(y, m, d, props.firstDayOfWeek)
+      };
+      return obj;
+    };
     // 获取当前月数据
     const getCurrData = (type: string) => {
       const monthData = type == 'prev' ? state.monthsData[0] : state.monthsData[state.monthsData.length - 1];
@@ -549,6 +584,19 @@ export default create({
           state.currDate = [...defaultArr];
           state.defaultData = [...splitDate(defaultArr[0])];
         }
+      } else if (props.type == 'week' && Array.isArray(state.currDate)) {
+        if (state.currDate.length > 0) {
+          let [y, m, d] = splitDate(state.currDate[0]);
+          let weekArr = Utils.getWeekDate(y, m, d, props.firstDayOfWeek);
+          state.currDate = weekArr;
+          if (propStartDate && Utils.compareDate(state.currDate[0], propStartDate)) {
+            state.currDate.splice(0, 1, propStartDate);
+          }
+          if (propEndDate && Utils.compareDate(propEndDate, state.currDate[1])) {
+            state.currDate.splice(1, 1, propEndDate);
+          }
+          state.defaultData = [...splitDate(state.currDate[0]), ...splitDate(state.currDate[1])];
+        }
       } else {
         if (state.currDate) {
           if (propStartDate && Utils.compareDate(state.currDate as string, propStartDate)) {
@@ -568,7 +616,7 @@ export default create({
           if (item.title == translate('monthTitle', state.defaultData[0], state.defaultData[1])) {
             current = index;
           }
-          if (props.type == 'range') {
+          if (props.type == 'range' || props.type == 'week') {
             if (item.title == translate('monthTitle', state.defaultData[3], state.defaultData[4])) {
               lastCurrent = index;
             }
@@ -583,6 +631,8 @@ export default create({
         if (state.isRange) {
           chooseDay({ day: state.defaultData[2], type: 'curr' }, state.monthsData[state.currentIndex], true);
           chooseDay({ day: state.defaultData[5], type: 'curr' }, state.monthsData[lastCurrent], true);
+        } else if (props.type == 'week') {
+          chooseDay({ day: state.defaultData[2], type: 'curr' }, state.monthsData[state.currentIndex], true);
         } else if (props.type == 'multiple') {
           [...state.currDate].forEach((item: string) => {
             let dateArr = splitDate(item);
@@ -630,44 +680,6 @@ export default create({
               }, 200);
             }, 10);
           });
-          // if (Taro.getEnv() == 'ALIPAY') {
-          //   state.scrollTop = state.monthsData[index].cssScrollHeight;
-          // } else {
-          //   if (selectorQuery) {
-          //     selectorQuery
-          //       .select('.nut-calendar-content')
-          //       .scrollOffset((res) => {
-          //         if (props.toDateAnimation) {
-          //           let scrollTop = res.scrollTop;
-          //           let distance = state.monthsData[index].cssScrollHeight - scrollTop;
-          //           // state.scrollTop = res.scrollTop;
-          //           let flag = 0;
-          //           let interval = setInterval(() => {
-          //             flag++;
-          //             if (months.value) {
-          //               let offset = distance / 10;
-          //               state.scrollTop = state.scrollTop + offset;
-          //             }
-          //             if (flag >= 10) {
-          //               clearInterval(interval);
-          //               if (months.value) {
-          //                 state.scrollTop = state.monthsData[index].cssScrollHeight;
-          //               }
-          //             }
-          //           }, 40);
-          //         } else {
-          //           state.scrollTop = res.scrollTop;
-          //           setDefaultRange(state.monthsNum, index);
-          //           requestAniFrame(() => {
-          //             state.scrollTop = state.monthsData[index].cssScrollHeight;
-          //           });
-          //         }
-          //       })
-          //       .exec();
-          //   } else {
-          //     state.scrollTop = state.monthsData[index].cssScrollHeight;
-          //   }
-          // }
         }
       });
     };
@@ -701,7 +713,11 @@ export default create({
     };
     // 区间选择&&当前月&&选中态
     const isActive = (day: Day, month: MonthInfo) => {
-      return props.type == 'range' && day.type == 'curr' && getClass(day, month) == 'nut-calendar__day--active';
+      return (
+        (props.type == 'range' || props.type == 'week') &&
+        day.type == 'curr' &&
+        getClass(day, month) == 'nut-calendar__day--active'
+      );
     };
 
     // 是否有开始提示

+ 60 - 9
src/packages/__VUE/calendaritem/index.vue

@@ -233,7 +233,7 @@ export default create({
       if (day.type == 'curr') {
         if (
           Utils.isEqual(state.currDate as string, currDate) ||
-          (type == 'range' && (isStart(currDate) || isEnd(currDate))) ||
+          ((type == 'range' || type == 'week') && (isStart(currDate) || isEnd(currDate))) ||
           (type == 'multiple' && isMultiple(currDate))
         ) {
           return `${state.dayPrefix}--active`;
@@ -243,7 +243,7 @@ export default create({
         ) {
           return `${state.dayPrefix}--disabled`;
         } else if (
-          type == 'range' &&
+          (type == 'range' || type == 'week') &&
           Array.isArray(state.currDate) &&
           Object.values(state.currDate).length == 2 &&
           Utils.compareDate(state.currDate[0], currDate) &&
@@ -261,8 +261,13 @@ export default create({
     const confirm = () => {
       const { type } = props;
       if ((type == 'range' && state.chooseData.length == 2) || type != 'range') {
-        let chooseData = state.chooseData.slice(0);
-        emit('choose', chooseData);
+        let selectData: any = state.chooseData.slice(0);
+        if (type == 'week') {
+          selectData = {
+            weekDate: [handleWeekDate(state.chooseData[0] as string[]), handleWeekDate(state.chooseData[1] as string[])]
+          };
+        }
+        emit('choose', selectData);
         if (props.poppable) {
           emit('update');
         }
@@ -274,6 +279,7 @@ export default create({
       if (getClass(day, month) != `${state.dayPrefix}--disabled`) {
         const { type } = props;
         let days = [...month.curData];
+        let [y, m] = month.curData;
         days[2] = Utils.getNumTwoBit(Number(day.day));
         days[3] = `${days[0]}-${days[1]}-${days[2]}`;
         days[4] = Utils.getWhatDay(+days[0], +days[1], +days[2]);
@@ -311,7 +317,6 @@ export default create({
               Array.isArray(state.currDate) && state.currDate.unshift(days[3]);
             }
           }
-
           if (state.chooseData.length == 2 || !state.chooseData.length) {
             state.chooseData = [[...days]];
           } else {
@@ -321,20 +326,47 @@ export default create({
               state.chooseData = [[...days], ...state.chooseData];
             }
           }
+        } else if (type == 'week') {
+          let weekArr = Utils.getWeekDate(y, m, day.day, props.firstDayOfWeek);
+          if (state.propStartDate && Utils.compareDate(weekArr[0], state.propStartDate)) {
+            weekArr.splice(0, 1, state.propStartDate);
+          }
+          if (state.propEndDate && Utils.compareDate(state.propEndDate, weekArr[1])) {
+            weekArr.splice(1, 1, state.propEndDate);
+          }
+          state.currDate = weekArr;
+          state.chooseData = [Utils.formatResultDate(weekArr[0]), Utils.formatResultDate(weekArr[1])];
         } else {
           state.currDate = days[3];
           state.chooseData = [...days];
         }
         if (!isFirst) {
+          let selectData: any = state.chooseData;
+          if (type == 'week') {
+            selectData = {
+              weekDate: [
+                handleWeekDate(state.chooseData[0] as string[]),
+                handleWeekDate(state.chooseData[1] as string[])
+              ]
+            };
+          }
           // 点击日期 触发
-          emit('select', state.chooseData);
+          emit('select', selectData);
           if (props.isAutoBackFill || !props.poppable) {
             confirm();
           }
         }
       }
     };
-
+    const handleWeekDate = (weekDate: string[]) => {
+      let [y, m, d] = weekDate;
+      let obj = {
+        date: weekDate,
+        monthWeekNum: Utils.getMonthWeek(y, m, d, props.firstDayOfWeek),
+        yearWeekNum: Utils.getYearWeek(y, m, d, props.firstDayOfWeek)
+      };
+      return obj;
+    };
     // 获取当前月数据
     const getCurrData = (type: string) => {
       const monthData = type == 'prev' ? state.monthsData[0] : state.monthsData[state.monthsData.length - 1];
@@ -529,6 +561,19 @@ export default create({
           state.currDate = [...defaultArr];
           state.defaultData = [...splitDate(defaultArr[0])];
         }
+      } else if (props.type == 'week' && Array.isArray(state.currDate)) {
+        if (state.currDate.length > 0) {
+          let [y, m, d] = splitDate(state.currDate[0]);
+          let weekArr = Utils.getWeekDate(y, m, d, props.firstDayOfWeek);
+          state.currDate = weekArr;
+          if (propStartDate && Utils.compareDate(state.currDate[0], propStartDate)) {
+            state.currDate.splice(0, 1, propStartDate);
+          }
+          if (propEndDate && Utils.compareDate(propEndDate, state.currDate[1])) {
+            state.currDate.splice(1, 1, propEndDate);
+          }
+          state.defaultData = [...splitDate(state.currDate[0]), ...splitDate(state.currDate[1])];
+        }
       } else {
         if (state.currDate) {
           if (propStartDate && Utils.compareDate(state.currDate as string, propStartDate)) {
@@ -547,7 +592,7 @@ export default create({
           if (item.title == translate('monthTitle', state.defaultData[0], state.defaultData[1])) {
             current = index;
           }
-          if (props.type == 'range') {
+          if (props.type == 'range' || props.type == 'week') {
             if (item.title == translate('monthTitle', state.defaultData[3], state.defaultData[4])) {
               lastCurrent = index;
             }
@@ -562,6 +607,8 @@ export default create({
         if (props.type == 'range') {
           chooseDay({ day: state.defaultData[2], type: 'curr' }, state.monthsData[state.currentIndex], true);
           chooseDay({ day: state.defaultData[5], type: 'curr' }, state.monthsData[lastCurrent], true);
+        } else if (props.type == 'week') {
+          chooseDay({ day: state.defaultData[2], type: 'curr' }, state.monthsData[state.currentIndex], true);
         } else if (props.type == 'multiple') {
           [...state.currDate].forEach((item: string) => {
             let dateArr = splitDate(item);
@@ -651,7 +698,11 @@ export default create({
     };
     // 区间选择&&当前月&&选中态
     const isActive = (day: Day, month: MonthInfo) => {
-      return props.type == 'range' && day.type == 'curr' && getClass(day, month) == 'nut-calendar__day--active';
+      return (
+        (props.type == 'range' || props.type == 'week') &&
+        day.type == 'curr' &&
+        getClass(day, month) == 'nut-calendar__day--active'
+      );
     };
 
     // 是否有开始提示

+ 64 - 33
src/packages/utils/date.ts

@@ -3,7 +3,7 @@ const Utils = {
    * 是否为闫年
    * @return {Boolse} true|false
    */
-  isLeapYear: function(y: number): boolean {
+  isLeapYear: function (y: number): boolean {
     return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
   },
 
@@ -11,18 +11,10 @@ const Utils = {
    * 返回星期数
    * @return {String}
    */
-  getWhatDay: function(year: number, month: number, day: number): string {
+  getWhatDay: function (year: number, month: number, day: number): string {
     const date = new Date(year + '/' + month + '/' + day);
     const index = date.getDay();
-    const dayNames = [
-      '星期日',
-      '星期一',
-      '星期二',
-      '星期三',
-      '星期四',
-      '星期五',
-      '星期六'
-    ];
+    const dayNames = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
     return dayNames[index];
   },
 
@@ -30,7 +22,7 @@ const Utils = {
    * 返回星期数
    * @return {Number}
    */
-  getMonthPreDay: function(year: number, month: number): number {
+  getMonthPreDay: function (year: number, month: number): number {
     const date = new Date(year + '/' + month + '/01');
     let day = date.getDay();
     if (day == 0) {
@@ -43,32 +35,20 @@ const Utils = {
    * 返回月份天数
    * @return {Number}
    */
-  getMonthDays: function(year: string, month: string): number {
+  getMonthDays: function (year: string, month: string): number {
     if (/^0/.test(month)) {
       month = month.split('')[1];
     }
-    return ([
-      0,
-      31,
-      this.isLeapYear(Number(year)) ? 29 : 28,
-      31,
-      30,
-      31,
-      30,
-      31,
-      31,
-      30,
-      31,
-      30,
-      31
-    ] as number[])[month as any];
+    return ([0, 31, this.isLeapYear(Number(year)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] as number[])[
+      month as any
+    ];
   },
 
   /**
    * 补齐数字位数
    * @return {string}
    */
-  getNumTwoBit: function(n: number): string {
+  getNumTwoBit: function (n: number): string {
     n = Number(n);
     return (n > 9 ? '' : '0') + n;
   },
@@ -77,7 +57,7 @@ const Utils = {
    * 日期对象转成字符串
    * @return {string}
    */
-  date2Str: function(date: Date, split?: string): string {
+  date2Str: function (date: Date, split?: string): string {
     split = split || '-';
     const y = date.getFullYear();
     const m = this.getNumTwoBit(date.getMonth() + 1);
@@ -90,7 +70,7 @@ const Utils = {
    * @param {Number} 0返回今天的日期、1返回明天的日期,2返回后天得日期,依次类推
    * @return {string} '2014-12-31'
    */
-  getDay: function(i: number): string {
+  getDay: function (i: number): string {
     i = i || 0;
     let date = new Date();
     const diff = i * (1000 * 60 * 60 * 24);
@@ -102,7 +82,7 @@ const Utils = {
    * 时间比较
    * @return {Boolean}
    */
-  compareDate: function(date1: string, date2: string): boolean {
+  compareDate: function (date1: string, date2: string): boolean {
     const startTime = new Date(date1.replace('-', '/').replace('-', '/'));
     const endTime = new Date(date2.replace('-', '/').replace('-', '/'));
     if (startTime >= endTime) {
@@ -115,13 +95,64 @@ const Utils = {
    * 时间是否相等
    * @return {Boolean}
    */
-  isEqual: function(date1: string, date2: string): boolean {
+  isEqual: function (date1: string, date2: string): boolean {
     const startTime = new Date(date1).getTime();
     const endTime = new Date(date2).getTime();
     if (startTime == endTime) {
       return true;
     }
     return false;
+  },
+  getMonthWeek: function (year: string, month: string, date: string, firstDayOfWeek: number = 0): number {
+    const dateNow = new Date(Number(year), parseInt(month) - 1, Number(date));
+    let w = dateNow.getDay(); //星期数
+    let d = dateNow.getDate();
+    let remainder = 6 - w;
+    if (firstDayOfWeek !== 0) {
+      w = w == 0 ? 7 : w;
+      remainder = 7 - w;
+    }
+    return Math.ceil((d + remainder) / 7);
+  },
+  getYearWeek: function (year: string, month: string, date: string, firstDayOfWeek: number = 0): number {
+    const dateNow = new Date(Number(year), parseInt(month) - 1, Number(date));
+    const dateFirst = new Date(Number(year), 0, 1);
+    const dataNumber = Math.round((dateNow.valueOf() - dateFirst.valueOf()) / 86400000);
+    return Math.ceil((dataNumber + (dateFirst.getDay() + 1 - 1)) / 7);
+  },
+  getWeekDate: function (year: string, month: string, date: string, firstDayOfWeek: number = 0): string[] {
+    const dateNow = new Date(Number(year), parseInt(month) - 1, Number(date));
+    const nowTime = dateNow.getTime();
+    let day = dateNow.getDay();
+    if (firstDayOfWeek === 0) {
+      const oneDayTime = 24 * 60 * 60 * 1000;
+      //显示周日
+      const SundayTime = nowTime - day * oneDayTime; //本周的周日
+      //显示周六
+      const SaturdayTime = nowTime + (6 - day) * oneDayTime; //本周的周六
+
+      const sunday = this.date2Str(new Date(SundayTime));
+      const saturday = this.date2Str(new Date(SaturdayTime));
+      return [sunday, saturday];
+    } else {
+      day = day == 0 ? 7 : day;
+      const oneDayTime = 24 * 60 * 60 * 1000;
+      //显示周一
+      const MondayTime = nowTime - (day - 1) * oneDayTime; //本周的周一
+      //显示周日
+      const SundayTime = nowTime + (7 - day) * oneDayTime; //本周的周日
+
+      const monday = this.date2Str(new Date(MondayTime));
+      const sunday = this.date2Str(new Date(SundayTime));
+      return [monday, sunday];
+    }
+  },
+  formatResultDate: function (date: string) {
+    let days = [...date.split('-')];
+    days[2] = Utils.getNumTwoBit(Number(days[2]));
+    days[3] = `${days[0]}-${days[1]}-${days[2]}`;
+    days[4] = Utils.getWhatDay(+days[0], +days[1], +days[2]);
+    return days;
   }
 };
 

+ 31 - 4
src/sites/mobile-taro/vue/src/dentry/pages/calendar/index.vue

@@ -61,7 +61,27 @@
       >
       </nut-calendar>
     </div>
-
+    <div>
+      <nut-cell
+        :show-icon="true"
+        title="周选择"
+        :desc="date9 ? `${date9[0]}${'至'}${date9[1]}` : '请选择'"
+        @click="openSwitch('isVisible9')"
+      >
+      </nut-cell>
+      <nut-calendar
+        v-model:visible="isVisible9"
+        :default-value="date9"
+        type="week"
+        :start-date="`2019-12-22`"
+        :end-date="`2021-01-08`"
+        @close="closeSwitch('isVisible9')"
+        @choose="setChooseValue9"
+        @select="select"
+        :first-day-of-week="1"
+      >
+      </nut-calendar>
+    </div>
     <h2>快捷选择</h2>
     <div>
       <nut-cell
@@ -76,8 +96,6 @@
         @close="closeSwitch('isVisible3')"
         @choose="setChooseValue3"
         :default-value="date3"
-        :start-date="null"
-        :end-date="null"
         :is-auto-back-fill="true"
       >
       </nut-calendar>
@@ -211,6 +229,7 @@ interface TestCalendarState {
   isVisible6: boolean;
   isVisible7: boolean;
   isVisible8: boolean;
+  isVisible9: boolean;
   date1: string[];
   date2: string;
   date3: string;
@@ -219,6 +238,7 @@ interface TestCalendarState {
   date6: string[];
   date7: string[];
   date8: string;
+  date9: string[];
 }
 export default {
   props: {},
@@ -241,6 +261,7 @@ export default {
       date6: [],
       date7: [],
       date8: '',
+      date9: ['2020-01-23', '2020-01-26'],
       isVisible1: false,
       isVisible2: false,
       isVisible3: false,
@@ -248,7 +269,8 @@ export default {
       isVisible5: false,
       isVisible6: false,
       isVisible7: false,
-      isVisible8: false
+      isVisible8: false,
+      isVisible9: false
     });
     const openSwitch = (param: string) => {
       state[`${param}`] = true;
@@ -297,6 +319,10 @@ export default {
     const setChooseValue8 = (param: string) => {
       state.date8 = param[3];
     };
+    const setChooseValue9 = (param: any) => {
+      let { weekDate } = param;
+      state.date9 = [weekDate[0].date[3], weekDate[1].date[3]];
+    };
     const clickBtn = () => {
       let date = [Utils.date2Str(new Date()), Utils.getDay(6)];
       state.date5 = date;
@@ -332,6 +358,7 @@ export default {
       clickBtn1,
       setChooseValue7,
       setChooseValue8,
+      setChooseValue9,
       goDate,
       calendarRef,
       select,