当前位置:   article > 正文

Vue结合Element UI的el-table打造加工工序甘特图可视化解决方案

Vue结合Element UI的el-table打造加工工序甘特图可视化解决方案

引言

在玻璃加工行业,高效管理切割、磨边、洗、钢化、丝印等复杂工序对于提升生产效率至关重要。本文将介绍如何利用Vue.js框架结合Element UI组件库,自定义实现一个工序甘特图,以可视化展示各道工序的时间线与进度,为生产调度带来便利。

渲染效果

Vue结合Element UI的el-table打造加工工序甘特图可视化解决方案
同产品高亮
在这里插入图片描述

拖拽滚动,同产品高亮

在这里插入图片描述

小时高度,宽度改变动态效果

Vue结合Element UI的el-table打造加工工序甘特图可视化解决方案

全部代码:

优化

优化内容:减少timeInterval的调用,拖动滚动效果,同产品高亮效果。

<template>
  <div class="home group">
    <el-card
      :span="24"
      :xs="24"
      class="box-card"
      id="boxCard"
      ref="tableBox"
      append-to-body
    >
      <el-row>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button
            type="primary"
            plain
            icon="el-icon-view"
            size="mini"
            @click.native="switchView"
            >切换视图</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button
            type="primary"
            plain
            icon="el-icon-s-tools"
            size="mini"
            @click.native="startSchedulingProductionFun"
            >开始排产</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button
            type="primary"
            plain
            icon="el-icon-s-tools"
            size="mini"
            @click.native="proposalFun"
            >负荷调整建议</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button type="primary" plain size="mini" icon="el-icon-document"
            >查看物料到货计划</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button type="primary" plain size="mini" icon="el-icon-upload2"
            >导出</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button type="primary" plain icon="el-icon-printer" size="mini"
            >打印</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button type="primary" plain icon="el-icon-lock" size="mini"
            >锁定排产</el-button
          >
        </el-col>
        <el-col :span="1.5" style="margin-right: 10px">
          <el-button type="primary" plain icon="el-icon-unlock" size="mini"
            >解锁排产</el-button
          ></el-col
        >
        <!-- <el-col :span="1.5" style="margin-right: 10px">
          <el-button type="primary" plain icon="el-icon-rank" size="mini"
            >拖拽排产</el-button
          ></el-col
        > -->
      </el-row>
      <el-table
        @mousedown.native="startDrag"
        @mousemove.native="handleDrag"
        @mouseup.native="endDrag"
        @mouseleave.native="endDrag"
        v-loading="loading"
        element-loading-text="正在加载处理数据...."
        v-if="isView"
        :virtual-scroll="true"
        class="ganteTable"
        :class="isFillScreen ? 'fullscreen-table ganteTable' : 'ganteTable'"
        ref="ganTeTable"
        :height="tableHeight"
        :style="
          timeArr.length > 0
            ? 'width:' + tableWidth + 'px;'
            : 'width:239px;height:100%'
        "
        :key="tableKey"
        :cell-style="iCellStyle"
        :fit="false"
        :data="tableData"
        border
        align="center"
        size="mini"
        :span-method="tableSpanMethod"
      >
        <el-table-column
          fixed
          align="center"
          prop="index1"
          label="工作中心"
          class="index1"
        >
          <template slot-scope="scope">
            <el-popover
              placement="top-start"
              title="工作中心"
              trigger="hover"
              :content="scope.row.index1.label"
            >
              <div
                slot="reference"
                :class="rowHeight < 36 ? 'oneLineCls' : 'twoLineCls'"
              >
                {{ scope.row.index1.label }}
              </div>
            </el-popover>
          </template>
        </el-table-column>
        <el-table-column
          fixed
          align="center"
          prop="index2"
          label="产线名称"
          class="index1"
        >
          <template slot-scope="scope">
            <!-- {{ scope.row.index2.label }} -->
            <el-popover
              placement="top-start"
              title="产线名称"
              width="200"
              trigger="hover"
              :content="scope.row.index3.label"
            >
              <div
                slot="reference"
                :class="rowHeight < 36 ? 'oneLineCls' : 'twoLineCls'"
              >
                {{ scope.row.index2.label }}
              </div>
            </el-popover>
          </template>
        </el-table-column>
        <el-table-column
          fixed
          height="47px"
          align="center"
          prop="index3"
          label="设备名称"
          class="index1"
        >
          <template slot-scope="scope">
            <!-- {{ scope.row.index3.label }} -->
            <el-popover
              placement="top-start"
              title="设备名称"
              width="200"
              trigger="hover"
              :content="scope.row.index3.label"
            >
              <div
                slot="reference"
                :class="rowHeight < 36 ? 'oneLineCls' : 'twoLineCls'"
              >
                {{ scope.row.index3.label }}
              </div>
            </el-popover>
          </template>
        </el-table-column>
        <!-- 表头遍历日期 -->
        <div
          v-for="(timeArrItem, index1) in timeArr"
          :key="timeArrItem + index1 + ''"
        >
          <el-table-column
            height="47px"
            align="center"
            :label="timeArrItem.substr(0, 10)"
          >
            <!-- 表头遍历时间 -->
            <template v-for="(hourArrItem, index2) in hourArr">
              <el-table-column
                height="47px"
                align="center"
                class="pc-box"
                :label="hourArrItem + ''"
                :key="index1 + '-' + index2 + 5 + timeArrItem + hourArrItem"
                :width="latticeWidth + 'px;'"
              >
                <template slot="header">
                  <div class="hour-item" @mousemove="updateXY">
                    <span>{{ hourArrItem }}</span>

                    <div class="hour-ten-scale-box">
                      <div class="hour-ten-scale" v-for="x in 5" :key="x"></div>
                    </div>
                    <div class="hour-ten-side-box">
                      <div class="hour-ten-side-box-left"></div>
                      <div class="hour-ten-side-box-right"></div>
                    </div>
                  </div>
                  <div
                    class="minute-scale"
                    v-if="index2 === 0 && index1 === 0"
                    :style="{ width: tableWidth + 'px' }"
                  ></div>
                  <div
                    ref="pointBox"
                    id="pointBox"
                    v-if="index2 === 0 && index1 === 0"
                  ></div>
                </template>
                <template
                  slot-scope="scope"
                  v-if="index2 === 0 && index1 === 0"
                >
                  <div
                    id="content-box"
                    @mousemove="updateXY"
                    class="content-box"
                    :ref="index1 + '-' + index2 + 5"
                    :style="
                      'width:' +
                      timeArr.length * 24 * latticeWidth +
                      'px;overflow:hidden;'
                    "
                  >
                    <el-tooltip
                      :draggable="true"
                      v-for="workItem in scope.row.workPlanList.data"
                      :key="workItem.onlyId"
                      class="item"
                      style="z-index: 99999"
                      effect="dark"
                      content="Bottom Right 提示文字"
                      placement="bottom-end"
                    >
                      <div slot="content">
                        <p>信息</p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          工序:{{ workItem.workOrder }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          产品名称:{{ workItem.materialName }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          产品编码:{{ workItem.materialNo }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          产线名称:{{ workItem.productLineName }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          产线编码:{{ workItem.productLineSn }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          设备名称:{{ scope.row.index3.label }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          开始时间:{{ workItem.startTime }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          结束时间:{{ workItem.endTime }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          交期时间:{{ workItem.deliverTime }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          工作中心描述:{{ workItem.workCenterDesc }}
                        </p>
                        <p
                          v-if="
                            workItem.lineChangeFlag === null &&
                            workItem.restFlag === null
                          "
                        >
                          工作中心编码:{{ workItem.workCenterSn }}
                        </p>
                        <p v-if="workItem.lineChangeFlag === true">
                          状态:换线
                        </p>
                        <p v-if="workItem.restFlag === true">状态:休息</p>
                      </div>
                      <div
                        v-if="
                          workItem.lineChangeFlag === null &&
                          workItem.restFlag === null
                        "
                        @click="
                          highlightSimilarElements(
                            'A' + workItem.materialNo + workItem.deliverTime
                          )
                        "
                        :draggable="true"
                        :class="
                          'AAA A' +
                          workItem.materialNo +
                          workItem.deliverTime +
                          ''
                        "
                        :style="
                          'background-color:' +
                          workItem.color +
                          ';' +
                          ' position: absolute;' +
                          timeInterval(
                            workItem.startTime,
                            workItem.endTime,
                            workItem.onlyId
                          )
                        "
                      ></div>
                      <div
                        v-if="workItem.lineChangeFlag === true"
                        @click="
                          highlightSimilarElements(
                            'A' + workItem.materialNo + workItem.deliverTime
                          )
                        "
                        :draggable="true"
                        :class="
                          'AAA A' +
                          workItem.materialNo +
                          workItem.deliverTime +
                          ''
                        "
                        :style="
                          ' position: relative;  top: 50%;  bottom: 50%;height: 3px' +
                          ';' +
                          'background-color:' +
                          '#FF0000' +
                          ';' +
                          ' position: absolute;' +
                          timeInterval(
                            workItem.startTime,
                            workItem.endTime,
                            workItem.onlyId
                          )
                        "
                      ></div>
                      <div
                        v-if="workItem.restFlag === true"
                        @click="
                          highlightSimilarElements(
                            'A' + workItem.materialNo + workItem.deliverTime
                          )
                        "
                        :draggable="true"
                        :class="
                          'AAA A' +
                          workItem.materialNo +
                          workItem.deliverTime +
                          ''
                        "
                        :style="
                          'background-color:' +
                          '#cedcf0;' +
                          ' position: absolute;' +
                          timeInterval(
                            workItem.startTime,
                            workItem.endTime,
                            workItem.onlyId
                          )
                        "
                      ></div>
                    </el-tooltip>
                  </div>
                </template>
              </el-table-column>
            </template>
          </el-table-column>
        </div>
      </el-table>
      <day-table-view v-if="!isView"></day-table-view>
      <scheduling-window
        ref="schedulingWindow"
        @openSchedulingResultsWindow="openSchedulingResultsWindow"
      ></scheduling-window>
      <scheduling-results-window
        ref="schedulingResultsWindow"
        @switchView="switchView"
      ></scheduling-results-window>
      <suggestions-load-adjustment
        ref="suggestionsLoadAdjustment"
        @reScheduleProduction="getGanttChartData"
      ></suggestions-load-adjustment>
      <div class="slider-block" v-if="isView">
        <div class="slider-block-text">小时高度:</div>
        <el-slider
          @change="sliderHeightChange"
          style="width: 200px"
          v-model="rowHeight"
          :min="24"
          :max="72"
          :step="12"
          show-stops
        >
        </el-slider>
      </div>
      <div class="slider-block1" v-if="isView">
        <div v-if="isSlider" class="slider-block-text">小时宽度:</div>
        <el-slider
          v-if="isSlider"
          @change="sliderWidthChange"
          style="width: 200px"
          v-model="latticeWidth"
          :min="minWidth"
          :max="maxWidth"
          :step="12"
          show-stops
        >
        </el-slider>
      </div>
      <!-- <div class="slider-block1-btn" v-show="isView">
        <el-button @click="fullScreenFunc" size="mini">
          {{ isFillScreen ? "退出全屏" : "全屏" }}
        </el-button>
      </div> -->
    </el-card>
  </div>
</template>
<script>
import { getGanttChart } from "@/api/ganttChart/ganttChart";
import dayTableView from "./gentterTable.vue";
import schedulingWindow from "./startSchedulingWindow.vue";
import schedulingResultsWindow from "./schedulingResultsWindow.vue";
import suggestionsLoadAdjustment from "./suggestionsLoadAdjustment.vue";
export default {
  name: "dailyScheduling",
  components: {
    dayTableView,
    schedulingWindow,
    schedulingResultsWindow,
    suggestionsLoadAdjustment,
  },
  data() {
    return {
      styleCache: {}, //存放缓存结果
      highlightedClass: null,
      dragging: false,
      startX: 0,
      startY: 0,
      scrollLeft: 0,
      scrollTop: 0,
      ganTeTable: null, // 初始化表格引用
      isFillScreen: false, // 是否全屏
      loading: false, //表格数据处理
      isView: true,
      content: "内容",
      isSlider: true, //是否显示缩放和拉长
      minWidth: 24, //最小缩放
      maxWidth: 72, //最大缩放
      rowHeight: 24, //每一行的高度
      tableWidth: 0,
      pointObj: {
        pointX: 340,
        pointBoxLeft: 0, //指针盒子距离左侧的偏移量
      },
      eleData: {
        dayList: [],
        startTime: "", // 开始时间
        endTime: "", // 结束时间
        workcenterList: [],
      },
      tableHeight: 0, //table的高度
      oneHourPx: 24, //一小时间隔15px 一分钟间隔0.25px
      oneMinutePx: 0.4, //一分钟0.4px
      tableData: null, //表格数据
      latticeWidth: 30, //一个单元格的宽度最小24px
      timeArr: [], //天数集合
      hourArr: [
        "00",
        "01",
        "02",
        "03",
        "04",
        "05",
        "06",
        "07",
        "08",
        "09",
        "10",
        "11",
        "12",
        "13",
        "14",
        "15",
        "16",
        "17",
        "18",
        "19",
        "20",
        "21",
        "22",
        "23",
      ],
      tableKey: 0, //值改变更新table
      earliestTime: "", //最早时间
      latestTime: "", //最晚时间
      conWidth: 0,
      usedKeys: new Set(),
    };
  },
  created() {
    window.onload = function () {
      document.addEventListener("touchstart", function (event) {
        if (event.touches.length > 1) {
          event.preventDefault();
        }
      });
      document.addEventListener("gesturestart", function (event) {
        event.preventDefault();
      });
    };
    //初始化表格高度,和初始化指针数据
    this.$set(this.pointObj, "pointX", 0);
    this.$nextTick(() => {
      this.tableHeight = this.$refs.tableBox.offsetHeight - 110;
    });
  },
  mounted() {
    this.getGanttChartData();
    //禁止ctrl+滚轮缩放
    let scrollFunc = function (e) {
      e = e || window.event;
      if (e.wheelDelta && event.ctrlKey) {
        //IE/Opera/Chrome
        event.returnValue = false;
      } else if (e.detail) {
        //Firefox
        event.returnValue = false;
      }
    };
    /*注册事件*/
    if (document.addEventListener) {
      document.addEventListener("DOMMouseScroll", scrollFunc, false);
    } //W3C
    window.onmousewheel = document.onmousewheel = scrollFunc; //IE/Opera/Chrome/Safari
    //设置表格最大高度沾满全屏
    this.$nextTick(() => {
      this.tableHeight = document.getElementById("boxCard").offsetHeight - 110;
      window.addEventListener("scroll", this.handleScroll, true);
      //获取标针盒子距离浏览器左侧的距离
      //   this.pointObj.pointBoxLeft = document.getElementById("pointBox").getBoundingClientRect().left
      //监听浏览器窗口变化
      const that = this;
      window.onresize = () => {
        return (() => {
          //计算装有指针的盒子距离浏览器左侧的距离,指针减去这个盒子距离浏览器左侧的偏移量得到正确时间指针
          this.pointObj.pointBoxLeft = 0;
          console.log("窗口改变了");
        })();
      };
      //如果日期小于2天 则官渡为39
      if (this.timeArr.length <= 2) {
        this.latticeWidth = 24;
        this.minWidth = 24;
        this.maxWidth = 72;
      }
      // console.log("我被执行了", this.timeArr.length);
      if (this.timeArr.length >= 2) {
        this.latticeWidth = 24;
        this.minWidth = 24;
        this.maxWidth = 72;
      }
      if (this.timeArr.length == 1) {
        this.latticeWidth = 66;
        this.isSlider = false;
      }
      this.widthAA = this.timeArr.length * 24 * this.latticeWidth;
      this.tableWidth = this.widthAA + 240;
    });
    this.ganTeTable = this.$refs.ganTeTable.$el.querySelector(
      ".el-table__body-wrapper"
    );
  },
  computed: {
    // timeInterval() {
    //   return (startTime, endTime,id) => {
    //     console.log("我被执行了", startTime, endTime,id);
    //     let time = new Date(endTime) - new Date(startTime); // 获取任务开始时间和任务结束时间的相差时间戳
    //     let minuteDiff = Math.floor(time / (60 * 1000)); // 相差时间间隔
    //     let initialTime = new Date(startTime) - new Date(this.timeArr[0]); // 获取距离最开始的距离
    //     let inittiDiff = Math.floor(initialTime / (60 * 1000));
    //     let obj = {
    //       widthPx: minuteDiff * (this.latticeWidth / 60),
    //       startPx: inittiDiff * (this.latticeWidth / 60),
    //     };
    //     return "width:" + obj.widthPx + "px;left:" + obj.startPx + "px;";
    //   };
    // },
  },
  methods: {
    timeInterval(startTime, endTime, id) {
      // Check cache first
      const cacheKey = `${startTime}_${endTime}_${id}`;
      if (this.styleCache[cacheKey]) {
        return this.styleCache[cacheKey];
      }

      console.log("我被执行了", startTime, endTime, id);
      let time = new Date(endTime) - new Date(startTime); // 获取任务开始时间和任务结束时间的相差时间戳
      let minuteDiff = Math.floor(time / (60 * 1000)); // 相差时间间隔
      let initialTime = new Date(startTime) - new Date(this.timeArr[0]); // 获取距离最开始的距离
      let inittiDiff = Math.floor(initialTime / (60 * 1000));
      let obj = {
        widthPx: minuteDiff * (this.latticeWidth / 60),
        startPx: inittiDiff * (this.latticeWidth / 60),
      };

      const style = `width:${obj.widthPx}px;left:${obj.startPx}px;`;
      // Store in cache
      this.styleCache[cacheKey] = style;

      return style;
    },
    generateRandomKey() {
      let key;
      do {
        key = Math.random().toString(36).substr(2, 9); // Generate a random string key
      } while (this.usedKeys.has(key)); // Ensure key is unique

      this.usedKeys.add(key); // Add key to usedKeys set
      return key;
    },
    // 负荷调整建议
    proposalFun() {
      this.$refs.suggestionsLoadAdjustment.open();
    },
    // 开始排产弹窗
    openSchedulingResultsWindow() {
      this.showDialogVisible = false;
      this.$refs.schedulingResultsWindow.open();
    },
    highlightSimilarElements(targetClass) {
      // 先移除所有元素的高亮状态
      if (this.highlightedClass) {
        document.querySelectorAll(`.${this.highlightedClass}`).forEach((el) => {
          el.classList.remove("highlighted");
        });
      }

      // 更新当前要高亮的类名
      this.highlightedClass = targetClass;

      // 查找所有具有目标类名的元素并应用高亮
      document.querySelectorAll(`.${targetClass}`).forEach((el) => {
        el.classList.add("highlighted");
      });
    },
    // 开始排程的英文
    startSchedulingProductionFun() {
      this.$refs.schedulingWindow.showDialogVisible = true;
    },
    // 当鼠标按下时触发,记录起始位置和滚动条位置。
    startDrag(e) {
      this.dragging = true;
      this.startX = e.pageX;
      this.startY = e.pageY;
      this.scrollLeft = this.ganTeTable.scrollLeft;
      this.scrollTop = this.ganTeTable.scrollTop;
    },

    // 当鼠标移动时触发,计算鼠标移动距离并更新滚动条位置。
    handleDrag: _.throttle(function (e) {
      if (this.dragging) {
        const dx = e.pageX - this.startX;
        const dy = e.pageY - this.startY;
        this.ganTeTable.scrollLeft = this.scrollLeft - dx;
        this.ganTeTable.scrollTop = this.scrollTop - dy;
      }
    }, 16), // 使用节流函数,16ms对应60fps的更新频率

    // 鼠标松开,移出
    endDrag() {
      this.dragging = false;
    },

    //全屏退出全屏
    fullScreenFunc() {
      if (!document.fullscreenElement) {
        this.enterFullScreen();
        this.isFillScreen = true;
        this.latticeWidth = 72;
        this.sliderWidthChange();
      } else {
        this.exitFullScreen();
        this.latticeWidth = 39;
        this.sliderWidthChange();
        this.isFillScreen = false;
      }
    },
    //进入全屏
    enterFullScreen() {
      let element = document.documentElement;
      if (element.requestFullscreen) {
        element.requestFullscreen();
      } else if (element.mozRequestFullScreen) {
        /* Firefox */
        element.mozRequestFullScreen();
      } else if (element.webkitRequestFullscreen) {
        /* Chrome, Safari & Opera */
        element.webkitRequestFullscreen();
      } else if (element.msRequestFullscreen) {
        /* IE/Edge */
        element.msRequestFullscreen();
      }
    },
    //退出全屏
    exitFullScreen() {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.mozCancelFullScreen) {
        /* Firefox */
        document.mozCancelFullScreen();
      } else if (document.webkitExitFullscreen) {
        /* Chrome, Safari and Opera */
        document.webkitExitFullscreen();
      } else if (document.msExitFullscreen) {
        /* IE/Edge */
        document.msExitFullscreen();
      }
      this.isFillScreen = false;
    },
    async getGanttChartData() {
      this.loading = true;
      console.log("开始");
      //判断是否传递过来id
      let id = null;
      if (typeof this.$route.query.id !== "undefined") {
        id = JSON.parse(this.$route.query.id);
      }
      let repos = null;
      await getGanttChart()
        .then((res) => {
          repos = res;
          this.processGanttData(repos);
          this.loading = false;
        })
        .catch((error) => {
          // 请求失败的处理
          console.error("请求数据失败:", error);
          this.loading = false; // 可选:设置加载状态为false
          // 可以进行错误处理或者用户提示
        });
    },
    processGanttData(repos) {
      // 在获取到数据后进行处理
      this.timeArr = repos.data.dayList.map((element) => element + " 00:00:00");
      this.eleData.workcenterList = repos.data.workcenterList;
      this.treeToTableData();
      for (let i = 0; i < this.tableData.length; i++) {
        for (let j = 0; j < this.tableData[i].workPlanList.data.length; j++) {
          this.tableData[i].workPlanList.data[j].onlyId =
            this.generateRandomKey();
          // this.tableData[i].workPlanList.data[j].pxObj={...this.timeInterval(this.tableData[i].workPlanList.data[j].startTime,this.tableData[i].workPlanList.data[j].endTime)}
        }
      }
      // 根据时间长度设置 latticeWidth
      if (this.timeArr.length <= 2) {
        this.latticeWidth = 24;
        this.minWidth = 24;
        this.maxWidth = 72;
      } else if (this.timeArr.length >= 3) {
        this.latticeWidth = 21;
        this.minWidth = 21;
        this.maxWidth = 72;
      } else if (this.timeArr.length == 1) {
        this.latticeWidth = 66;
        this.minWidth = 66;
        this.maxWidth = 66;
        this.isSlider = false;
      }
      // 计算表格宽度
      this.widthAA = this.timeArr.length * 24 * this.latticeWidth;
      this.tableWidth = this.widthAA + 240;
      // 更新表格布局
      this.$nextTick(() => {
        if (this.$refs.ganTeTable) {
          this.$refs.ganTeTable.doLayout();
        }
        this.$forceUpdate();
      });
    },
    //切换视图
    switchView() {
      this.isView = !this.isView;
      if (this.isView === true) {
        this.getGanttChartData();
      }
    },
    //物料信息展开
    //行高回调
    iCellStyle() {
      return "height:" + this.rowHeight + "px";
    },
    //改变行高
    sliderHeightChange() {
      //重新布局表格
      this.$nextTick(() => {
        this.styleCache = {};
        this.iCellStyle();
        this.$refs.ganTeTable.doLayout();
        // this.tableKey = Math.random();
      });
    },
    //改变行宽
    sliderWidthChange() {
      //重新布局表格
      this.$nextTick(() => {
        this.styleCache = {};
        this.widthAA = this.timeArr.length * 24 * this.latticeWidth;
        this.tableWidth = this.widthAA + 240;
        this.$refs.ganTeTable.doLayout();
        // this.tableKey = Math.random();
      });
    },
    // 当鼠标移动时触发
    updateXY(e) {
      let x = e.clientX;
      //计算装有指针的盒子距离浏览器左侧的距离,指针减去这个盒子距离浏览器左侧的偏移量得到正确时间指针
      this.pointObj.pointBoxLeft = document
        .getElementById("pointBox")
        .getBoundingClientRect().left;
      this.$nextTick(() => {
        this.boble = false;
        document.querySelector(
          "#pointBox"
        ).innerHTML = `<div  style="width: 1px; height: 225px; position: absolute; background: red;top:-18px; left:${
          x - this.pointObj.pointBoxLeft
        }px;" id="head-pointer" class="head-pointer"> </div>`;
      });
      this.boble = false;
    },
    parentW(index1, index2) {
      if (this.$refs[index1 + "-" + index2 + 5]) {
        // console.log(this.$refs[index1 + "-" + index2 + 5][0].clientWidth);
        return this.$refs[index1 + "-" + index2 + 5][0].clientWidth;
      } else {
        return 0;
      }
    },
    parentH(index1, index2) {
      if (this.$refs[index1 + "-" + index2 + 5]) {
        // console.log(this.$refs[index1 + "-" + index2 + 5][0].clientHeight);
        return this.$refs[index1 + "-" + index2 + 5][0].clientHeight;
      } else {
        return 0;
      }
    },
    draggableStart() {
      // console.log(this.tableData[0].workPlanList.data);
    },
    draggableEnd() {
      // console.log(this.tableData[0].workPlanList.data);
    },
    /**
     * 计算两个时间的间隔
     * 入参 开始时间,结束时间
     * 回参 返回一个任务距离最开始时间的分钟[距离],和一个任务开始时间和结束时间的分钟[距离],
     */
    // timeInterval(startTime, endTiem) {
    //   console.log("我被执行了",startTime, endTiem)
    //   let time = new Date(endTiem) - new Date(startTime); //获取任务开始时间和任务结束时间的相差时间戳
    //   let minuteDiff = Math.floor(time / (60 * 1000)); //相差时间间隔
    //   let initialTime = new Date(startTime) - new Date(this.timeArr[0]); //获取距离最开始的距离

    //   // ,new Date(startTime),new Date(this.timeArr[0])
    //   // console.log("~~~~~~~~~~~", this.timeArr[0])
    //   let inittiDiff = Math.floor(initialTime / (60 * 1000));
    //   // console.log("latticeWidth",inittiDiff)
    //   return {
    //     widthPx: minuteDiff * (this.latticeWidth / 60),
    //     startPx: inittiDiff * (this.latticeWidth / 60),
    //   };
    // },
    treeToTableData() {
      // console.log("this.eleData.workcenterList", this.eleData.workcenterList);
      //将树状结构格式转换成二维数组表格形式
      let ewArr = this.parseTreeToRow(this.eleData.workcenterList);
      let tableData = [];
      ewArr.map((item) => {
        let obj = {};
        item.map((itemc, indexb) => {
          obj["index" + (indexb + 1)] = {
            id: itemc.id,
            label: itemc.label,
          };
          if (typeof itemc.workPlanList !== "undefined") {
            // for(let i=0;i<itemc.workPlanList.length;i++){
            //   itemc.workPlanList[i].pxObj = null;
            //   itemc.workPlanList[i].pxObj = this.timeInterval(itemc.workPlanList[i].startTime,itemc.workPlanList[i].endTime)
            // }
            obj.workPlanList = { data: itemc.workPlanList };
          }
        });
        tableData.push(obj);
      });
      this.tableData = tableData;
    },
    /**
     * 递归-----将树结构数据格式,转化为,二维数组 表格形式
     * @param node 树的源数据
     * @param data 树转化为二维数组的数据
     * @param row 临时存储数据
     * @returns {*[]}
     */
    parseTreeToRow(node, data = [], row = []) {
      console.log("parseTreeToRow执行中");
      node.map((item) => {
        let obj = {
          id: item.workCenterId || item.lineId || item.machineId,
          label: item.workCenterName || item.lineName || item.machineDescribe,
        };
        if (typeof item.workPlanList !== "undefined") {
          obj.workPlanList =
            item.workPlanList.length > 0 ? item.workPlanList : [];
        }
        if (item.children && item.children.length != 0) {
          this.parseTreeToRow(item.children, data, [...row, obj]);
        } else {
          data.push([...row, obj]);
        }
      });
      return data;
    },
    /**
     * 合并行或列的计算方法
     */
    tableSpanMethod({ row, column, rowIndex, columnIndex }) {
      // console.log("row, column, rowIndex, columnIndex");
      // console.log(
      //   "row, column, rowIndex, columnIndex",
      //   columnIndex,
      //   row,
      //   column,
      //   rowIndex,
      //   columnIndex
      // );
      return {
        rowspan:
          columnIndex < 3
            ? this.mergeRows(
                row[column.property],
                this.tableData,
                rowIndex,
                column.property
              )
            : 1,
        colspan: 1,
      };
    },
    /**
     * 表格单元格合并-----行
     * @param {Object} value      当前单元格的值
     * @param {Object} data       当前表格所有数据
     * @param {Object} index      当前单元格的值所在 行 索引
     * @param {Object} property   当前列的property
     * @returns {number}          待合并单元格数量
     */
    mergeRows(value, data, index, property) {
      // 判断 当前行的该列数据 与 上一行的该列数据 是否相等
      if (index !== 0 && value.label === data[index - 1][property].label) {
        // 返回 0 使表格被跨 行 的那个单元格不会渲染
        return 0;
      }
      // 判断 当前行的该列数据 与 下一行的该列数据 是否相等
      let rowSpan = 1;
      for (let i = index + 1; i < data.length; i++) {
        if (value.label !== data[i][property].label) {
          break;
        }
        rowSpan++;
      }
      return rowSpan;
    },
  },
};
</script>
<style>
.highlighted {
  box-shadow: inset 0 0 0 3px yellow !important; /* 内置阴影,用作边框 */
}
</style>
<style lang="less" scoped>
.hour-item span {
  position: relative;
  bottom: -9px;
}
.hour-ten-side-box {
  width: 100%;
  height: 10px;
  position: relative;
  bottom: -6px;
  .hour-ten-side-box-left {
    width: 1px;
    height: 14px;
    background: #263c59;
    position: relative;
    left: -1px;
    float: left;
  }
  .hour-ten-side-box-right {
    width: 1px;
    height: 14px;
    background: #263c59;
    position: relative;
    right: -1px;
    float: right;
  }
}
.hour-ten-scale-box {
  width: 100%;
  display: flex;
  justify-content: space-evenly;
  position: relative;
  bottom: -16px;
}
.hour-ten-scale {
  height: 5px;
  width: 1px;
  background: #263c59;
}
#pointBox {
  position: relative;
  z-index: 2 !important;
}
.aaaaa {
  width: 20px;
  background: red;
  height: 25px;
  position: relative;
}
//表头指针
.head-pointer {
  width: 1px;
  height: 18px;
  position: absolute;
  background: red;
  z-index: 2 !important;
}
//表头清楚内容
/deep/ .el-table th.el-table__cell {
  overflow: visible !important;
}
//占满屏幕
.box-card {
  height: calc(100vh - 100px); /*示例中顶部区域固定高度190px*/
}
/deep/ .el-table--enable-row-transition .el-table__body td.el-table__cell {
  //   height: 47px;
}
/deep/ .el-table_1_column_1 .el-table_1_column_2 .el-table_1_column_3 {
  z-index: 300 !important;
}
/deep/ .el-table_1_column_4_column_5_column_6 > .cell {
  // width: 3120px !important;
  padding: 0;
}
.content-box {
  // width: 2000px !important;
  z-index: 2 !important;
  text-align: left;
  position: absolute;
  top: 0;
  bottom: 0;
}
.AAA {
  // left: -10px;
  // height: 30px;
  position: relative;
  width: 15px;
  height: 100%;
  z-index: 2 !important;
}
/deep/ .el-table_1_column_4_column_5_column_6 .is-center .el-table__cell {
  // width: 3060px !important;
  display: flex !important;
  // z-index: 1 !important;
}
//去除鼠标移入
/deep/ .group > .el-table--enable-row-hover .el-table__body tr:hover > td {
  background-color: white !important;
  height: 100%;
}
/deep/
  .group
  > .el-table--enable-row-hover
  .el-table__body
  tr:hover
  > td
  > div {
  height: 100%;
}
/deep/ .el-table .cell {
  overflow: visible !important;
  padding-left: 0px !important;
  display: flex; //横向排列
  padding-right: 0px !important;
  width: 100%;
  text-align: center;
}
/deep/ .el-table--mini .el-table__cell {
  // z-index: 1 !important;
  padding: 0 !important;
}
::v-deep .el-table th.el-table__cell > .cell {
  display: contents;
  line-height: 15px;
}
.timeItemBox {
  display: flex;
  width: 500px;
  margin-left: -10px;
  z-index: 1;
  z-index: 200 !important;
}
.timeItem {
  height: 37.9px;
  width: 30px;
}
.wl-real-start {
  left: 50%;
  &:after {
    position: absolute;
    top: 0;
    // left: -5px;
    left: 0;
    z-index: 1;
    content: "";
    width: 8px;
    height: 36px;
    // border-radius: 50%;
    background: #fcc300;
  }
}
.wl-real-start1 {
  left: 50%;
  &:after {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 200 !important;
    content: "";
  }
}
//伸缩加长
.slider-block {
  margin-top: 5px;
  margin-left: 20px;
  float: right;
  position: fixed;
  z-index: 10002;
  bottom: 0;
  right: 20px;
  display: flex;
  line-height: 33px;
  .slider-block-text {
    margin-right: 5px;
    font-size: 16px;
  }
}
.slider-block1 {
  margin-top: 5px;
  margin-left: 20px;
  z-index: 10002;
  float: right;
  position: fixed;
  bottom: 0;
  right: 344px;
  display: flex;
  line-height: 33px;
  .slider-block-text {
    margin-right: 5px;
    font-size: 16px;
  }
}
.slider-block1-btn {
  margin-top: 5px;
  margin-left: 20px;
  z-index: 10002;
  float: right;
  position: fixed;
  display: flex;
  line-height: 33px;
  bottom: 9px;
  right: 639px;
}
//超过一行显示
.oneLineCls {
  text-overflow: -o-ellipsis-lastline;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  -webkit-box-orient: vertical;
}
.twoLineCls {
  text-overflow: -o-ellipsis-lastline;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
}
.ganteTable {
  margin-top: 20px;
}
.minute-scale {
  position: absolute;
  z-index: 2 !important;
}
/* 在你的全局样式或组件的<style>标签内 */
.fullscreen-table {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  margin: 0 auto;
  z-index: 1002;
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618
  • 619
  • 620
  • 621
  • 622
  • 623
  • 624
  • 625
  • 626
  • 627
  • 628
  • 629
  • 630
  • 631
  • 632
  • 633
  • 634
  • 635
  • 636
  • 637
  • 638
  • 639
  • 640
  • 641
  • 642
  • 643
  • 644
  • 645
  • 646
  • 647
  • 648
  • 649
  • 650
  • 651
  • 652
  • 653
  • 654
  • 655
  • 656
  • 657
  • 658
  • 659
  • 660
  • 661
  • 662
  • 663
  • 664
  • 665
  • 666
  • 667
  • 668
  • 669
  • 670
  • 671
  • 672
  • 673
  • 674
  • 675
  • 676
  • 677
  • 678
  • 679
  • 680
  • 681
  • 682
  • 683
  • 684
  • 685
  • 686
  • 687
  • 688
  • 689
  • 690
  • 691
  • 692
  • 693
  • 694
  • 695
  • 696
  • 697
  • 698
  • 699
  • 700
  • 701
  • 702
  • 703
  • 704
  • 705
  • 706
  • 707
  • 708
  • 709
  • 710
  • 711
  • 712
  • 713
  • 714
  • 715
  • 716
  • 717
  • 718
  • 719
  • 720
  • 721
  • 722
  • 723
  • 724
  • 725
  • 726
  • 727
  • 728
  • 729
  • 730
  • 731
  • 732
  • 733
  • 734
  • 735
  • 736
  • 737
  • 738
  • 739
  • 740
  • 741
  • 742
  • 743
  • 744
  • 745
  • 746
  • 747
  • 748
  • 749
  • 750
  • 751
  • 752
  • 753
  • 754
  • 755
  • 756
  • 757
  • 758
  • 759
  • 760
  • 761
  • 762
  • 763
  • 764
  • 765
  • 766
  • 767
  • 768
  • 769
  • 770
  • 771
  • 772
  • 773
  • 774
  • 775
  • 776
  • 777
  • 778
  • 779
  • 780
  • 781
  • 782
  • 783
  • 784
  • 785
  • 786
  • 787
  • 788
  • 789
  • 790
  • 791
  • 792
  • 793
  • 794
  • 795
  • 796
  • 797
  • 798
  • 799
  • 800
  • 801
  • 802
  • 803
  • 804
  • 805
  • 806
  • 807
  • 808
  • 809
  • 810
  • 811
  • 812
  • 813
  • 814
  • 815
  • 816
  • 817
  • 818
  • 819
  • 820
  • 821
  • 822
  • 823
  • 824
  • 825
  • 826
  • 827
  • 828
  • 829
  • 830
  • 831
  • 832
  • 833
  • 834
  • 835
  • 836
  • 837
  • 838
  • 839
  • 840
  • 841
  • 842
  • 843
  • 844
  • 845
  • 846
  • 847
  • 848
  • 849
  • 850
  • 851
  • 852
  • 853
  • 854
  • 855
  • 856
  • 857
  • 858
  • 859
  • 860
  • 861
  • 862
  • 863
  • 864
  • 865
  • 866
  • 867
  • 868
  • 869
  • 870
  • 871
  • 872
  • 873
  • 874
  • 875
  • 876
  • 877
  • 878
  • 879
  • 880
  • 881
  • 882
  • 883
  • 884
  • 885
  • 886
  • 887
  • 888
  • 889
  • 890
  • 891
  • 892
  • 893
  • 894
  • 895
  • 896
  • 897
  • 898
  • 899
  • 900
  • 901
  • 902
  • 903
  • 904
  • 905
  • 906
  • 907
  • 908
  • 909
  • 910
  • 911
  • 912
  • 913
  • 914
  • 915
  • 916
  • 917
  • 918
  • 919
  • 920
  • 921
  • 922
  • 923
  • 924
  • 925
  • 926
  • 927
  • 928
  • 929
  • 930
  • 931
  • 932
  • 933
  • 934
  • 935
  • 936
  • 937
  • 938
  • 939
  • 940
  • 941
  • 942
  • 943
  • 944
  • 945
  • 946
  • 947
  • 948
  • 949
  • 950
  • 951
  • 952
  • 953
  • 954
  • 955
  • 956
  • 957
  • 958
  • 959
  • 960
  • 961
  • 962
  • 963
  • 964
  • 965
  • 966
  • 967
  • 968
  • 969
  • 970
  • 971
  • 972
  • 973
  • 974
  • 975
  • 976
  • 977
  • 978
  • 979
  • 980
  • 981
  • 982
  • 983
  • 984
  • 985
  • 986
  • 987
  • 988
  • 989
  • 990
  • 991
  • 992
  • 993
  • 994
  • 995
  • 996
  • 997
  • 998
  • 999
  • 1000
  • 1001
  • 1002
  • 1003
  • 1004
  • 1005
  • 1006
  • 1007
  • 1008
  • 1009
  • 1010
  • 1011
  • 1012
  • 1013
  • 1014
  • 1015
  • 1016
  • 1017
  • 1018
  • 1019
  • 1020
  • 1021
  • 1022
  • 1023
  • 1024
  • 1025
  • 1026
  • 1027
  • 1028
  • 1029
  • 1030
  • 1031
  • 1032
  • 1033
  • 1034
  • 1035
  • 1036
  • 1037
  • 1038
  • 1039
  • 1040
  • 1041
  • 1042
  • 1043
  • 1044
  • 1045
  • 1046
  • 1047
  • 1048
  • 1049
  • 1050
  • 1051
  • 1052
  • 1053
  • 1054
  • 1055
  • 1056
  • 1057
  • 1058
  • 1059
  • 1060
  • 1061
  • 1062
  • 1063
  • 1064
  • 1065
  • 1066
  • 1067
  • 1068
  • 1069
  • 1070
  • 1071
  • 1072
  • 1073
  • 1074
  • 1075
  • 1076
  • 1077
  • 1078
  • 1079
  • 1080
  • 1081
  • 1082
  • 1083
  • 1084
  • 1085
  • 1086
  • 1087
  • 1088
  • 1089
  • 1090
  • 1091
  • 1092
  • 1093
  • 1094
  • 1095
  • 1096
  • 1097
  • 1098
  • 1099
  • 1100
  • 1101
  • 1102
  • 1103
  • 1104
  • 1105
  • 1106
  • 1107
  • 1108
  • 1109
  • 1110
  • 1111
  • 1112
  • 1113
  • 1114
  • 1115
  • 1116
  • 1117
  • 1118
  • 1119
  • 1120
  • 1121
  • 1122
  • 1123
  • 1124
  • 1125
  • 1126
  • 1127
  • 1128
  • 1129
  • 1130
  • 1131
  • 1132
  • 1133
  • 1134
  • 1135
  • 1136
  • 1137
  • 1138
  • 1139
  • 1140
  • 1141
  • 1142
  • 1143
  • 1144
  • 1145
  • 1146
  • 1147
  • 1148
  • 1149
  • 1150
  • 1151
  • 1152
  • 1153
  • 1154
  • 1155
  • 1156
  • 1157
  • 1158
  • 1159
  • 1160
  • 1161
  • 1162
  • 1163
  • 1164
  • 1165
  • 1166
  • 1167
  • 1168
  • 1169
  • 1170
  • 1171
  • 1172
  • 1173
  • 1174
  • 1175
  • 1176
  • 1177
  • 1178
  • 1179
  • 1180
  • 1181
  • 1182
  • 1183
  • 1184
  • 1185
  • 1186
  • 1187
  • 1188
  • 1189
  • 1190
  • 1191
  • 1192
  • 1193
  • 1194
  • 1195
  • 1196
  • 1197
  • 1198
  • 1199
  • 1200
  • 1201
  • 1202
  • 1203
  • 1204
  • 1205
  • 1206
  • 1207
  • 1208
  • 1209
  • 1210
  • 1211
  • 1212
  • 1213
  • 1214
  • 1215
  • 1216
  • 1217
  • 1218
  • 1219
  • 1220
  • 1221
  • 1222
  • 1223
  • 1224
  • 1225
  • 1226
  • 1227
  • 1228
  • 1229
  • 1230
  • 1231
  • 1232
  • 1233
  • 1234
  • 1235
  • 1236
  • 1237
  • 1238
  • 1239
  • 1240
  • 1241
  • 1242
  • 1243
  • 1244
  • 1245
  • 1246
  • 1247
  • 1248
  • 1249
  • 1250
  • 1251
  • 1252
  • 1253
  • 1254
  • 1255
  • 1256
  • 1257
  • 1258
  • 1259
  • 1260
  • 1261
  • 1262
  • 1263
  • 1264
  • 1265
  • 1266
  • 1267
  • 1268
  • 1269
  • 1270
  • 1271
  • 1272
  • 1273
  • 1274
  • 1275
  • 1276
  • 1277
  • 1278
  • 1279
  • 1280
  • 1281
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号