<template>
  <div class="app-container">
    
    <div class="u-gantt-container u-flex">
      <div>
        <el-table
          :data="tableData" 
          stripe
          :cell-class-name="tableCellClassName"
          :header-cell-class-name="tableCellClassName"
          row-key="id"
          default-expand-all
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          @expand-change="expandChange"
          :row-style="{ height: uStyle.ganttHeight + 'px' }"
          :header-row-style="{ height: uStyle.ganttHeight + 'px' }"
          @cell-click="cellClick"
          @row-dblclick="rowDblclick"
          >
          <template v-for="(item, index) in configColumns">
            <el-table-column
              v-if="item.name !== 'add'"
              :prop="item.name"
              :label="item.label"
              :width="item.width"
              :align="item.align"
              :key="index"
              show-overflow-tooltip
              >
            </el-table-column>
            <el-table-column
              v-if="item.name === 'add'"
              :prop="item.name"
              :label="item.label"
              :align="item.align"
              :width="item.width"
              :key="index"
              >
              <template slot-scope="scope">
                <!-- <i class="el-icon-plus" v-if="!scope.row.pid" @click="addRow(scope.row, scope.$index)"></i> -->
                <span v-if="!scope.row.pid" @click="addRow(scope.row, scope.$index)" class="add-btn">＋</span>
              </template>
            </el-table-column>
            <!-- :fixed="item.fixed" -->
          </template>
        </el-table>
      </div>
      <!-- <div class="u-gantt-area" ref="uGantt"> -->
      
      <div class="u-gantt" ref="uGantt">
        <div class="u-gantt-title u-flex" >
          <div v-for="(item, index) in uGanttColumns" :key="index" class="item-title" :style="{'height': uStyle.ganttHeight + 'px', 'lineHeight': uStyle.ganttHeight + 'px'}">{{ item.label}}</div>
        </div>
        <div class="u-gantt-content">
          <div class="u-gantt-bg">
            <div v-for="(item, tr) in ganttLists" :key="tr" class="item-tr u-flex" :style="{'height': uStyle.ganttHeight + 'px'}">
              <!--  :style="{'display': item.show}" -->
              <div class="item-td" v-for="(item, td) in uGanttColumns" :key="td"></div>
            </div>
          </div>
          <div class="u-gantt-task">
            <div class="u-gantt-task-content" v-for="(item, index) in ganttLists" :key="index">
              <!-- <span class="resize" ref="`resize${index}}`" @mousedown="dragControllerDiv(index)"></span> -->
              <!-- 计划 -->
              <div class="u-gantt-plan" ref="uGanttTaskItem" :style="setPlanStyle(item)">
                <div class="u-gantt-task-drag" ref="uGanttDrag"></div>
                <div class="u-gantt-task-resize resize-left" ref="uGanttResizeL"></div>
                <div class="u-gantt-task-text">{{ item.task_text }}</div>
                <div class="u-gantt-task-resize resize-right" ref="uGanttResizeR"></div>
              </div>
              <!-- 实际 -->
              <div v-if="hasReality" class="u-gantt-reality" :style="setRealityStyle(item)"></div>

            </div>
          </div>
        </div>
      </div>
      <!-- </div> -->
    </div>

    <!-- 自定义内容：弹窗 -->
    <slot/>

  </div>
</template>

