<template>
  <Card :title="title">
    <div class="gantt-chart">
      <div class="table">
        <div class="thead">
          <div class="row">
            <div class="td">分部分项工程名称</div>
            <div class="td">开始日期</div>
            <div class="td">完成日期</div>
            <div class="td" v-for="date in dates" :key="date">
              <div class="date">
                <div class="month">
                  {{ date }}
                </div>
                <div class="days">
                  <div class="day" v-for="day in getDays(date)" :key="day.num">{{ day.num }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="tbody">
          <div class="row-groups" :class="{ open: openedIndex === i }" v-for="(p, i) in projects" :key="p.pName">
            <div class="row">
              <div class="td" @click="handleOpen(i)">{{ p.pName }}</div>
              <div class="td">{{ p.startTime }}</div>
              <div class="td">{{ p.endTime }}</div>
              <div class="td" v-for="date in dates" :key="date + 'grid-date'">
                <div class="grids">
                  <div class="grid" v-for="day in getDays(date)" :key="'grid' + day.num" :ref="p.pName + '-' + day.date"></div>
                </div>
              </div>
              <div class="progress" :style="{ left: gantt.left, width: gantt.width }" v-for="(gantt, index) in p.gantts" :key="index"></div>
            </div>
            <div class="children">
              <div class="row" v-for="child in p.children" :key="'child-' + child.pName">
                <div class="td">{{ child.pName }}</div>
                <div class="td">{{ child.startTime }}</div>
                <div class="td">{{ child.endTime }}</div>
                <div class="td" v-for="date in dates" :key="date + 'grid-date'">
                  <div class="grids">
                    <div class="grid" v-for="day in getDays(date)" :key="'grid' + day.num" :ref="child.pName + '-' + day.date"></div>
                  </div>
                </div>
                <div class="progress"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </Card>
</template>

<script>
import Card from '../components/Card.vue'
export default {
  components: { Card },
  props: {
    title: {
      type: String,
      default: ''
    }
  },
  created() {
    console.log(this.getDays('2022/09'), '到')
  },
  mounted() {
    this.getGantts()
  },
  data() {
    return {
      dates: ['2020/03', '2020/04', '2020/05', '2020/07', '2020/08'],
      projects: [
        {
          pName: '地基与基础工程',
          startTime: '2020/04/06',
          endTime: '2020/05/09',
          gantts: [{ left: '420px', width: '100px', status: '' }],
          children: [
            { pName: '无支护土方工程', startTime: '2020/04/06', endTime: '2020/05/07' },
            { pName: '有支护土方工程', startTime: '2020/04/10', endTime: '2020/05/08' }
          ]
        },
        { pName: '主体结构', startTime: '2020/03/12', endTime: '2020/06/04' },
        { pName: '建筑装饰装修', startTime: '2020/04/21', endTime: '2020/07/30' }
      ],
      openedIndex: 9999
    }
  },
  methods: {
    getGantts() {
      this.projects.map(project => {
        let { startTime, pName, gantts } = project
        const dateArr = startTime.split('/')
        let startRef = null

        if (!(dateArr[2] % 2)) {
          const day = dateArr[2] - 1
          dateArr[2] = day < 10 ? '0' + day : day
          startTime = dateArr.join('/')
          console.log(startTime, 'xxx')
        }

        startRef = this.$refs[`${pName}-${startTime}`][0]
        const left = startRef.offsetLeft
        gantts[0].left = left + 'px'
        console.log(startRef.offsetLeft, '丢雷', startTime)
        // 设置 left
      })
    },
    getDays(date) {
      const year = date.split('/')[0]
      const month = +date.split('/')[1]
      const large = [1, 3, 5, 7, 8, 10, 12]
      const normal = [4, 6, 9, 11]
      const small = [2]
      let count = 0
      switch (true) {
        case large.includes(month):
          count = 31
          break
        case normal.includes(month):
          count = 30
          break
        case small.includes(month):
          count = year % 4 ? 28 : 29
          break
      }

      return (() => {
        const days = new Array(count)
          .fill(0)
          .map((item, index) => {
            let num = index + 1
            let fulldate = date + (num < 10 ? '/0' + num : '/' + num)
            return { num, date: fulldate }
          })
          .filter(item => item.num % 2)
        if (count === 28) {
          days.push({ num: 28, date: date + '/28' })
        } else if (count === 30) {
          days.push({ num: 30, date: date + '/30' })
        }
        return days
      })()
    },
    handleOpen(index) {
      if (index === this.openedIndex) {
        this.openedIndex = 9999
      } else {
        this.openedIndex = index
      }
    }
  }
}
</script>

<style lang="less" scoped>
.gantt-chart {
  height: 100%;
  .table {
    height: 100%;
    overflow-x: auto;
    .thead {
      border-bottom: 1px solid #234d5f;
      .row {
        display: flex;
        .td {
          flex-shrink: 0;
          box-sizing: border-box;
          height: 42px;
          line-height: 42px;
          background-color: #163549;
          .date {
            line-height: 21px;
            border-left: 1px solid #234d5f;
            .month {
              border-bottom: 1px solid #234d5f;
            }
            .days {
              display: flex;
              .day {
                flex: 1;
              }
            }
          }
          &:nth-child(1) {
            padding-left: 40px;
            width: 200px;
          }
          &:not(:nth-child(1)) {
            width: 100px;
            text-align: center;
          }
          &:nth-child(n + 4) {
            width: 400px;
          }
        }
      }
    }
    .tbody {
      border-left: 1px solid #234d5f;
      .row-groups {
        position: relative;
        &::before {
          content: '';
          position: absolute;
          left: 26px;
          top: 16px;
          width: 0;
          height: 0;
          border-top: 4px solid transparent;
          border-right: 4px solid transparent;
          border-bottom: 4px solid transparent;
          border-left: 4px solid #5be1f4;
          z-index: 99;
        }
        &.open {
          &::before {
            border-left-color: transparent;
            border-top-color: #5be1f4;
          }
          .children {
            display: block;
          }
        }
        > .row .td:first-child {
          user-select: none;
          cursor: pointer;
        }
        .row {
          position: relative;
          display: flex;
          .td {
            flex-shrink: 0;
            box-sizing: border-box;
            height: 42px;
            line-height: 42px;
            background-color: #0a1b2f;
            border-right: 1px solid #234d5f;
            border-bottom: 1px solid #234d5f;
            .grids {
              height: 100%;
              display: flex;
              .grid {
                position: relative;
                flex: 1;
                height: 100%;
                &:not(:last-child) {
                  border-right: 1px solid #234d5f;
                }
              }
            }
            &:nth-child(1) {
              padding-left: 40px;
              width: 200px;
            }
            &:not(:nth-child(1)) {
              width: 100px;
              font-size: 14px;
              text-align: center;
            }
            &:nth-child(n + 4) {
              width: 400px;
            }
          }
          .progress {
            flex-shrink: 0;
            position: absolute;
            top: calc(50% - 7px);
            width: 20px;
            height: 14px;
            background: pink;
          }
        }
        .children {
          display: none;
          .td {
            height: 38px;
            line-height: 38px;
            font-size: 14px;
          }
        }
      }
    }
  }
}
</style>
