Forráskód Böngészése

fix: calendar schedule month switching exception

Casper Dai 3 éve
szülő
commit
6b086c1b01

+ 114 - 55
src/components/Schedule/ScheduleCalendar/index.vue

@@ -9,8 +9,15 @@
     @click.stop
   >
     <template #header>
+      <button
+        v-if="editable"
+        class="l-flex__none c-sibling-item o-button"
+        @click="today"
+      >
+        此刻
+      </button>
       <i
-        class="c-schedule-calendar__btn el-icon-arrow-left u-pointer"
+        class="c-schedule-calendar__btn el-icon-arrow-left c-sibling-item u-pointer"
         :class="{ show: canToPresent }"
         @click="toPresent"
       />
@@ -41,7 +48,7 @@
             v-for="(day, dayIndex) in week"
             :key="dayIndex"
             class="c-schedule-calendar__col day c-day-card"
-            :class="{ 'enabled': day.enabled, 'disabled': !day.enabled, 'invalid': day.invalid, 'u-pointer': day.editable }"
+            :class="{ 'enabled': day.editable, 'disabled': day.disabled, 'invalid': day.invalid }"
             @dblclick="addProgramByDay(day)"
           >
             <span class="c-day-card__day">{{ day.value }}</span>
@@ -157,10 +164,25 @@ export default {
   },
   methods: {
     init () {
-      const now = Date.now()
-      this.min = this.programs.length ? this._transform(this.programs[0].startDateTime) : this._transform(now)
-      if (!this.editable) {
+      const now = this._transform(Date.now())
+      let current = {
+        year: now.year,
+        month: now.month
+      }
+      if (this.editable) {
+        this._setMinDate()
+        if (this.programs.length) {
+          const minProgramDate = this._transform(this.programs[0].startDateTime)
+          if (this._compare(now, minProgramDate, false) < 0) {
+            current = {
+              year: minProgramDate.year,
+              month: minProgramDate.month
+            }
+          }
+        }
+      } else {
         if (this.programs.length) {
+          this.min = this._transform(this.programs[0].startDateTime)
           this.max = this.programs.reduce((curr, { endDateTime }) => {
             const date = this._transform(endDateTime)
             if (curr) {
@@ -169,10 +191,16 @@ export default {
             return date
           }, null)
         } else {
-          this.max = this.min
+          this.max = this.min = now
+        }
+        if (this._compare(now, this.max, false) > 0) {
+          current = {
+            year: this.min.year,
+            month: this.min.month
+          }
         }
       }
-      this.current = { ...this.min }
+      this.current = current
       this._calculate()
     },
     onSave () {
@@ -232,21 +260,45 @@ export default {
         }
       ).then(() => {
         this.dirty = true
-        const index = this.programs.findIndex(program => program.key === key)
-        this.programs.splice(index, 1)
+        this._removeProgram(key)
         this._calculate()
       })
     },
+    _removeProgram (key) {
+      const index = this.programs.findIndex(program => program.key === key)
+      this.programs.splice(index, 1)
+      if (index === 0) {
+        this._setMinDate()
+        if (this._compare(this.current, this.min, false) < 0) {
+          this.current = {
+            year: this.min.year,
+            month: this.min.month
+          }
+        }
+      }
+    },
+    _setMinDate () {
+      let minDate = this._transform(Date.now())
+      if (this.programs.length) {
+        const minProgramDate = this._transform(this.programs[0].startDateTime)
+        if (this._compare(minDate, minProgramDate, false) > 0) {
+          minDate = minProgramDate
+        }
+      }
+      if (!this.min || this._compare(this.min, minDate) < 0) {
+        this.min = minDate
+      }
+    },
     addProgram () {
       this.editProgram({})
     },
     addProgramByDay (day) {
-      if (day.enabled) {
+      if (day.editable) {
         const { year, month } = this.current
         const date = day.value
         this.editProgram({
-          startDateTime: `${year}-${month + 1}-${date} ${this._compare({ year, month, day: date }, this.min) === 0 ? parseTime(new Date(), '{h}:{i}:{s}') : '00:00:00'}`,
-          endDateTime: `${year}-${month + 1}-${date} 23:59:59`
+          startDateTime: `${year}-${(month + 1).toString().padStart(2, '0')}-${date} ${this._compare({ year, month, day: date }, this._transform(Date.now())) === 0 ? parseTime(new Date(), '{h}:{i}:{s}') : '00:00:00'}`,
+          endDateTime: `${year}-${(month + 1).toString().padStart(2, '0')}-${date} 23:59:59`
         })
       }
     },
@@ -256,18 +308,6 @@ export default {
         this.editing = true
       }
     },
-    checkConflict (program, key) {
-      if (this.programs.length) {
-        const cstartDateTime = new Date(program.startDateTime)
-        const cendDateTime = new Date(program.endDateTime)
-        return this.programs.find(item => {
-          const startDateTime = new Date(item.startDateTime)
-          const endDateTime = new Date(item.endDateTime)
-          return item.key !== key && !(cstartDateTime > endDateTime || cendDateTime < startDateTime)
-        })
-      }
-      return null
-    },
     saveProgram () {
       const program = this.$refs.editor.getValue()
       const { id, startDateTime, endDateTime } = program
@@ -305,9 +345,7 @@ export default {
       program.key = Math.random().toString(16).slice(2)
       program.days = this._getDays(program.startDateTime, program.endDateTime)
       if (this.program.id) {
-        const key = this.program.key
-        const index = this.programs.findIndex(item => item.key === key)
-        this.programs.splice(index, 1)
+        this._removeProgram(this.program.key)
       }
       const timestamp = new Date(startDateTime).getTime()
       const insertIndex = this.programs.findIndex(item => new Date(item.startDateTime).getTime() > timestamp)
@@ -319,10 +357,27 @@ export default {
       this._calculate()
       this.handleCloseEditDialog()
     },
+    checkConflict (program, key) {
+      if (this.programs.length) {
+        const cstartDateTime = new Date(program.startDateTime)
+        const cendDateTime = new Date(program.endDateTime)
+        return this.programs.find(item => {
+          const startDateTime = new Date(item.startDateTime)
+          const endDateTime = new Date(item.endDateTime)
+          return item.key !== key && !(cstartDateTime > endDateTime || cendDateTime < startDateTime)
+        })
+      }
+      return null
+    },
     handleCloseEditDialog () {
       this.program = null
       this.editing = false
     },
+    today () {
+      const { year, month } = this._transform(Date.now())
+      this.current = { year, month }
+      this._calculate()
+    },
     _transform (timestamp) {
       const date = new Date(timestamp)
       return {
@@ -342,42 +397,23 @@ export default {
     },
     _createItem (date, disabled) {
       const dateObj = this._transform(date)
-      const valid = this._compare(dateObj, this._transform(Date.now())) >= 0 && (!this.editable || this._compare(dateObj, this.max) <= 0)
-      const enabled = valid && !disabled
+      const invalid = this._compare(dateObj, this._transform(Date.now())) < 0
       const day = `${dateObj.year}-${dateObj.month + 1}-${dateObj.day}`
       return {
         value: dateObj.day,
-        editable: enabled && this.editable,
-        enabled,
-        invalid: !valid,
+        editable: this.editable && !disabled && !invalid,
+        invalid,
+        disabled,
         programs: this.programs.length ? this.programs.filter(program => {
           return program.days[day]
         }) : []
       }
     },
-    _offsetMonth (offset) {
-      if (offset < 0) {
-        if (this.current.month === 0) {
-          this.current.year -= 1
-          this.current.month = 11
-        } else {
-          this.current.month -= 1
-        }
-      } else if (offset > 0) {
-        if (this.current.month === 11) {
-          this.current.year += 1
-          this.current.month = 0
-        } else {
-          this.current.month += 1
-        }
-      }
-      this._calculate()
-    },
     _calculate () {
       const { year, month } = this.current
       const monthDays = this._getPreentMonthDays(year, month).concat(this._currentMonthDays(year, month))
-      const diff = monthDays.length % 7
-      const dates = diff === 0 ? monthDays : monthDays.concat(this._getNextMonthDays(year, month, 7 - diff))
+      const diff = 42 - monthDays.length
+      const dates = diff === 0 ? monthDays : monthDays.concat(this._getNextMonthDays(year, month, diff))
       const weeks = []
       let row
       for (let i = 0; i < dates.length; i++) {
@@ -400,8 +436,10 @@ export default {
     },
     _getPreentMonthDays (year, month) {
       const dateArr = []
+      const week = new Date(year, month, 1).getDay()
+      const fill = week === 0 ? 7 : week
 
-      for (let i = new Date(year, month, 1).getDay(); i > 0; i--) {
+      for (let i = fill; i > 0; i--) {
         dateArr.push(this._createItem(new Date(year, month, 1 - i), true))
       }
 
@@ -416,6 +454,24 @@ export default {
 
       return dateArr
     },
+    _offsetMonth (offset) {
+      if (offset < 0) {
+        if (this.current.month === 0) {
+          this.current.year -= 1
+          this.current.month = 11
+        } else {
+          this.current.month -= 1
+        }
+      } else if (offset > 0) {
+        if (this.current.month === 11) {
+          this.current.year += 1
+          this.current.month = 0
+        } else {
+          this.current.month += 1
+        }
+      }
+      this._calculate()
+    },
     toPresent () {
       if (this.canToPresent) {
         this._offsetMonth(-1)
@@ -478,6 +534,7 @@ export default {
     display: flex;
     min-width: 0;
     height: 108px;
+    user-select: none;
 
     &.disabled {
       color: $gray;
@@ -488,8 +545,10 @@ export default {
       cursor: not-allowed;
     }
 
-    &.day.enabled {
-      &.actived, &:hover {
+    &.day.enabled{
+      cursor: pointer;
+
+      &:hover {
         transition: background-color .4s;
         background-color: #f2f8fe;
       }

+ 2 - 2
src/components/Schedule/components/ScheduleWrapper.vue

@@ -20,7 +20,7 @@
     </el-result>
     <template v-if="!error && !loading">
       <div class="l-flex__none l-flex--row has-bottom-padding">
-        <div class="l-flex__auto l-flex--row">
+        <div class="l-flex__auto l-flex--row c-sibling-item">
           <template v-if="editable">
             <button
               class="l-flex__none c-sibling-item o-button"
@@ -51,7 +51,7 @@
             <span class="c-sibling-item">{{ resolutionRatio }}</span>
           </div>
         </div>
-        <div class="l-flex__none l-flex--row">
+        <div class="l-flex__none l-flex--row c-sibling-item">
           <slot name="header" />
         </div>
       </div>