<!-- 前台头部 -->
<template>
  <div
    :class="[
      'super-breadcrumb',
      superBreadcrumbData.length <= 1 && !$route.meta.customSystemRouter
        ? 'super-breadcrumb-hide'
        : '',
    ]"
  >
    <div
      v-for="(item, index) in superBreadcrumbData"
      :key="index"
      :class="[
        'breadcrumb-item',
        (item.disabled && !item.compName) ||
        superBreadcrumbData.length === index + 1
          ? 'breadcrumb-item-disabled'
          : '',
        disableThirdLevel && item.level === 3 && !item.compName
          ? 'breadcrumb-item-disabled'
          : '',
      ]"
      @click="breadcrumbClick(item, index)"
    >
      <i class="before-arrow" />
      <div class="breadcrumb-item-content">
        <svgIcon
          v-if="item.menuIcon"
          icon-style="icon header-icon"
          :icon-class="item.menuIcon"
        />
        <span>{{ item.name }}</span>
      </div>
      <i class="after-arrow" />
    </div>
  </div>
</template>

<script>
import {mapState} from 'vuex'
//引入pub-sub-js库
import pubSub from 'pubsub-js'
import lodash from 'lodash'

export default {
  name: 'SuperBreadcrumb',
  props: {},
  computed: {
    ...mapState({
      // 重构菜单信息
      businessMenu: (state) => {
        return (
          state.menu.frontMenus.find((i) => i.alias === 'normal')?.children ||
          []
        )
      },
    }),
  },
  watch: {
    $route: {
      handler({path, meta}) {
        const {customSystemRouter = false, breadcrumbName = ''} = meta
        if (customSystemRouter) {
          this.superBreadcrumbData = [{name: breadcrumbName}]
        } else {
          this.superBreadcrumbData = this.getSuperBreadcrumbData(
            path,
            this.businessMenu
          )
        }
      },
      immediate: true,
    },
  },
  data() {
    return {
      superBreadcrumbData: [],
      pubAdd: null,
      pubBack: null,
      pubDisableThirdLevel: null,
      disableThirdLevel: false, // 是否禁用第三级，用于tab页面
    }
  },
  created() {},
  mounted() {
    // 添加自定义面包屑pub-sub
    this.pubAdd = pubSub.subscribe('add-custom-breadcrumb', (_, strOrObj) => {
      // 可跳转的组件需要两个参数，导航名称和组件名字
      // 由于该方法只能接受两个参数，
      // 面包屑导航名称和组件名字合并为一个对象，{name, compName}

      // 如果参数是字符串则为普通组件
      // 如果参数是对象则是可跳转组件
      if (typeof strOrObj === 'object') {
        const {name, compName} = strOrObj
        this.addCustomBreadcrumb(name, compName) // 可跳转组件
      } else {
        this.addCustomBreadcrumb(strOrObj) // 普通组件
      }
    })

    // 去掉最后一个
    this.pubBack = pubSub.subscribe('go-back', (_) => {
      this.superBreadcrumbData.pop()
    })

    // 是否禁用第三级
    this.pubDisableThirdLevel = pubSub.subscribe(
      'disable-third-level',
      (_, state = false) => {
        this.disableThirdLevel = state
      }
    )
  },
  methods: {
    /**
     * 获取面包屑数据
     * @param {String} path 路由路径
     * @param {Array} tree 树形菜单
     * @return {Array} 面包屑路径数据
     * */
    getSuperBreadcrumbData(path, tree) {
      /**
       * 获取树节点路径
       * @param {*} routerPath 树节点标识的值
       * @param {array} data 树
       * @returns {array} result 存放搜索到的树节点到顶部节点的路径节点
       */
      const getPathByKey = (routerPath, data) => {
        /** 存放搜索到的树节点到顶部节点的路径节点 */
        let result = []
        /**
         * 路径节点追踪
         * @param {*} routerPath 树节点标识的值
         * @param {array} path 存放搜索到的树节点到顶部节点的路径节点
         * @param {*} data 树
         * @returns undefined
         */
        let traverse = (routerPath, path, data) => {
          // 树为空时，不执行函数
          if (data.length === 0) return

          // 遍历存放树的数组
          for (let item of data) {
            // 遍历的数组元素存入path参数数组中
            path.push(item)
            // 如果目的节点的id值等于当前遍历元素的节点id值
            if (item.routerPath === routerPath) {
              // 把获取到的节点路径数组path赋值到result数组
              result = lodash.cloneDeep(path)
              return
            }

            // 当前元素的children是数组
            const children = Array.isArray(item.children) ? item.children : []
            // 递归遍历子数组内容
            traverse(routerPath, path, children)
            // 利用回溯思想，当没有在当前叶树找到目的节点，依次删除存入到的path数组路径
            path.pop()
          }
        }
        traverse(routerPath, [], data)
        // 返回找到的树节点路径
        return result.map((item) => {
          const {children, routerPath, ..._item} = item
          const level = routerPath.split('/').length - 2
          return {
            routerPath, // 路由地址
            level, // 层级
            isDirectory: level === 2, // 是否为目录（暂时只能约束2级）
            // disabled: level === 2, // 是否禁用
            isCurrentRoute: this.$route.path === routerPath, // 是否为当前路由
            ..._item,
          }
        })
      }

      return getPathByKey(path, tree)
    },

    // 面包屑点击
    breadcrumbClick(item, index) {
      if (
        (item.disabled && !item.compName) ||
        (this.disableThirdLevel && item.level === 3)
      )
        return
      pubSub.publish('breadcrumb-click', item)

      if (this.$route.path === item.routerPath || item.compName) {
        this.superBreadcrumbData.splice(index + 1)
      } else if (item.isDirectory) {
        pubSub.publish('directory-click', item)
      } else {
        // const oldLevel = this.superBreadcrumbData[this.superBreadcrumbData.length - 1]?.level
        // const newLevel = this.superBreadcrumbData.find(i => i.routerPath === item.routerPath)?.level
        // if (oldLevel - newLevel === 1) {
        //   this.$router.go(-1)
        // } else {
        //   this.$router.push(item.routerPath)
        // }
        this.$router.push(item.routerPath)
      }
    },

    // 添加自定义面包屑   携带compName的是可以跳转的组件 组件名称用于跳转返回
    addCustomBreadcrumb(name, compName = '') {
      this.superBreadcrumbData.push({
        name,
        compName,
        level: this.superBreadcrumbData.length + 1,
        isCurrentRoute: true,
        disabled: true,
      })
    },
  },
  beforeDestroy() {
    // 在组件销毁之前 清除订阅消息
    pubSub.unsubscribe(this.pubAdd)
    pubSub.unsubscribe(this.pubBack)
    pubSub.unsubscribe(this.pubDisableThirdLevel)
  },
}
</script>