<script>
  export default {
    props: {
      configColumns: {
        type: Array,
        default: []
      },
      taskLists: {
        type: Array,
        default: []
      },
      uStyle: {
        type: Object,
        default: () => ({
          ganttHeight: 40, // 一行的高度（整体一行的）
          planHeight: 26, // 计划甘特条的高度
          planBg: '#44c2e5', // 计划甘特条的颜色
          realityHeight: 10, // 实际甘特条的高度
          realityBgIncomplete: '#ffaf58', // 实际甘特条进行中的颜色
          realityBgCompleted: '#9BDF90', // 实际甘特条已完成的颜色
          // #e5de44
          top: 4, // 甘特条离上线条距离
        })
      },
      hasReality: {
        type: Boolean,
        default: false
      }
    },
    data(){
      return {
        // 甘特图部分时间表头
        uGanttColumns: [],
        // 表格使用数据
        tableData: [],
        // 甘特图显示的
        ganttLists: [],
        
      }
    },
    watch: {
      taskLists: {
        handler(newValue, oldValue){
          console.log(newValue, oldValue)
          if(newValue.length > 0){
            
            newValue.forEach(res=>{
              if(!res.end_date){
                res.end_date = res.start_date
              }
            })
            console.log(newValue)
            this.changeTableTree()

            this.getStartEndTime()
            this.$nextTick(() => {
              this.uGanttDrag()
              this.uGanttResizeL()
              this.uGanttResizeR()
            })
            // this.$forceUpdate()
          } else {
            console.log(this.setDefaultDate())
            this.uGanttColumns = this.setDefaultDate()
          }
        },
        immediate: true,
        // deep: true
      }
    },
    created (){
      // this.changeTableTree()
      // this.getStartEndTime()
    },
    mounted () {
      // this.uGanttDrag()
      // this.uGanttResizeL()
      // this.uGanttResizeR()
    },
    methods: {
      // 没有数据时设置默认当月日期
      setDefaultDate() {
        // 获取标准时间
        var nowdays = new Date()
        // 获取当年
        var currentYear = new Date().getFullYear()
        // 获取当月
        var currentMonth = new Date().getMonth() + 1
        // 获取当天
        var nowDay = new Date().getDate()
        // 获取当前月有多少天
        var currentMonthNum = new Date(currentYear, currentMonth, 0).getDate()
        // console.log(nowDay, currentMonth, currentMonthNum)
        // 
        // let now = new Date(nowDay)
        // console.log(nowdays, now)
        // 当前月份所有日期集合
        let currentMonthArr = []
        for (let i = 1; i <= currentMonthNum; i++) {
          // let day = nowdays.setDate(i);
          // console.log(day)
          // 年月日(yyyy-MM-dd)
          let dateLabel = (currentMonth < 10 ? '0' + currentMonth : currentMonth) + "月" + (i < 10 ? '0' + i : i) + "日";
          let dateName = currentYear + "-" + (currentMonth < 10 ? '0' + currentMonth : currentMonth) + "-" + (i < 10 ? '0' + i : i);
          // let day = 
          currentMonthArr.push({label: dateLabel, name: dateName});
        }
        console.log(currentMonthArr)
        return currentMonthArr
      },
      // 获取最开始和最末尾时间
      getStartEndTime(){
        // 开始日期（实际和计划都）排序选择最开始的一天
        // var hasSjStartArr = this.taskLists.filter(res=> res.reality_startDate) // 因为计划开始日期一定有，所以就不判断了
        var allStartDataArr = []
        this.taskLists.forEach(res=>{
          // console.log(res.reality_startDate)
          if(res.reality_startDate){allStartDataArr.push(res.reality_startDate)}
          allStartDataArr.push(res.start_date)
        })
        // 从小到大排序
        allStartDataArr.sort(function(a, b) {
          return new Date(a) - new Date(b)
        })
        // console.log(allStartDataArr)

        // 结束日期（实际和计划都）排序选择最后的一天
        var allEndDataArr = []
        this.taskLists.forEach(res=>{
          allEndDataArr.push(res.reality_endDate)
          allEndDataArr.push(res.end_date)
        })
        // 从大到小排序
        allEndDataArr.sort(function(a, b) {
          return new Date(b) - new Date(a)
        })
        // console.log(allEndDataArr)

        // 获取最开始和最结束时间
        const start_date = allStartDataArr[0]
        const end_date = allEndDataArr[0]
        // const end_date = setTimeData[setTimeData.length - 1].end_date

        // 判断两个日期之间多少天--bug：少一天
        var betweenDays = (new Date(end_date).getTime() - new Date(start_date).getTime()) / (1000 * 60 * 60 * 24)
        // console.log(betweenDays)
        var final_date = betweenDays > 30 ? 2 : (30 - betweenDays)

        // 最前面往前一天，最后面往后两天
        var addStart = this.addDate(start_date, -1)
        var addEnd = this.addDate(end_date, final_date)

        this.uGanttColumns = this.getBetweenDate(addStart, addEnd)
      },
      /**
       * 计算某个日期几天后的日期
       * @param {*} date 相加前的时间
       * @param {*} days 需要相加的天数
       */
      addDate(date, days) {
        var date = new Date(date);
        date.setDate(date.getDate() + days);
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        var day = date.getDate();
        var mm = "'" + month + "'";
        var dd = "'" + day + "'";
        if(mm.length == 3) {
          month = "0" + month;
        }
        if(dd.length == 3) {
          day = "0" + day;
        }
        var time = year + "-" + month + "-" + day
        return time;
      },
      /** 获取两个日期之间的间隔日期
       * @param { Date | number | string } startTime 开始时间 标准时间格式 时间戳格式 字符串格式(2008-08-08,2008-8-8,2008-08-8,2008-8-08)
       * @param { Date | number | string } endTime 结束时间 标准时间格式 时间戳格式 字符串格式(2008-08-08,2008-8-8,2008-08-8,2008-8-08)
       *  */
      getBetweenDate(startTime, endTime){
        // 校验时间格式
        if (typeof startTime === 'string') {
          const reg = /^\d{4}-(0?[1-9]|1[0-2])-((0?[1-9])|((1|2)[0-9])|30|31)$/g
          if (!reg.test(startTime)) throw `开始时间：${startTime}时间格式错误`
        }
        if (typeof endTime === 'string') {
          const reg = /^\d{4}-(0?[1-9]|1[0-2])-((0?[1-9])|((1|2)[0-9])|30|31)$/g
          if (!reg.test(endTime)) throw `结束时间：${endTime}时间格式错误`
        }
        let start = new Date(startTime)
        let end = new Date(endTime)
        const resultTime = []
        // 当 开始时间小于结束时间的时候进入循环
        while (start <= end) {
          let getDay = start.getDate()
          // 月份需要加 1
          let getMonth = start.getMonth() + 1
          let getYear = start.getFullYear()
          /**
           * 拼接时间格式
           * (getMonth >= 10 ? `${getMonth}` : `0${getMonth}`) 自动给 小于10的时间前面补0
           */
          let setTime =
              `${getYear}-` +
              (getMonth >= 10 ? `${getMonth}` : `0${getMonth}`) +
              '-' +
              (getDay >= 10 ? `${getDay}` : `0${getDay}`)
          let dateLabel = (getMonth < 10 ? '0' + getMonth : getMonth) + "月" + (getDay < 10 ? '0' + getDay : getDay) + "日";
          resultTime.push({label: dateLabel, name: setTime})
          /**
           * 重新设置开始时间
           * 使用 setFullYear() 方法会自动将时间累加，返回的是时间戳格式
           * 使用 new Date() 将时间重新设置为标准时间
           * getMonth - 1 将月份时间重新还原
           */
          start = new Date(start.setFullYear(getYear, getMonth - 1, getDay + 1))
        }
        return resultTime
      },
      // 将一维数组改成多维数组
      changeTableTree(){
        // console.log(this.taskLists)
        this.tableData = this.changeDataTree(this.taskLists, 'id', 'pid')
        // this.tableData = this.handleTree(this.taskLists, 'id', "pid")
        // console.log(this.tableData)
        this.ganttLists = []
        this.changeTaskSort(this.tableData)
      },
      // 将一维数组转成table使用的二维数组(时间问题没改成多维)
      changeDataTree(Array, id, pid){
        let data = JSON.parse(JSON.stringify(Array));
        data.forEach(item => {
          console.log(item[pid])
          if(item[pid]){
            // 有父级的情况
            var index = data.findIndex(res => res[id] === item[pid])
            data[index].children = data[index].children || []
            data[index].children.push(item)
          } else {
            item.children = item.children || undefined;
          }
        })
        console.log(data)
        return data.filter(res => !res[pid])
      },
      // 将组好的多维数组转成一维数组--是为了左右对应
      changeTaskSort(arr){
        for(var i = 0; i < arr.length; i++){
          // arr[i].show = 'flex'
          if(Array.isArray(arr[i].children)){
            this.ganttLists.push(arr[i]);
            this.changeTaskSort(arr[i].children);
          }else{
            this.ganttLists.push(arr[i]);
          }
        }
      },
      // 绘制计划甘特条
      setPlanStyle(item){
        var startIndex = this.uGanttColumns.findIndex(res => res.name === item.start_date)
        var endIndex = this.uGanttColumns.findIndex(res => res.name === item.end_date)
        if(endIndex !== -1){
          var trIndex = this.ganttLists.findIndex(res => res.id === item.id)
          // console.log(trIndex, this.ganttLists)
          var style = {
            left: 70 * startIndex + 'px',
            width: 70 * (endIndex - startIndex + 1) + 'px',
            top: (this.uStyle.ganttHeight * trIndex + this.uStyle.top) + 'px',
            height: this.uStyle.planHeight + 'px',
            lineHeight: this.uStyle.planHeight + 'px',
            background: this.uStyle.planBg
          }
          return style
        }
      },
      // 绘制实际的甘特条
      setRealityStyle(item){
        // 如果没有实际开始  直接返回
        if(!item.reality_startDate){
          return
        }
        console.log(item.reality_startDate, item.reality_endDate)
        var startIndex = this.uGanttColumns.findIndex(res => res.name === item.reality_startDate)
        var endIndex
        
        // 如果没有结束时间，则显示到的当天，如果有则显示赋值的
        if(item.reality_endDate){
          endIndex = this.uGanttColumns.findIndex(res => res.name === item.reality_endDate)
        } else {
          var year = new Date().getFullYear();
          var month = new Date().getMonth() + 1;
          var day = new Date().getDate();
          var mm = "'" + month + "'";
          var dd = "'" + day + "'";
          if(mm.length == 3) {
            month = "0" + month;
          }
          if(dd.length == 3) {
            day = "0" + day;
          }
          var time = year + "-" + month + "-" + day

          endIndex = this.uGanttColumns.findIndex(res => res.name === time)
        }
        var trIndex = this.ganttLists.findIndex(res => res.id === item.id)
        // console.log(trIndex, this.ganttLists)
        var style = {
          left: 70 * startIndex + 'px',
          width: 70 * (endIndex - startIndex + 1) + 'px',
          top: (this.uStyle.ganttHeight * (trIndex+1) - 10) + 'px',
          height: this.uStyle.realityHeight,
          // jhpqStatus:0未完成 1已完成
          background: item.jhpqStatus === '0' ? this.uStyle.realityBgIncomplete : this.uStyle.realityBgCompleted
        }
        return style
      },
      // 拖拽位移事件
      uGanttDrag(){
        var _this = this
        // 当前甘特条可移动部分
        var uGanttDrag = this.$refs.uGanttDrag;
        // 当前甘特条
        var uGanttTaskItem = this.$refs.uGanttTaskItem;
        // 整个甘特图
        var uGantt = this.$refs.uGantt
        // console.log(this.$refs)
        //当前甘特区域宽度 
        for (let i = 0; i < uGanttDrag.length; i++) {
          // 鼠标按下
          uGanttDrag[i].onmousedown = function (e) {
            // 整个甘特图区域滚动宽度(非展示宽度，加上看不见的滚动区域)
            var scrollWidth = uGantt.scrollWidth
            const uGanttWidth = uGantt.offsetWidth // 放在down外值不对，不知道为啥
            /**如果这些参数放在move设置就是会变的，放在down中就是固定值 */
            // 当前甘特条距离左侧距离
            const offsetLeft = uGanttTaskItem[i].offsetLeft
            // 当前甘特条宽度
            const offsetWidth = uGanttTaskItem[i].offsetWidth
            // 设置上次移动结束滚动条位置，用来判断
            const oldScrollLeft = uGantt.scrollLeft
            // 甘特图距离窗口左侧的距离
            var ganttWindowLeft = uGantt.getBoundingClientRect().left
            // 鼠标按下位置-用于计算
            var startX = e.clientX;
            var endX, moveLen
            // 向上取证获取当前是第几行
            var ganttIndex = Math.trunc(uGanttTaskItem[i].offsetTop / _this.uStyle.ganttHeight)
            // console.log(uGantt.scrollLeft)
            // console.log(startX)
            // 移动事件
            document.onmousemove = function (e) {
              endX = e.clientX;
              // 设置当前甘特条距离左侧的距离（使得左侧移动，而宽度不变，右侧对应向右移，产生移动效果）
              // console.log(oldScrollLeft, uGantt.scrollLeft)
              var distance
              if(uGantt.scrollLeft === oldScrollLeft){
                // 如果滚动条没有滚动
                distance = offsetLeft + ( endX - startX )
              } else {
                // 如果滚动条滚动了
                distance = offsetLeft + ( endX - startX ) + (uGantt.scrollLeft - oldScrollLeft)
              }
              // 判断超出左右距离时设置临界值
              if(distance > (scrollWidth - offsetWidth)){
                // 超出右边距离
                moveLen = scrollWidth - offsetWidth
              } else if(distance < 0) {
                // 超出左边距离
                moveLen = 0
              } else {
                moveLen = distance
              }
              uGanttTaskItem[i].style.left = moveLen + 'px'
              // 移动过程鼠标变成拖拽形状
              uGanttDrag[i].style.cursor = 'move'
              
              // 监听位置进行滚动条滚动
              // 鼠标当前位置
              var pointRight = ganttWindowLeft + uGanttWidth - endX
              // console.log(document.documentElement.clientWidth)
              
              if(pointRight < 50){
                uGantt.scrollLeft += 70
              }
              // 鼠标当前位置位于左侧边缘
              if(endX - ganttWindowLeft < 50){
                uGantt.scrollLeft -= 70
              }
              // uGantt.scrollHeight // 滚动条的高度
            }
            document.onmouseup = function (evt) {
              // 同样：不能停在一段的中间位置，所以计算使其整段整段的形式显示
              // console.log(uGanttTaskItem[i].offsetLeft)
              // 移动到最后一列的时候：时间往前+1天
              var StartLeft = Math.round(moveLen/70) * 70
              // var startNum
              if(StartLeft <= 0){
                var currentStartData = _this.addDate(_this.uGanttColumns[0].name, -1)
                _this.uGanttColumns = _this.getBetweenDate(currentStartData, _this.uGanttColumns[_this.uGanttColumns.length - 1].name)
                uGanttTaskItem[i].style.left = (Math.round(moveLen/70) + 1) * 70 + 'px';
                // startNum = (uGanttTaskItem[i].offsetLeft)/70
              } else {
                uGanttTaskItem[i].style.left = Math.round(moveLen/70) * 70 + 'px';
              }
              // 获取最终左侧停在第几列
              var startNum = (uGanttTaskItem[i].offsetLeft)/70
              // console.log(startNum)
              // var StartNum0 = startNum === 0 ? startNum + 1 : startNum
              // console.log(isStartNum)
              // 获取最终右侧停在第几列
              var endNum = (offsetWidth / 70) + startNum
              // 找到对应的时间强制赋值刷新
              _this.$set(_this.ganttLists[ganttIndex], 'start_date', _this.uGanttColumns[startNum].name)
              _this.$set(_this.ganttLists[ganttIndex], 'end_date', _this.uGanttColumns[endNum - 1].name)

              // 移动到最后一列的时候：时间+2天
              if(endNum >= _this.uGanttColumns.length){
                var currentEndData = _this.addDate(_this.uGanttColumns[endNum - 1].name, 2)
                _this.uGanttColumns = _this.getBetweenDate(_this.uGanttColumns[0].name, currentEndData)
              }
              
              
              // 鼠标变回手型
              uGanttDrag[i].style.cursor = 'pointer'
              // 释放
              document.onmousemove = null;
              document.onmouseup = null; 
              document.releaseCapture && document.releaseCapture();
            }
            document.setCapture && document.setCapture();
            return false;
          }
        }
      },
      // 改变大小
      uGanttResizeL(){
        var _this = this
        var resize = this.$refs.uGanttResizeL;
        var uGanttTaskItem = this.$refs.uGanttTaskItem;
        for (let i = 0; i < resize.length; i++) {
          resize[i].onmousedown = function (e) {
            var startX = e.clientX;
            var ganttIndex = Math.trunc(uGanttTaskItem[i].offsetTop / _this.uStyle.ganttHeight)
            const offsetLeft = uGanttTaskItem[i].offsetLeft;
            const offsetWidth = uGanttTaskItem[i].offsetWidth
            var moveLen
            var ganttWidth
            document.onmousemove = function (e) {
              var endX = e.clientX;
              moveLen = offsetLeft - (startX - endX);
              ganttWidth = (startX - endX) + offsetWidth
              if (ganttWidth < 70){
                ganttWidth = 70
                moveLen = offsetLeft + offsetWidth - 70
              }
              
              uGanttTaskItem[i].style.left = moveLen + 'px';
              uGanttTaskItem[i].style.width = ganttWidth + 'px';
            }
            document.onmouseup = function (evt) {
              // 移动到最后一列的时候：时间往前+1天
              var StartLeft = Math.round(moveLen/70) * 70
              if(StartLeft <= 0){
                var currentStartData = _this.addDate(_this.uGanttColumns[0].name, -1)
                _this.uGanttColumns = _this.getBetweenDate(currentStartData, _this.uGanttColumns[_this.uGanttColumns.length - 1].name)
                uGanttTaskItem[i].style.left = (Math.round(moveLen/70) + 1) * 70 + 'px';
                // startNum = (uGanttTaskItem[i].offsetLeft)/70
              } else {
                uGanttTaskItem[i].style.left = Math.round(moveLen/70) * 70 + 'px';
              }
              uGanttTaskItem[i].style.width = Math.round(ganttWidth/70) * 70 + 'px';
              var num = (uGanttTaskItem[i].offsetLeft)/70
              // console.log(num)
              // 普通赋值
              // _this.ganttLists[0].end_date = _this.uGanttColumns[num - 1].name
              // 强制赋值刷新
              // console.log(ganttIndex)
              _this.$set(_this.ganttLists[ganttIndex], 'start_date', _this.uGanttColumns[num].name)
              // 强制刷新
              // _this.$forceUpdate()
              document.onmousemove = null;
              document.onmouseup = null; 
              document.releaseCapture && document.releaseCapture();
            }
            document.setCapture && document.setCapture();
            return false;
          }
        }
      },
      // 改变大小
      uGanttResizeR(){
        // 方法域（onmousedown等方法中有自己的this，所以在外面重新赋值this，让内部方法调用）
        var _this = this
        // 1.获取ref
        var resize = this.$refs.uGanttResizeR;
        var uGanttTaskItem = this.$refs.uGanttTaskItem;
        // 整个甘特图
        var uGantt = this.$refs.uGantt
        // 2.循环监听获取当前点击的事件
        // 上面设置onmousedown方法会出现第一次点击无法调用的问题，所以在mounted中写（不知道为什么有类似监听的效果）
        // 因为ref有好几个，获取的数组，所以这里要循环
        for (let i = 0; i < resize.length; i++) {
          // 不可以设置var resize = resize[i] 下面统一使用resize的方式 =>这样会有问题
          // 1.鼠标按下事件：
          // 用[resize[i].],而不是全局document监听，这样才能监听到是哪儿一个甘特条触发了事件
          resize[i].onmousedown = function (e) {
            // 1.整个甘特图区域滚动宽度(非展示宽度，加上看不见的滚动区域)
            var scrollWidth = uGantt.scrollWidth
            const uGanttWidth = uGantt.offsetWidth
            // 2.获取当前点击的甘特条是第几行的，也就是对应左侧项目组中的index
            var ganttIndex = Math.trunc(uGanttTaskItem[i].offsetTop / _this.uStyle.ganttHeight)
            // 3.获取按下位置距离
            var startX = e.clientX;
            // 4.获取当前右侧拖拽区域距离父元素左侧距离(也就是右侧拖拽区域距离甘特图左边的距离：注意父子关系)
            var offsetLeft = resize[i].offsetLeft;
            // 转言之：上面那个就是当前甘特条的宽度--也就可以写作下面的方式
            // var offsetLeft = uGanttTaskItem[i].offsetWidth;
            // 5.甘特图距离窗口左侧的距离
            var ganttWindowLeft = uGantt.getBoundingClientRect().left
            // 6.定义拖拽参数--主要是为了onmouseup能调用
            var moveLen
            // 7.鼠标移动事件--注意：这里是document全局，这样就可以实现超出位置依旧可以控制拖拽
            document.onmousemove = function (e) {
              // 1.获取移动过程中实时位置
              var endX = e.clientX;
              // 2.设置当前甘特条的宽度：一开始甘特条的宽度 +（拖拽区域（鼠标点）末位置-初始位置）
              moveLen = offsetLeft + (endX - startX);
              // 3.判断如果小于1格，就不再减少
              if (moveLen < 70) moveLen = 70; 
              // 这一步好像是没啥用啊？
              // resize[i].style.left = moveLen;
              // 设置甘特条随move变化：即实时宽度也为moveLen即可
              uGanttTaskItem[i].style.width = moveLen + 'px';

              // 4.监听位置进行滚动条滚动
              // 鼠标当前位置
              var pointRight = ganttWindowLeft + uGanttWidth - endX
              // 如果位置靠右小于50，滚动条滚动
              // if(pointRight < 50){
              //   uGantt.scrollLeft += 70
              // }
            }
            // 鼠标抬起事件
            document.onmouseup = function (evt) {
              // 1.因为时间一段一段的，设置少于35(70的一半)最终结果向左靠，反之向右靠
              uGanttTaskItem[i].style.width = Math.round(moveLen/70) * 70 + 'px';
              // 2.获取当前甘特条最后位置在第几列--用于赋值
              var num = (uGanttTaskItem[i].offsetLeft + uGanttTaskItem[i].offsetWidth)/70

              // 移动到最后一列的时候：时间+2天
              if(num >= _this.uGanttColumns.length){
                var currentEndData = _this.addDate(_this.uGanttColumns[num - 1].name, 2)
                _this.uGanttColumns = _this.getBetweenDate(_this.uGanttColumns[0].name, currentEndData)
              }

              // 普通赋值
              // _this.ganttLists[0].end_date = _this.uGanttColumns[num - 1].name
              // 3.强制赋值刷新--获取列对应的时间，赋值给左侧的第ganttIndex个项目的end_date
              _this.$set(_this.ganttLists[ganttIndex], 'end_date', _this.uGanttColumns[num - 1].name)
              // 强制刷新
              // _this.$forceUpdate()
              // 4.释放鼠标事件
              document.onmousemove = null;
              document.onmouseup = null; 
              // 5.从当前线程中的窗口释放鼠标捕获，并恢复通常的鼠标输入处理
              document.releaseCapture && document.releaseCapture();
            }
            // 当前线程的给定窗口设置鼠标捕获
            document.setCapture && document.setCapture();
            return false;
          }
        }
      },
      tableCellClassName({ row, column, rowIndex, columnIndex }){
        //把每一行的索引放进row--可以用于获取index
        // row.index = rowIndex;
        // 设置新增列
        if(columnIndex === this.configColumns.length - 1 && column.property === 'add'){
          return 'add-btn-cell u-table-cell'
        }
        return 'u-table-cell'
      },
      // 展开隐藏事件
      expandChange(row, isExpend){
        console.log(row, isExpend)
        if(isExpend){
          // 展开
          var index = this.ganttLists.findIndex(res=>res.id === row.id)
          this.ganttLists.splice(index+1, 0, ...row.children)

          this.$forceUpdate()

        } else {
          // 隐藏
          this.ganttLists = this.ganttLists.filter(res=>res.pid !== row.id)
          this.$forceUpdate()
        }
      },
      // 双击事件
      rowDblclick(row, column, event){
        // console.log(row, column, event)
        // 深拷贝：直接赋值会有还没点确定，甘特图部分就已经改变的bug
        // this.currentDbEdit = JSON.parse(JSON.stringify(row))
        // this.$emit('dbclick', JSON.parse(JSON.stringify(row)))
        const dbClickRow = JSON.parse(JSON.stringify(row))
        const dbClickColumn = JSON.parse(JSON.stringify(column))
        this.$emit('dbclick', dbClickRow, dbClickColumn)
      },
      // 单元格点击事件
      cellClick(row,column,event,cell){
        // console.log(row,column,event,cell)
        const clickRow = JSON.parse(JSON.stringify(row))
        const clickColumn = JSON.parse(JSON.stringify(column))
        this.$emit('cellClick', clickRow, clickColumn)
      },
      // 添加事件
      addRow(row, index){
        // console.log(row, index)
        this.$emit('addRow', row, index)
        // var current = this.ganttLists[index].children
        // console.log(current)
        // var copy = current[current.length - 1]
        // this.ganttLists[index].children.push(copy)
        // this.$forceUpdate()
      },
      // 将数据返回
      getSaveData(){
        return this.ganttLists
      }
    }
  }
