【Vue+Element】实现日历任务展示

【Vue+Element】实现日历任务展示

效果图

【Vue+Element】实现日历任务展示_第1张图片

代码

新建Calendar.vue

<template>
  <div>
    
    <div class="calendar-header">
      <div class="calendar-header-btn">
        <i class="el-icon-d-arrow-left" @click="changeDateForYear('pre')">i>
        <i class="el-icon-arrow-left" @click="changeDateForMonth('pre')" style="margin-left: 10px">i>
      div>
      <div class="calendar-header-btn">
        <span>{{ currentDate.currentYear }}年{{ currentDate.currentMonth }}月span>
      div>

      <div class="calendar-header-btn ">
        <i class="el-icon-arrow-right" @click="changeDateForMonth('next')" style="margin-right: 10px">i>
        <i class="el-icon-d-arrow-right" @click="changeDateForYear('next')">i>
      div>

    div>
    
    <el-divider>el-divider>
    
    <div class="calendar-body">
      
      <div class="calendar-body-week">
        <div
          :class="item.value === currentDate.currentWeek ? 'calendar-day-box-selected calendar-day-box': 'calendar-day-box'"
          v-for="(item,index) in weeArray" :key="item.value">
          <div style="border-radius: 50%;">
            <span>{{ item.cn_label }}span>
          div>
        div>
      div>
      
      <div class="calendar-body-date">
        <div class="calendar-day-box"
             :class="item.isNow ? 'calendar-day-box-selected calendar-day-box': 'calendar-day-box'"
             v-for="(item,index) in calendarList" :key="index">
          <span :class="item.isNonCurrentMonth ? 'non-current-month':'' ">{{ item.currentDay }}span>
        div>
      div>
    div>
    <el-divider>el-divider>
    <div class="task-box">
      <div class="task-box-tag">
        <el-tabs :stretch="true" v-model="activeName" @tab-click="changeTaskType">
          <el-tab-pane name="SystemTask">
            <span slot="label">
             系统任务({{ taskList.systemTask.nonCompletedSum }})
            span>
          el-tab-pane>
          <el-tab-pane name="CustomTask">
            <span slot="label">
             自定义任务({{ taskList.customTask.nonCompletedSum }})
            span>
          el-tab-pane>
        el-tabs>
      div>
      <div>
        <el-button type="primary" v-if="activeName === 'CustomTask'" size="mini">新建el-button>
        <el-button size="mini">查看全部el-button>
      div>
    div>
    <div class="task-list" v-if=" currentTaskList && currentTaskList.length > 0">
      <div v-for="(item, index) in currentTaskList" :key="index" class="task-list-item">
        <div class="task-list-item-box">
          <div>
            <svg-icon :icon-class="item.taskDegreeLevelType || 'general'">svg-icon>
          div>
          <div class="task-list-item-view">
            <div class="task-list-item-title">
              <span>{{ item.taskName }}span>
            div>
            <div class="task-list-item-info">
              <span>来自:{{ item.from }} | {{ item.pushDate }}span>
            div>
          div>
        div>
        <div>
          <tag-view :tag-id="item.taskStatus"
                    :tags="staticOptions['TaskStatus']">
          tag-view>
        div>
        <div>
          <el-button type="text">查看详情el-button>
        div>
      div>
    div>
    <div class="task-list" v-else>
      <el-empty description="暂无任务数据">el-empty>
    div>
  div>
template>

<script>
import {weekDisplayList} from '@/utils/constant'
import {getDashboardTaskPanel} from "@/api/task";
import {getStaticOptions} from "@/api/resources";
import TagView from "@/components/TagView";

