vue中的日历展示进度功能的实现

在这里插入图片描述

先下载引入moment

// viewer.vue
<template>
  <div class="viewPager">
    <div class="box">
      <div class="block">
        <el-date-picker
          v-model="value"
          style="margin-bottom: 10px"
          type="month"
          placeholder="选择月"
          @change="change"
        />
      </div>
      <ul class="week">
        <li v-for="(item, i) in week" :key="'week' + i" class="week">
          {{ item }}
        </li>
      </ul>
      <ul v-for="(weekItem, index) in list" :key="'day' + index" class="day">
        <li
          v-for="(item, indexDay) in weekItem"
          :key="'day' + indexDay"
          :class="item.val"
        >
          <div class="content">
            <p class="date">{{ item.date }}</p>
          </div>
          <div v-if="item['children']" class="content1">
            <div
              v-for="(sub, subIndex) in item['children']"
              :key="'day' + subIndex"
            >
              <div
                v-if="sub.status === 'grade-finsh'"
                class="linear"
                :class="indexDay === 6 && 'w100'"
              >
                <p v-if="indexDay === 0">{{ sub.label }}</p>
                <span class="grade-finsh" :style="{ width: sub.bar1 }" /><a
                  class="text-ellipsis"
                  >{{ `${+sub.actual}/${sub.plan}` }}</a
                >
              </div>
              <div
                v-else-if="sub.status === 'grade-full'"
                class="linear"
                :class="indexDay === 6 && 'w100'"
                style=""
              >
                <p v-if="indexDay === 0">{{ sub.label }}</p>
                <span
                  class="grade-full"
                  :style="{ width: sub.bar1, marginRight: 0 }"
                />
                <span
                  class="grade-full"
                  :style="{ width: sub.bar2, marginLeft: 0 }"
                /><a class="text-ellipsis">{{
                  `${+sub.actual}/${sub.plan}`
                }}</a>
              </div>
              <div
                v-else-if="sub.status === 'grade-unfinsh'"
                class="linear"
                :class="indexDay === 6 && 'w100'"
              >
                <p v-if="indexDay === 0">{{ sub.label }}</p>
                <!-- <span  /> -->
                <span :style="{ width: sub.bar2 }" class="grade-unfinsh"
                  ><a class="text">
                    <a class="text-ellipsis">{{
                      `${+sub.actual}/${sub.plan}`
                    }}</a>
                  </a></span
                >
                <span class="i" :style="{ width: sub.bar1 }" />
              </div>
            </div>
          </div>
          <div v-else class="content1">
            <div class="linear" :class="indexDay === 6 && 'w0'">
              <p v-if="indexDay === 0"></p>
              <span /><a />
            </div>
            <div class="linear" :class="indexDay === 6 && 'w0'">
              <p v-if="indexDay === 0"></p>
              <span /><a />
            </div>
            <div class="linear" :class="indexDay === 6 && 'w0'">
              <p v-if="indexDay === 0"></p>
              <span /><a />
            </div>
            <div class="linear" :class="indexDay === 6 && 'w0'">
              <p v-if="indexDay === 0"></p>
              <span /><a />
            </div>
          </div>
        </li>
      </ul>

      <div class="footer">
        <ul class="icon">
          <li>
            <span class="finsh" />
            <p>完成</p>
          </li>
          <li>
            <span class="full" />
            <p>超额</p>
          </li>
          <li>
            <span class="un-finsh" />
            <p>未完成</p>
          </li>
        </ul>
        <ul class="text-desc">
          <li>早班:8:00-16:00</li>
          <li>中班:16:00-24:00</li>
          <li>晚班:24:00-8:00</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