</script>

<style lang="scss">
.u-flex{
  display: flex;
}
.u-gantt-container{
  background-color: #fff;
  // width: calc(100vw - 240px);
  .el-table{
    user-select: none;
    // border-top: 1px solid #ebebeb;
    // border-left: 1px solid #ebebeb;
    // width: auto;
    .u-table-cell{
      padding: 0 !important;
      height: 40px !important;
      line-height: 40px !important;
      box-sizing: border-box !important;
    }
    .el-table--enable-row-transition .el-table__body td.el-table__cell{
      padding: 0 !important;
    }
    // 
    .add-btn-cell .cell{
      padding-left: 0;
      padding-right: 0;
    }
    .add-btn{
      font-size: 28px;
      font-weight: bolder;
      color: #44c2e5;
    }
  }
  .u-gantt-area{
    flex: 1;
    overflow: hidden;
  }
  .u-gantt{
    flex: 1;
    border-top: 1px solid #ebebeb;
    border-left: 1px solid #ebebeb;
    // width: calc(100% - 371px);
    overflow: auto;
  }
  .u-gantt-title{
    .item-title{
      width: 70px;
      // height: 40px;
      // line-height: 40px;
      text-align: center;
      border-right: 1px solid #ebebeb;
      border-bottom: 1px solid #ebebeb;
      font-size: 12px;
      color: #787878;
      flex-shrink: 0; // 设置宽度不够时，元素不压缩而是超出滚动
    }
  }
  .u-gantt-content{
    position: relative;
    // 底层表格线框
    .u-gantt-bg{
      // position: absolute;
      .item-tr{
        // height: 40px;
      }
      .item-td{
        width: 70px;
        // height: 40px;
        border-right: 1px solid #ebebeb;
        border-bottom: 1px solid #ebebeb;
        flex-shrink: 0; // 设置宽度不够时，元素不压缩而是超出滚动
      }
    }
    // 项目甘特条
    .u-gantt-task{
      // position: absolute;
      // top: 0;
      // left: 0;
      // right: 0;
      // bottom: 0;
      // background-color: #b72222;
      .u-gantt-task-content{
        .u-gantt-plan{
          position: absolute;
          top: 0;
          left: 0;
          width: 0;
          height: 0;
          line-height: 0;
          background-color: #44c2e5;
          border-radius: 0;
          .u-gantt-task-drag{
            position: absolute;
            top: 0;
            left: 1px;
            right: 1px;
            bottom: 0;
            cursor: pointer;
          }
          .u-gantt-task-resize{
            position: absolute;
            width: 8px;
            height: 26px;
            top: 0;
            cursor: w-resize;
          }
          .resize-left{
            left: -7px;
          }
          .u-gantt-task-text{
            color: #fff;
            text-align: center;
            
          }
          .resize-right{
            right: -7px;
          }
        }
        .u-gantt-reality{
          position: absolute;
          top: 0;
          left: 0;
          width: 0;
          height: 6px;
          // line-height: 6px;
          background-color: #e5de44;
          border-radius: 0;
        }
      }
    }
  }
}
</style>