export default {
  name: "Calendar",
  components: {TagView},
  data() {
    return {
      staticOptionsScopes: 'TaskType,TaskStatus',
      staticOptions: {},

      weeArray: weekDisplayList,
      currentDate: {
        currentYear: 1900,
        currentMonth: 1,
        currentDay: 1,
        currentWeek: 0,
      },
      calendarList: [],

      activeName: 'SystemTask',
      taskList: {
        systemTask: {
          nonCompletedSum: 0,
          taskList: []
        },
        customTask: {
          nonCompletedSum: 0,
          taskList: []
        }
      },
      currentTaskList: []


    }
  },
  created() {

  },
  mounted() {
    this.$nextTick(function () {
      this.init()
    })
  },
  methods: {
    async init() {
      await this.initOptions()
      await this.initCalendar()
      await this.initTaskList()
    },
    initCalendar() {
      console.log("initCalendar")
      const date = new Date()
      this.currentDate.currentYear = date.getFullYear() + ''
      this.currentDate.currentMonth = date.getMonth() + 1
      // 月份是从0开始的(0-11)
      this.currentDate.currentDay = date.getDate()
      this.currentDate.currentWeek = date.getDay()
      console.log('initCalendar', this.currentDate)
      //
      this.getCalendarBox(this.currentDate)
    },
    initOptions() {
      console.log("initOptions")
      getStaticOptions(this.staticOptionsScopes).then(res => {
        this.staticOptions = res.data
      })
    },
    initTaskList() {
      console.log("initTaskList")
      let startTime = new Date(this.currentDate.currentYear + '-' + this.currentDate.currentMonth + '-' + this.currentDate.currentDay + ' 00:00:00').getTime()
      let endTime = new Date(this.currentDate.currentYear + '-' + this.currentDate.currentMonth + '-' + this.currentDate.currentDay + ' 23:59:59').getTime()
      getDashboardTaskPanel(startTime, endTime).then(res => {
        this.taskList = res.data
        this.changeTaskList()
      })
    },
    getCalendarBox(currentDate) {
      this.calendarList = []
      // 唯一知道的只有这个封装的时间类
      // 获取当前月的第一天的date和最后一天的date
      let startDateStr = currentDate.currentYear + '-' + currentDate.currentMonth + '-' + '1'
      let endDateStr = currentDate.currentYear + '-' + currentDate.currentMonth + '-' + this.getMonthDays(currentDate.currentYear, currentDate.currentMonth, currentDate.currentDay, 0)

      let startDate = new Date(startDateStr)
      let endDate = new Date(endDateStr)

      // 判断第一天是否是周日 不是周日向前推到周日
      // 周日是 0
      if (startDate.getDay() !== 0) {
        let preYear = currentDate.currentYear
        let preMonth = currentDate.currentMonth
        if (currentDate.currentMonth === 1) {
          preMonth = 12
          preYear = preYear - 1
        } else {
          preMonth = preMonth - 1
        }
        // 获取上个月的最后一天
        let preLastDay = this.getMonthDays(preYear, preMonth, 1, 0);
        for (let i = startDate.getDay(); i > 0; i--) {
          let preDay = preLastDay - i
          let preDate = new Date(preYear + '-' + preMonth + '-' + preDay)
          let dateObj = {
            currentYear: preYear,
            currentMonth: preMonth,
            currentDay: preDate.getDate(),
            currentWeek: preDate.getDay(),
            isNow: false,
            isNonCurrentMonth: true,
            inlineWeek: false
          }
          this.calendarList.push(dateObj)
        }
      }
      // 补齐中间数据 也就是当前月
      let nowYear = new Date().getFullYear() + ''
      let nowMonth = new Date().getMonth() + 1
      let nowDay = new Date().getDate()
      let nowWeek = new Date().getDay()

      for (let i = 1; i <= endDate.getDate(); i++) {
        let _currentDate = new Date(currentDate.currentYear + '-' + currentDate.currentMonth + '-' + i)
        let dateObj = {
          currentYear: _currentDate.getFullYear(),
          currentMonth: _currentDate.getMonth() + 1,
          currentDay: _currentDate.getDate(),
          currentWeek: _currentDate.getDay(),
          isNow: false,
          isNonCurrentMonth: false,
          inlineWeek: false
        }

        // 判断当前日期节点
        if (parseInt(nowYear) === parseInt(dateObj.currentYear)
          && parseInt(nowMonth) === parseInt(dateObj.currentMonth)
          && parseInt(nowDay) === parseInt(dateObj.currentDay)) {
          dateObj.isNow = true
        }
        this.calendarList.push(dateObj)
      }
      // 补齐尾部数据

      if (endDate.getDay() !== 6) {
        let nextYear = currentDate.currentYear
        let nextMonth = currentDate.currentMonth
        if (currentDate.currentMonth === 12) {
          nextMonth = 1
          nextYear = nextYear + 1
        } else {
          nextMonth = nextMonth + 1
        }
        // 获取下个月个月的最后一天
        let len = 6 - endDate.getDay()
        for (let i = 1; i <= len; i++) {
          let nextMonthDay = new Date(nextYear + '-' + nextMonth + '-' + i)
          let dateObj = {
            currentYear: nextMonthDay.getFullYear(),
            currentMonth: nextMonthDay.getMonth() + 1,
            currentDay: nextMonthDay.getDate(),
            currentWeek: nextMonthDay.getDay(),
            isNow: false,
            isNonCurrentMonth: true,
            inlineWeek: false
          }
          this.calendarList.push(dateObj)
        }
      }
      console.log('getCalendarBox', this.calendarList)
    },
    getMonthDays(year, month, day, val) {
      let date = new Date(year + '-' + month + '-' + day)
      // 获取当前页面的天数
      date.setMonth(date.getMonth() + 1); // 先设置为下个月
      date.setDate(val); // 再置0,变成当前月最后一天
      return date.getDate();
    },
    changeDateForMonth(type) {
      // 最小粒度是从月份开始的
      if (type === 'pre') {
        // 推前
        if (this.currentDate.currentMonth === 1) {
          this.currentDate.currentYear = this.currentDate.currentYear - 1
          this.currentDate.currentMonth = 12
        } else {
          this.currentDate.currentMonth = this.currentDate.currentMonth - 1
        }
      } else {
        // 推后一个月
        if (this.currentDate.currentMonth === 12) {
          this.currentDate.currentYear = this.currentDate.currentYear + 1
          this.currentDate.currentMonth = 1
        } else {
          this.currentDate.currentMonth = this.currentDate.currentMonth + 1
        }
      }
      // 2月份比较特殊 要判断最后一天
      let lastDay = this.getMonthDays(this.currentDate.currentYear, this.currentDate.currentMonth, 1, 0);
      console.log('lastDay', lastDay)
      //
      if (this.currentDate.currentDay > lastDay) {
        this.currentDate.currentDay = lastDay
      }
      console.log('changeDate', this.currentDate)
      this.getCalendarBox(this.currentDate)
    },
    changeDateForYear(type) {
      // 最小粒度是从月份开始的
      if (type === 'pre') {
        // 推前
        this.currentDate.currentYear = this.currentDate.currentYear - 1
      } else {
        // 推后一个月
        this.currentDate.currentYear = this.currentDate.currentYear + 1
      }
      let lastDay = this.getMonthDays(this.currentDate.currentYear, this.currentDate.currentMonth, 1, 0);
      console.log('lastDay', lastDay)
      //
      if (this.currentDate.currentDay > lastDay) {
        this.currentDate.currentDay = lastDay
      }
      console.log('changeDate', this.currentDate)
      this.getCalendarBox(this.currentDate)
    },
    changeTaskType(tab, event) {
      console.log('changeTaskType', tab, event, this.activeName)
      this.changeTaskList()
    },
    changeTaskList() {
      this.currentTaskList = []
      if (this.activeName === 'SystemTask') {
        console.log("initTaskList", this.taskList.systemTask.tasksList)
        this.currentTaskList = this.taskList.systemTask.tasksList
      } else {
        this.currentTaskList = this.taskList.customTask.tasksList
      }
    }
  }
}
script>