import moment from "moment";
import { getMonthlyData } from "@/api/dispatch";
import { getData, week } from "../common";
export default {
  props: {
    keyValue: {
      type: Number,
      default: 1,
    },
  },
  data() {
    return {
      week,
      timer: "",
      value: "",
      params: {
        workingFaceId: this.$store.getters.workingId,
        startDay: "",
        endDay: "",
        month: "",
        year: "",
      },
      listLoading: false,
      list: [],
      monthList: [],
      dateList: [],
      getData,
    };
  },
  watch: {
    keyValue: {
      handler(val, oldval) {
        this.change(this.value);
      },
      deep: true, // 开启深度监听
    },
  },
  created() {
    this.value = new Date();
  },
  mounted() {
    // this.list = this.getData(moment())
    // 轮询调用
    this.change(this.value);
    this.timer = setInterval(() => this.change(this.value), 1000 * 60 * 2);
  },
  beforeDestroy() {
    clearInterval(this.timer);
  },
  methods: {
    change(m) {
      if (!m) {
        this.list = [];
        return;
      }
      this.monthList = this.getData(moment(m));
      this.fetchData(m);
      // this.value =
    },
    fetchData(data) {
      // debugger
      const m = moment(data);
      // debugger
      this.monthList = this.getData(m);
      this.params.startDay = this.monthList[0][0].full;
      const endDay = this.monthList[this.monthList.length - 1];
      this.params.endDay = endDay[endDay.length - 1].full;
      // console.log(this.monthList)
      this.params["month"] = m.month() + 1;
      this.params["year"] = m.year();

      // 旧传参与返回值
      //http://localhost:9528/app/faceScheduling/getMonthlyData?workingFaceId=2566929a-6dd6-11ec-b297-525400017fd2&startDay=2021-12-26&endDay=2022-02-05&month=1&year=2022
      var canshu = {
        workingFaceId: "2566929a-6dd6-11ec-b297-525400017fd2",
        startDay: "2021-12-26",
        endDay: "2022-02-05",
        month: 1,
        year: 2022,
      };
      var aaa = [
        {
          actual: 0,
          actuallyMiddleShift: null,
          actuallyMorningShift: null,
          actuallyNightShift: null,
          actuallyTotal: 0,
          bar1: "0%",
          bar2: "60%",
          day: 1,
          fullDate: "2022-01-01",
          label: "总",
          month: 1,
          plan: 6.06,
          planMiddleShift: 2.02,
          planMorningShift: 2.02,
          planNightShift: 2.02,
          planTotal: 6.06,
          status: "grade-unfinsh",
          year: 2022,
        },
      ];
      var a1aa = [
        {
          actuallyMiddleShift: 1,
          actuallyMorningShift: 2.02,
          actuallyNightShift: 1.3,
          actuallyTotal: 3,
          day: 1,
          fullDate: "2022-05-01",
          month: 5,
          planMiddleShift: 2.01,
          planMorningShift: 2.02,
          planNightShift: 2.03,
          planTotal: 6.06,
          // status: "grade-unfinsh",
          year: 2022,
        },
        {
          actuallyMorningShift: 4,
          actuallyMiddleShift: 1,
          actuallyNightShift: 1.3,
          actuallyTotal: 5,
          day: 2,
          fullDate: "2022-05-02",
          month: 5,
          planMorningShift: 2,
          planMiddleShift: 3,
          planNightShift: 4,
          planTotal: 5,
          // status: "grade-unfinsh",
          year: 2022,
        },
      ];
      // ----------------------------------------------------------------
      var naaa = [
        {
          DF: 0,
          MIDDFACT: 0,
          EARLYFACT: 0,
          DEPT: "掘进一区二队",
          WORKFACE: "109采区轨道大巷",
          WORKFACEID: 5568,
          DAY: "2022-05-10",
        },
      ];

      // this.list = qwe
      this.list = this.dealData(
              a1aa,
              this.params["month"],
              this.params["year"]
            );

      // getMonthlyData(this.params).then((res) => {
      //   if (res.code === 200) {
      //     if (res.data && Array.isArray(res.data) && res.data.length > 0) {
      //       this.list = this.dealData(
      //         res.data,
      //         this.params["month"],
      //         this.params["year"]
      //       );
      //       console.log(this.list);
      //     } else {
      //       this.list = [];
      //     }

      //     // console.log(this.dealData(res.data, this.params['month'], this.params['year']))
      //   }
      //   this.listLoading = false;
      // });
    },
    dealData(data, month, year) {
      const mockList = this.monthList;
      const fileds = ["MorningShift", "MiddleShift", "NightShift", "Total"];
      const rate = 0.6;
      const dic = {
        0: "早",
        1: "中",
        2: "晚",
        3: "总",
      };
      if (Array.isArray(data)) {
        data.forEach((item) => {
          const maxList = [item["planTotal"], item["actuallyTotal"]];
          const filedTotal = Math.max(...maxList);
          const children = [];
          item.fullDate = moment(
            `${item.year}-${item.month}-${item.day}`
          ).format("YYYY-MM-DD");

          fileds.forEach((filed, filedIndex) => {
            // console.log(filedIndex)
            const plan = item["plan" + filed];
            const actual = item["actually" + filed];
            item.plan = plan && +plan.toFixed(2);
            item.actual = actual && +actual.toFixed(2);
            item.label = dic[filedIndex];

            if (item.actual > item.plan) {
              item.status = "grade-full";

              item.bar1 = (plan / filedTotal).toFixed(4) * 100 * rate + "%";
              item.bar2 =
                ((actual - plan) / filedTotal).toFixed(4) * 100 * rate + "%";
            }
            if (item.actual === item.plan) {
              // const filedTotal = actual + plan

              item.status = "grade-finsh";
              item.bar1 = (plan / filedTotal).toFixed(4) * 100 * rate + "%";
            }
            if (item.actual < item.plan) {
              // const filedTotal = actual + plan

              item.status = "grade-unfinsh";
              item.bar1 = (actual / filedTotal).toFixed(4) * 100 * rate + "%";
              item.bar2 = (plan / filedTotal).toFixed(4) * 100 * rate + "%";
            }
            const value = { ...item };
            // console.log(children)
            children.push(value);
          });
          mockList.forEach((mockL) => {
            mockL.forEach((mock, i) => {
              if (mock.full === item.fullDate) {
                mock.children = children;
              }
            });
          });
        });
      }
      // console.log(mockList)
      return mockList;
    },
  },
};
</script>
<style >
.el-month-table td.today .cell {
  color: #606266;
}
</style>
<style lang="scss" scoped>
.w100 {
  width: 100% !important;
}
.w0 {
  width: 100% !important;
}
.text-ellipsis {
  display: inline-block;
  width: 60px;
  text-overflow: ellipsis;
}

