<!--
  @description: 代理机构驱动模板--分为后审驱动和资审驱动
  @Modifier：haoFx/肖文龙
  @routerPath:
  @date：  2019/11/14-9:43
-->
<template>
  <div :class="driveType" class="drive-bid-content clearfix">
    <!--驱动头部-->
    <div>
      <!--评标头部 -->
      <bidEvaDriveHeader
        v-if="driveType === 'evaluation'"
        :drive-data="driveData"
        :back="drive_back"
      />

      <!-- 项目头部 -->
      <driveHeader
        v-if="driveType === 'project'"
        ref="driveHeader"
        :drive-data="driveData"
        :back="drive_back"
        :package-change="setPackage"
      >
        <!-- 头部右边-具名插槽 -->
        <template v-slot:title-right>
          <slot name="header" />
        </template>
      </driveHeader>
    </div>
    <div class="content">
      <!--项目驱动内容展示-->
      <div class="content-left fl">
        <!--项目驱动步骤菜单-->
        <el-scrollbar class="scrollbar content-left_scrollbar">
          <driveSideBar
            :drive-data="drive_data"
            :list="driveTaskList"
            :set-drive-task-child="setDriveTaskChild"
          />
        </el-scrollbar>
        <!--非主流程菜单-->
        <noMainFlowMenu
          :menu-list="noMainFlowMenuList"
          :set-no-main-flow-menu-child="setNoMainFlowMenuChild"
        />
      </div>
      <div
        :class="'content-right '+(noMainFlowList.length>0||driveTaskChildList.length>0?'content-right-len':'content-right-len_0')"
        class="fl"
      >
        <!--主流程-二级项目驱动步骤tab-->
        <driveStep
          :drive-data="drive_data"
          :list="driveTaskChildList"
          :drive-task-child-change="driveTaskChildChange"
          :zs-list="driveZsTaskChildList"
        >
          <!-- 插槽-二级路由的其他操作 -->
          <template v-slot:stepRight>
            <slot name="stepRight" />
          </template>
        </driveStep>
        <!--非主流程-二级项目驱动步骤tab-->
        <noMainFlowStep
          :no-main-flow-change="noMainFlowMenuChildChange"
          :list="noMainFlowList"
        />
        <!--内容-->
        <div v-if="is_Reload && is_Show">
          <el-scrollbar class="content-right_scrollbar">
            <slot name="content">
              <router-view />
            </slot>
          </el-scrollbar>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
/* 公共方法*/
import { cloneObject } from '@assets/js/utils' // 常用方法
/* 组件*/
import driveHeader from '@comp/common/drive/components/driveHeader' // 项目驱动-头部驱动
import bidEvaDriveHeader from '@comp/common/drive/components/bidEvaDriveHeader' // 评标驱动-头部驱动
import driveSideBar from '@comp/common/drive/components/driveSideBar' // 一级项目驱动步骤
import driveStep from '@comp/common/drive/components/driveStep' // 二级项目驱动步骤tab
import noMainFlowMenu from '@comp/common/drive/components/noMainFlowMenu' // 非主流程菜单
import noMainFlowStep from '@comp/common/drive/components/noMainFlowStep' // 非主流程tab