<style scoped lang="scss">
.el-divider {
  margin: 10px 0;
}

.calendar-footer {
  cursor: pointer;
  text-align: center;
  margin: 0 auto;
  width: 68px;
  height: 34px;
  border-radius: 10px 10px 0 0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
}

.calendar-header {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;

  .calendar-header-btn {
    cursor: pointer;
    width: 100px;
    text-align: center;
  }

  .left {
    display: flex;
    flex-direction: row;
  }

  .right {
    display: flex;
    flex-direction: row-reverse
  }
}

.calendar-day-box {
  width: 88px;
  height: 44px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 5px
}

.calendar-body {
  text-align: center;
  min-height: 308px;

  .calendar-body-week {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
  }

  .calendar-body-date {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-around;

  }
}

.task-box {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: center;

  .task-box-tag {
    width: 250px;
  }
}

.task-list {
  height: 308px;
  overflow: auto;

  .task-list-item {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    margin: 20px 0;

    .task-list-item-box {
      display: flex;

      .task-list-item-view {
        margin: 0 35px;

        .task-list-item-title {
          font-weight: 900;
          margin-bottom: 10px;
        }

        .task-list-item-info {
          font-size: 15px;
        }
      }
    }


  }
}
style>

方法的数据结构可以自己定义

你可能感兴趣的:(Vue.js,vue.js,javascript,前端)