.viewPager {
  height: 100%;
  padding: 10px 30px 10px 0;
  .box {
    height: 96%;
    position: relative;
    padding-left: 50px;
    padding-right: 70px;
    overflow: auto;
    overflow-x: hidden;
    .week {
      width: 100%;
      color: rgb(68, 124, 235);
      font-weight: 550;
      height: 25px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #09265f;
      li {
        display: flex;
        justify-content: center;
        width: 14%;
      }
    }
    .footer {
      width: 100%;
      margin-top: 10px;
      .icon {
        width: 100%;
        display: flex;
        justify-content: flex-end;
        color: #4d8cff;
        font-size: 13px;
        li {
          width: 100px;
          display: flex;
          justify-content: center;
          align-items: center;
          p {
            margin-left: 10px;
          }
          span {
            display: inline-block;

            height: 15px;
            width: 20px;
            border-radius: 8px;
          }
          .finsh {
            background-image: linear-gradient(to right, #00efed, #00f157);
          }
          .full {
            background-image: linear-gradient(
              to right,
              #ff9300,
              #ffd100
            ) !important;
          }
          .un-finsh {
            background-image: linear-gradient(to right, #ff0000, #ff3f00);
          }
        }
      }
      .text-desc {
        margin-top: 10px;
        width: 100%;
        display: flex;
        justify-content: flex-end;
        color: #4d8cff;
        font-size: 13px;
        li {
          width: 140px;
          display: flex;
          justify-content: flex-end;
          align-items: center;
        }
      }
    }

    .day {
      margin-top: 5px;
      width: 100%;

      display: flex;
      justify-content: space-between;
      align-items: center;

      // background: #09265f;
      li {
        display: flex;
        background: #0c2854;
        padding: 3px;
        opacity: 0.8;
        // border: 1px solid #fff;
        height: 125px;
        justify-content: center;
        flex-direction: column;
        margin: 5px;
        align-items: center;
        width: 14%;
        border-radius: 8px;
        .content {
          width: 100%;
          height: 30px;
          flex-direction: column;
          justify-content: flex-start;
          .date {
            width: 95%;
            height: 60px;
            margin-top: 3px;
            //  margin-right: 20px;
            display: flex;
            font-size: 30px;
            color: #11428e;
            font-weight: 550;
            justify-content: flex-end;
          }
        }
        .content1 {
          width: 100%;
          height: 110px;
          flex-direction: column;
          justify-content: space-between;

          .linear {
            display: flex;
            justify-content: flex-start;
            position: relative;
            align-items: center;
            font-size: 12px;
            border-bottom: 1px dashed #20355a;
            width: 106%;
            p {
              // height: 100%;
              text-align: center;
              width: 40px;
              position: absolute;
              margin-top: 8px;
              left: -40px;
              z-index: 999;
              color: #4d8cff;
              border-bottom: 1px dashed #20355a;
            }
            span {
              display: block;
              margin: 5px;
              height: 10px;
              border-radius: 5px;
            }
          }
          .grade-finsh {
            width: 60%;
            background-image: linear-gradient(to right, #00efed, #00f157);
          }
          .grade-full {
            width: 50%;
            padding: 0;
            // margin-left: 0 !important;

            float: left;
            background-image: linear-gradient(to right, #ff9300, #ffd100);
          }
          .grade-unfinsh {
            height: 100%;
            width: 50%;
            border: 1px solid red;
            position: relative;
            display: flex;

            a {
              position: absolute;
              top: 0;
              left: 120%;
              height: 100%;
            }
          }
          .i {
            position: absolute;
            left: 0;
            display: inline-block;
            border-radius: 4px;
            width: 120%;
            height: 78%;
            background-image: linear-gradient(to right, #ff0000, #ff3f00);
            // box-shadow: 0 0 0 1px red;
          }
        }
      }
      .prev {
        background: #273251;
        color: #3f4a71;

        .grade-unfinsh {
          border: none !important;
        }
        i {
          border: 1px #3f4a71 solid !important;
        }
        span {
          background-image: linear-gradient(to right, grey, grey) !important;
        }
      }
      .next {
        background: #273251;
        color: #3f4a71;
        .grade-unfinsh {
          border: none !important;
        }
        i {
          border: 1px #3f4a71 solid !important;
        }
        span {
          background-image: linear-gradient(to right, grey, grey) !important;
        }
      }
      .current {
        background: #0a1946;
        border: #032bd7 1px solid;
        box-shadow: 0px 0 20px #032bd7 inset;
      }
    }
  }
}
</style>

// common.js
import moment from 'moment'
export const week = ['日', '一', '二', '三', '四', '五', '六']
export const getData = m => {
  const year = m.year()
  const month = m.months()
  // if (month <= 0) {
  //   debugger
  // }
  const day = moment().date()

  // const date = moment().date()
  const arr = []
  const monthDay = moment()
    .year(year)
    .month(month)
    .daysInMonth() //  本月有几天
  let firstDayweek = moment()
    .year(year)
    .month(month)
    .startOf('month')
    .weekday() // 本月一号星期几
  let lastMonthDay = moment()
    .year(year)
    .month(month - 1)
    .daysInMonth() // 上个月最后一天是几号
  // 放上月
  while (firstDayweek--) {
    const i = lastMonthDay--
    arr.unshift({
      date: i,
      val: 'prev',
      full: moment(`${month === 0 ? year - 1 : year}-${month === 0 ? 12 : month}-${i}`).format('YYYY-MM-DD')
    })
  }
  // 放本月
  for (let i = 1; i <= monthDay; i++) {
    let val = 'now'
    if (i === day) {
      val = 'current'
    }
    // if (
    //   moment(`${year}-${month + 1}-${i}`).format('YYYY-MM-DD') ===
    //   moment().format('YYYY-MM-DD')
    // ) {
    //   val = val + ' ' + 'today'
    // }
    arr.push({
      date: i,
      val: val,
      full: moment(`${year}-${month + 1}-${i}`).format('YYYY-MM-DD')
    })
  }

  // 放下月
  let count = 1
  const target = arr.length <= 35 ? 35 : 42
  while (arr.length < target) {
    const a = count++
    arr.push({
      date: a,
      val: 'next',
      full: moment(`${month === 11 ? year + 1 : year}-${month === 11 ? 1 : month + 2}-${a}`).format('YYYY-MM-DD')
    })
  }

  // 变成二维数组
  const erweiArr = []
  while (arr.length > 0) {
    erweiArr.push(arr.splice(0, 7))
  }
  // console.log(erweiArr)
  return erweiArr
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue实现文件管理功能,可以按照以下步骤进行: 1. 设计数据结构 首先需要设计数据结构,包括文件夹和文件的属性,例如文件名、大小、创建时间等。 2. 创建文件夹和文件列表组件 创建文件夹和文件列表组件,用于展示当前目录下的所有文件夹和文件。可以使用Vue的v-for指令来遍历文件夹和文件列表,并使用v-bind指令来绑定属性。 3. 实现文件上传和下载功能 为了上传和下载文件,需要使用Vue的组件库或第三方库。可以使用vue-file-upload组件库来实现文件上传功能,使用vue-file-download组件库来实现文件下载功能。 4. 实现文件删除功能 为了删除文件,需要在文件列表组件添加删除按钮,并使用Vue的事件处理机制来监听按钮点击事件。当用户点击删除按钮时,应该提示用户确认是否删除文件,并使用Vue的v-if指令来控制是否显示确认对话框。 5. 实现文件搜索功能 为了实现文件搜索功能,需要在文件列表组件添加搜索框,并使用Vue的v-model指令来实现双向数据绑定。当用户输入搜索关键字时,应该重新渲染文件夹和文件列表,只显示匹配的文件夹和文件。 6. 实现文件重命名功能 为了实现文件重命名功能,需要在文件列表组件添加重命名按钮,并使用Vue的事件处理机制来监听按钮点击事件。当用户点击重命名按钮时,应该弹出重命名对话框,并使用Vue的v-if指令来控制是否显示对话框。当用户输入新的文件名时,应该更新文件的属性,并重新渲染文件夹和文件列表。 7. 实现文件移动功能 为了实现文件移动功能,需要在文件列表组件添加移动按钮,并使用Vue的事件处理机制来监听按钮点击事件。当用户点击移动按钮时,应该弹出移动对话框,并使用Vue的v-if指令来控制是否显示对话框。当用户选择要移动到的目录时,应该更新文件的属性,并重新渲染文件夹和文件列表。 以上是在Vue实现文件管理功能的基本步骤,具体实现细节可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值