export default {
  name: 'ProjectDrive',
  provide() {
    return {
      driveReload: this.driveReload, // 驱动刷新
      getDriveTask: this.getProjectDriveTask // 刷新驱动节点
    }
  },
  components: {
    driveHeader, // 项目驱动-头部驱动
    bidEvaDriveHeader, // 评标驱动-头部驱动
    driveSideBar, // 一级项目驱动步骤
    driveStep, // 二级项目驱动步骤tab
    noMainFlowMenu, // 非主流程菜单
    noMainFlowStep // 非主流程tab
  },
  props: {
    // 需要初始化的内容
    readyData: {
      type: Function,
      default: function() {}
    },
    // 返回
    back: {
      type: Function,
      default: function() {}
    },
    // 驱动类型
    // project 项目驱动 evaluation 评标大厅驱动
    driveType: {
      type: String,
      default: 'project'
    },
    // 项目参数
    driveData: {
      type: Object,
      default: function() {
        return {
          driveName: 'taskName', // 节点名称-key名称 默认值 taskName
          mainIdKey: 'mainId', // 获取子节点id-key名称 默认值 mainId
          driveUrlKey: 'requestUrl', // 驱动主节点-路由-key名称 默认值 requestUrl
          driveIsOpenKey: 'isOpen', // 驱动主节点-状态-key名称 默认值 isOpen
          driveIconType: '00', // 图标使用状态 00 默认 01 自定义icon 02 序列号
          // ------------------------------------------------------------------
          driveOpenVal: '01', // 驱动主节点-状态-开启/完成value 默认值 01
          driveIsOpenOngoingVal: '01', // 驱动主节点-状态-进行中value 默认值 01
          driveNoOpenVal: '00', // 驱动主节点-状态-未开启value 默认值 00
          // ------------------------------------------------------------------
          childName: 'taskName', // 节点名称-key名称 默认值 taskName
          childUrlKey: 'requestUrl', // 子驱动-路由-key名称 默认值 requestUrl
          childIconType: '00', // 图标使用状态 00 默认 01 自定义icon 02 序列号
          // ------------------------------------------------------------------
          childStatusKey: 'processStatus', // 子驱动-key名称 默认值 processStatus
          childStatusOpenVal: '02', // 子驱动-开启/完成value 默认值 02
          childStatusOngoingVal: '01', // 子驱动-进行中value 默认值 01
          childStatusNoOpenVal: '00' // 子驱动-未开启value 默认值 00
        }
      }
    },
    // 驱动 获取驱动节点信息
    loadDrive: {
      type: Function,
      default: function() {}
    },
    // 标段(包)列表
    // fn 回调函数（索引id，标段列表list）
    initData: {
      type: Function,
      default: function(fn) {
        fn()
      }
    },
    /*
       * 切换标段
       *  packId 当前标段参数
       * */
    packageChange: {
      type: Function,
      default: function(item) {}
    },
    /*
       * 切换主流程步骤节点tab
       * item 主流程步骤节点参数
       * */
    driveTaskChange: {
      type: Function,
      default: function(item) {}
    },
    // 非主流程-初始化当前非主流程节点的二级步骤tab
    noMainFlowMenuList: {
      type: Array,
      default: function(item) {
        return []
      }
    },
    /*
       * 非主流程-切换步骤节点tab
       * item 步骤节点参数
       * */
    noMainFlowMenuChange: {
      type: Function,
      default: function(item) {}
    }
  },
  data() {
    return {
      is_Reload: true, // 刷新
      is_Show: false, // 驱动加载完成 才进行渲染页面
      // 动态key设置
      drive_data: {
        driveName: 'taskName', // 节点名称-key名称 默认值 taskName
        mainIdKey: 'mainId', // 获取子节点id-key名称 默认值 mainId
        driveUrlKey: 'requestUrl', // 驱动主节点-路由-key名称 默认值 requestUrl
        driveIsOpenKey: 'isOpen', // 驱动主节点-状态-key名称 默认值 isOpen
        driveIconType: '00', // 图标使用状态 00 默认 01 自定义icon 02 序列号
        // ------------------------------------------------------------------
        driveOpenVal: '01', // 驱动主节点-状态-开启/完成value 默认值 01
        driveIsOpenOngoingVal: '01', // 驱动主节点-状态-进行中value 默认值 01
        driveNoOpenVal: '00', // 驱动主节点-状态-未开启value 默认值 00
        // ------------------------------------------------------------------
        childName: 'taskName', // 节点名称-key名称 默认值 taskName
        childUrlKey: 'requestUrl', // 子驱动-路由-key名称 默认值 requestUrl
        childIconType: '00', // 图标使用状态 00 默认 01 自定义icon 02 序列号
        // ------------------------------------------------------------------
        childStatusKey: 'processStatus', // 子驱动-key名称 默认值 processStatus
        childStatusOpenVal: '02', // 子驱动-开启/完成value 默认值 02
        childStatusOngoingVal: '01', // 子驱动-进行中value 默认值 01
        childStatusNoOpenVal: '00' // 子驱动-未开启value 默认值 00
      },
      driveTaskList: [], // 一级项目驱动步骤
      driveTaskChildData: [], // 二级项目驱动步骤tab集合(当为后审状态 或 资审状态的后审阶段时)
      driveTaskChildList: [], // 当前节点二级项目驱动步骤tab(当为后审状态 或 资审状态的后审阶段时)
      driveZsTaskChildData: [], // 二级项目驱动步骤tab集合（资审状态下的资审阶段）
      driveZsTaskChildList: [], // 当前节点二级项目驱动步骤tab（资审状态下的资审阶段）
      noMainFlowList: [] // 非主流程当前索引Tabs
    }
  },
  created() {
    this.$store.dispatch('setSidebarIsCollapse', true) // 驱动菜单 展开隐藏
    // 需要初始化的内容
    this.drive_data = { ...this.drive_data, ...this.driveData } // 初始化动态key
    this.readyData()
  },
  mounted() {
    this.$nextTick(function() {
      if (this.driveType === 'evaluation') {
        // 评标大厅驱动
        this.initData(this.setPackage) // 获取标段（包）列表
      } else if (this.driveType === 'project') {
        // 项目驱动
        this.initData(this.$refs.driveHeader.setPackage) // 获取标段（包）列表
      }
    })
  },
  methods: {
    // 刷新 驱动内页面
    driveReload() {
      this.is_Reload = false
      this.$nextTick(() => {
        this.is_Reload = true
      })
    },
    // 返回
    drive_back() {
      this.back()
      this.$store.dispatch('setSidebarIsCollapse', false) // 驱动菜单 展开隐藏
    },
    /*
       * 切换标段
       *  packId 当前标段参数
       * */
    setPackage(item) {
      this.packageChange(item)
      this.getProjectDriveTask() // 获取驱动步骤菜单
    },
    /* =========================================主流程菜单部分========================================= */
    /*
       * 获取驱动步骤菜单
       * packId 当前标段Id
       * */
    async getProjectDriveTask() {
      // 初始化驱动数据
      this.driveTaskChildData = {} // 二级项目驱动步骤tab集合(当为后审状态 或 资审状态的后审阶段时)
      this.driveTaskChildList = [] // 当前节点二级项目驱动步骤tab(当为后审状态 或 资审状态的后审阶段时)
      this.driveZsTaskChildData = {} // 二级项目驱动步骤tab集合（资审状态下的资审阶段）
      this.driveZsTaskChildList = [] // 当前节点二级项目驱动步骤tab（资审状态下的资审阶段）
      this.noMainFlowList = [] // 非主流程Tabs
      const {
        currentStageType,
        driveTaskList,
        projectDriveListMap,
        qualificationProjectDriveMap
      } = await this.loadDrive() // 获取驱动节点信息
      this.currentStageType = currentStageType || '01' //  资格预审 00  资格后审 01 展示驱动
      this.driveTaskList = driveTaskList || [] // 一级项目驱动步骤
      //  二级项目驱动步骤tab集合 （后审项目或者资审项目的后审阶段）
      if (currentStageType === '01' || !currentStageType) {
        // 资格后审
        this.driveTaskChildData = projectDriveListMap || {} // 资格后审
        this.driveZsTaskChildData = qualificationProjectDriveMap || {} // 资格预审
      } else if (currentStageType === '00') {
        // 资审项目的资审状态
        this.driveTaskChildData = qualificationProjectDriveMap || {} // 资格预审
      }
      this.$forceUpdate() // 数据强制刷新
      // 设置当前节点的二级步骤tab(循环主驱动)
      this.driveTaskList.forEach((item, index) => {
        /*
           * 找到已开启的节点并进行跳转
           * isOpen === 01 已开启节点 && 该节点的下一个节点 是空的 或
           * isOpen === 01 已开启节点 && 该节点的下一个节点 isOpen === 00 未开启
           * isOpen === 02 已完成 && 是最后一个节点时
           * isOpen === 02 进行中 && 该节点的下一个节点 isOpen === 00 未开启
           * */
        if ((item[this.drive_data.driveIsOpenKey] === this.drive_data.driveIsOpenOngoingVal && !this.driveTaskList[index + 1]) ||
            (item[this.drive_data.driveIsOpenKey] === this.drive_data.driveIsOpenOngoingVal && this.driveTaskList[index + 1][this.drive_data.driveIsOpenKey] === this.drive_data.driveNoOpenVal) ||
            (item[this.drive_data.driveIsOpenKey] === this.drive_data.driveOpenVal && !this.driveTaskList[index + 1]) ||
            (item[this.drive_data.driveIsOpenKey] === this.drive_data.driveOpenVal && this.driveTaskList[index + 1][this.drive_data.driveIsOpenKey] === this.drive_data.driveNoOpenVal)
        ) {
          this.$set(item, 'driveTaskActivePath', item[this.drive_data.driveUrlKey]) // 主驱动索引-使用路由设置为索引
          this.setDriveTaskChild(item, index, 'for') // 'for'代表 item 一级步骤节点参数
        }
      })
      this.is_Show = true // 驱动加载完成 才进行渲染页面
    },
    /*
       * 设置当前主节点的二级步骤tab
       * item 一级步骤节点参数
       * driveTaskIndex 主驱动下标
       * type ==='for' 代表 mainId是循环出
       * */
    setDriveTaskChild(item, driveTaskIndex, type) {
      // 初始化
      this.driveZsTaskChildList = []// 主流程-资审
      this.driveTaskChildList = []// 主流程-后审
      this.noMainFlowList = [] // 非主流程Tabs

      // mainId 唯一获取二级步骤tab参数
      const mainId = item[this.drive_data.mainIdKey]
      // 判断是否有二级路由-索引值
      if (this.driveTaskChildData[mainId] || this.driveZsTaskChildData[mainId]) {
        // 二级项目驱动步骤tab集合(当为后审状态 或 资审状态的后审阶段时) 不为空时
        if (this.driveTaskChildData[mainId]) {
          // 二级项目驱动步骤tab集合(当为后审状态 或 资审状态的后审阶段时)
          this.driveTaskChildList = cloneObject(
            this.driveTaskChildData[mainId]
          ) // 深拷贝
        }
        // 判断二级项目驱动步骤集合（资审状态下的资审阶段） 不为空时执行
        if (this.driveZsTaskChildData[mainId]) {
          // 当前节点二级项目驱动步骤tab（资审状态下的资审阶段）
          this.driveZsTaskChildList = cloneObject(
            this.driveZsTaskChildData[mainId]
          ) // 深拷贝
        }
        this.driveTaskChildChangeMap(driveTaskIndex, type) // 查找二级步骤节点-当前正在进行中的节点进行跳转（循环子驱动）
      } else {
        // 没有子节点情况下，切换一级级步骤节点tab
        this.setDriveTaskChange(item)
      }
    },
    /*
       * 没有子节点情况下，切换一级级步骤节点tab
       * item 一级步骤节点参数
       * */
    setDriveTaskChange(item) {
      const { query } = this.driveTaskChange(item) || {}
      // 路由跳转
      this.$router.push({ path: item[this.drive_data.driveUrlKey], query })
      this.$forceUpdate()
      this.driveReload() // 刷新驱动
    },
    /*
       * 查找二级步骤节点-当前正在进行中的节点进行跳转（循环子驱动）
       * driveTaskIndex 主驱动下标
       * type ==='for' 代表 mainId是循环出
       * */
    driveTaskChildChangeMap(driveTaskIndex, type) {
      let isTask = false // 当前主驱动下的二级节点是否有正在制作节点
      // 查找当前正在进行中的节点进行跳转（循环子驱动）
      this.driveTaskChildList.forEach((item, index) => {
        /* isTask === false */
        if (!isTask) {
          // locationStatus 00:未定位/非索引状态 01:定位//索引状态
          if (item.locationStatus === '01') {
            isTask = true
            this.driveTaskChildChange(item) // 切换二级步骤节点tab
            return
          } else {
            if (
              (item[this.drive_data.childStatusKey] === this.drive_data.childStatusOngoingVal && !this.driveTaskChildList[index + 1]) ||
                (item[this.drive_data.childStatusKey] === this.drive_data.childStatusOngoingVal && this.driveTaskChildList[index + 1][this.drive_data.childStatusKey] === this.drive_data.childStatusNoOpenVal) ||
                (item[this.drive_data.childStatusKey] === this.drive_data.childStatusOpenVal && !this.driveTaskChildList[index + 1]) ||
                (item[this.drive_data.childStatusKey] === this.drive_data.childStatusOpenVal && this.driveTaskChildList[index + 1][this.drive_data.childStatusKey] === this.drive_data.childStatusNoOpenVal)
            ) {
              /*
                 * processStatus === 01 进行中 && 是最后一个节点时 或
                 * processStatus === 01 进行中 && 该节点的下一个节点 processStatus === 00 未开启
                 * processStatus === 02 已完成 && 是最后一个节点时
                 * processStatus === 02 进行中 && 该节点的下一个节点 processStatus === 00 未开启
                 * */
              isTask = true
              this.driveTaskChildChange(item) // 切换二级步骤节点tab
              return
            }
          }
        }
      })
      /* isTask === false */
      if (!isTask) {
        if (this.driveTaskList[driveTaskIndex - 1] && type === 'for') {
          /* 当前主节点有上一个节点时 && type === 'for'代表 mainId是循环出来时  */
          this.driveTaskList.forEach((item, index) => {
            this.$set(item, 'driveTaskActivePath', '') // 主驱动索引-清空所有索引
          })
          this.$set(
            this.driveTaskList[driveTaskIndex - 1],
            'driveTaskActivePath',
            this.driveTaskList[driveTaskIndex - 1][this.drive_data.driveUrlKey]
          ) // 主驱动索引-使用路由设置为索引
          this.setDriveTaskChild(
            this.driveTaskList[driveTaskIndex - 1],
            driveTaskIndex - 1,
            'for'
          ) // 'for'代表 mainId是循环出来时
        } else if (this.driveZsTaskChildList.length > 0 && type !== 'for') {
          /* 当前节点二级项目驱动步骤tab（已完成的资审步骤）有数据时 &&type !=='for'  */
          this.driveTaskChildChange(
            this.driveZsTaskChildList[this.driveZsTaskChildList.length - 1]
          ) // 切换二级步骤节点tab
        }
      }
    },
    /*
       * 切换二级步骤节点tab
       * item 二级步骤节点参数
       * */
    driveTaskChildChange(item) {
      // 索引-二级索引
      this.$set(item, 'activePath', item[this.drive_data.childUrlKey]) // 二级索引-使用路由设置为索引
      const { query } = this.driveTaskChange(item) || {}
      // 路由跳转
      this.$router.push({ path: item[this.drive_data.childUrlKey], query })
      this.$forceUpdate()
      this.driveReload() // 刷新驱动
    },
    /* =========================================非主流程菜单部分========================================= */
    /*
       * 设置当前非主流程节点的二级步骤tab
       * item 当前节点
       * */
    setNoMainFlowMenuChild(item) {
      // 二级项目驱动步骤tab集合(当为后审状态 或 资审状态的后审阶段时)
      this.driveTaskChildList = []
      // 当前节点二级项目驱动步骤tab（资审状态下的资审阶段）
      this.driveZsTaskChildList = []
      // 非主流程Tabs
      this.noMainFlowList = item.child ? cloneObject(item.child) : [] // 深拷贝
      if (item.child) { // 有子节点时
        this.noMainFlowMenuChildChange(this.noMainFlowList[0])
      } else { // 无子节点时
        this.noMainFlowMenuChildChange(item)
      }
    },
    /*
       * 切换非主流程步骤节点tab
       * item 非主流程步骤节点参数
       * */
    noMainFlowMenuChildChange(item) {
      const { query } = this.noMainFlowMenuChange(item) || {}
      // 路由跳转
      if (!item.path) return
      this.$router.push({ path: item.path, query })
    }
  }
}
</script>