<style lang="scss" scoped>
@import '~@/assets/css/element-variables';

.super-breadcrumb {
  width: 100%;
  background-color: #{$--system-module-color1};
  display: flex;
  align-items: center;
  column-gap: 12px;
  padding-left: 24px;
  transition: all 0.1s;
  height: 58px;

  $border-color: var(--border-color, #{$--system-border-color2});
  $font-color: var(--font-color, #{$--color-white});

  &.super-breadcrumb-hide {
    height: 0;
    overflow: hidden;
  }

  .breadcrumb-item {
    padding: 0 5px 0 20px;
    height: 40px;
    margin: 8px 0;
    background: $--system-module-color1;
    position: relative;
    border-top: 1px solid $border-color;
    border-bottom: 1px solid $border-color;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
    transition: all 0.2s;

    &:hover {
      --border-color: #{$--system-border-color1};
      --font-color: #{$--system-hover-active-text};
    }

    &:first-child {
      border-radius: 8px 0 0 8px;
      border-left: 1px solid $border-color;
      padding: 0 5px 0 15px;

      .before-arrow {
        display: none;
      }
    }

    &:last-child {
      --font-color: #{$--system-hover-active-text} !important;

      .breadcrumb-item-content {
        span {
          font-weight: 700;
          color: $font-color;
        }
      }
    }

    &.breadcrumb-item-disabled {
      --border-color: #{$--system-border-color2};
      --font-color: #{$--color-white};
      cursor: default;
    }

    .before-arrow {
      position: absolute;
      width: 0;
      height: 0;
      top: 50%;
      transform: translateY(-50%);
      left: 0;
      border-width: 20.5px 12px 20.5px 12px;
      border-style: solid;
      border-color: transparent transparent transparent $border-color;
      transition: all 0.2s;

      &::after {
        content: '';
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        left: -12px;
        border-width: 19.5px 11px 19.5px 11px;
        border-style: solid;
        border-color: transparent transparent transparent #{$--system-module-color1};
      }
    }

    .breadcrumb-item-content {
      display: flex;
      align-items: center;
      column-gap: 5px;

      svg {
        margin-top: 1.5px;
        font-size: 18px;
        color: $font-color;
        transition: all 0.2s;
      }

      span {
        font-size: 14px;
        font-family: Microsoft YaHei, Microsoft YaHei, serif;
        color: $font-color;
        transition: all 0.2s;
      }
    }

    .after-arrow {
      position: absolute;
      width: 0;
      height: 0;
      top: 50%;
      right: -22.5px;
      transform: translateY(-50%);
      border-width: 20.5px 12px 20.5px 12px;
      border-style: solid;
      border-color: transparent transparent transparent $border-color;
      transition: all 0.2s;

      &::after {
        content: '';
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        right: -9px;
        border-width: 19.5px 11px 19.5px 11px;
        border-style: solid;
        border-color: transparent transparent transparent #{$--system-module-color1};
      }
    }
  }
}
</style>