<style lang="less" scoped>
  @import "~@assets/style/common/public.less";
  // 默认样式
  /*项目驱动步骤菜单*/
  .drive-bid-content {
    position: relative;
    background-color: #edf0f5;
    .content-left {
      position: relative;
      width: 165px;
      z-index: 2;
      background: #fff;
      border-right: 1px solid #e2e7ee;
    }
    .content-right {
      width: calc(100% - 165px);
      position: relative;
      background: #fff;
    }
  }
  // 项目驱动-高度设置
  .project {
    min-height: calc(100vh - 56px - 28px);
    .content-left {
      height: calc(100vh - 56px - 40px);
      .content-left_scrollbar {
        height: calc(100vh - 56px - 32px - 82px - 40px);
      }
    }
    .content-right {
      height: calc(100vh - 56px - 40px);
    }
    // 有二级驱动
    .content-right-len {
      height: calc(100vh - 56px - 40px);
      .content-right_scrollbar {
        width: 100%;
        height: calc(100vh - 56px - 40px - 40px);
      }
    }
    // 无二级驱动
    .content-right-len_0 {
      height: calc(100vh - 56px - 40px);
      .content-right_scrollbar {
        width: 100%;
        height: calc(100vh - 56px - 40px);
      }
    }
  }
  // 评标驱动
  .evaluation {
    min-height: calc(100vh - 56px);
    .content {
      padding: 10px 16px;
      .content-left {
        height: calc(100vh - 56px - 20px);
        .content-left_scrollbar {
          height: calc(100vh - 56px - 32px - 82px - 20px);
        }
      }
      .content-right {
        height: calc(100vh - 56px - 20px);
      }
      // 有二级驱动
      .content-right-len {
        height: calc(100vh - 56px - 20px);
        .content-right_scrollbar {
          width: 100%;
          height: calc(100vh - 56px - 20px - 40px);
        }
      }
      // 无二级驱动
      .content-right-len_0 {
        height: calc(100vh - 56px  - 20px);
        .content-right_scrollbar {
          width: 100%;
          height: calc(100vh - 56px - 20px);
        }
      }
    }
  }
</style>
