From-wh пре 2 година
родитељ
комит
d3bf3d2b40

+ 287 - 0
template/admin/src/layout/component/transverseAside.vue

@@ -0,0 +1,287 @@
+<template>
+  <div class="layout-columns-tra-aside">
+    <el-scrollbar>
+      <ul>
+        <li
+          v-for="(v, k) in columnsAsideList"
+          :key="k"
+          @click="onColumnsAsideMenuClick(v)"
+          ref="columnsAsideOffsetLeftRefs"
+          class="layout-columns"
+          :class="{ 'layout-columns-active': v.k === liIndex }"
+          :title="$t(v.title)"
+        >
+          <div :class="setColumnsAsidelayout" v-if="!v.isLink || (v.isLink && v.isIframe)">
+            <Icon :type="v.icon" />
+            <div class="font12">
+              {{
+                $t(v.title) && $t(v.title).length >= 4
+                  ? $t(v.title).substr(0, setColumnsAsidelayout === 'columns-vertical' ? 4 : 3)
+                  : $t(v.title)
+              }}
+            </div>
+          </div>
+          <div :class="setColumnsAsidelayout" v-else>
+            <a :href="v.isLink" target="_blank">
+              <Icon :type="v.icon" />
+              <div class="font12">
+                {{
+                  $t(v.title) && $t(v.title).length >= 4
+                    ? $t(v.title).substr(0, setColumnsAsidelayout === 'columns-vertical' ? 4 : 3)
+                    : $t(v.title)
+                }}1
+              </div>
+            </a>
+          </div>
+        </li>
+        <div ref="columnsAsideActiveRef" :class="setColumnsAsideStyle"></div>
+      </ul>
+    </el-scrollbar>
+  </div>
+</template>
+
+<script>
+import { getMenuSider, getHeaderName } from '@/libs/system';
+import Logo from '@/layout/logo/index.vue';
+
+export default {
+  name: 'layoutColumnsAside',
+  components: { Logo },
+  data() {
+    return {
+      columnsAsideList: [],
+      liIndex: 0,
+      difference: 0,
+      routeSplit: [],
+      activePath: '',
+    };
+  },
+  computed: {
+    // 设置分栏高亮风格
+    setColumnsAsideStyle() {
+      return this.$store.state.themeConfig.themeConfig.columnsAsideStyle;
+    },
+    // 设置分栏布局风格
+    setColumnsAsidelayout() {
+      return this.$store.state.themeConfig.themeConfig.columnsAsideLayout;
+    },
+    Layout() {
+      return this.$store.state.themeConfig.themeConfig.Layout;
+    },
+    routesList() {
+      this.$store.state.routesList.routesList;
+    },
+  },
+  beforeDestroy() {
+    this.bus.$off('routesListChange');
+  },
+  mounted() {
+    this.bus.$on('routesListChange', () => {
+      this.setFilterRoutes();
+    });
+    this.setFilterRoutes();
+  },
+  methods: {
+    // 设置菜单高亮位置移动
+    setColumnsAsideMove(k) {
+      if (k === undefined) return false;
+      const els = this.$refs.columnsAsideOffsetLeftRefs;
+      this.liIndex = k;
+      this.$refs.columnsAsideActiveRef.style.left = `${els[k].offsetLeft + this.difference}px`;
+    },
+    // 菜单高亮点击事件
+    onColumnsAsideMenuClick(v) {
+      let { path, redirect } = v;
+      if (path) this.$router.push(path);
+      else this.$router.push(path);
+      // 一个路由设置自动收起菜单
+      if (!v.children || v.children.length <= 1) this.$store.state.themeConfig.themeConfig.isCollapse = true;
+      else if (v.children.length > 1) this.$store.state.themeConfig.themeConfig.isCollapse = false;
+      // this.bus.$emit('setSendColumnsChildren', getMenuSider(this.columnsAsideList, path));
+    },
+    // 设置高亮动态位置
+    onColumnsAsideDown(k) {
+      this.$nextTick(() => {
+        this.setColumnsAsideMove(k);
+      });
+    },
+    // 设置/过滤路由(非静态路由/是否显示在菜单中)
+    setFilterRoutes() {
+      if (this.$store.state.routesList.routesList.length <= 0) return false;
+      this.columnsAsideList = this.filterRoutesFun(this.$store.state.routesList.routesList);
+      //   const resData = getHeaderName(this.$route.path, this.columnsAsideList);
+      const resData = this.setSendChildren(getHeaderName(this.$route, this.columnsAsideList));
+      if (!resData.children) {
+        this.bus.$emit('setSendColumnsChildren', []);
+        this.$store.commit('menus/childMenuList', []);
+
+        this.$store.state.themeConfig.themeConfig.isCollapse = true;
+        return false;
+      }
+      this.bus.$emit('oneCatName', resData.item[0].title);
+      this.onColumnsAsideDown(resData.item[0].k);
+      // 刷新时,初始化一个路由设置自动收起菜单
+      resData.children.length > 0
+        ? (this.$store.state.themeConfig.themeConfig.isCollapse = false)
+        : (this.$store.state.themeConfig.themeConfig.isCollapse = true);
+      this.bus.$emit('setSendColumnsChildren', resData?.children || []);
+      this.$store.commit('menus/childMenuList', resData?.children || []);
+    },
+    // 传送当前子级数据到菜单中
+    setSendChildren(path) {
+      const currentPathSplit = path.split('/');
+      let currentData = {};
+      this.columnsAsideList.map((v, k) => {
+        if (v.path === path) {
+          v['k'] = k;
+          currentData['item'] = [{ ...v }];
+          //   currentData['children'] = [{ ...v }];
+          if (v.children) currentData['children'] = v.children;
+        }
+      });
+      return currentData;
+    },
+    // 路由过滤递归函数
+    filterRoutesFun(arr) {
+      return arr
+        .filter((item) => item.path)
+        .map((item) => {
+          item = Object.assign({}, item);
+          if (item.children) item.children = this.filterRoutesFun(item.children);
+          return item;
+        });
+    },
+    // tagsView 点击时,根据路由查找下标 columnsAsideList,实现左侧菜单高亮
+    setColumnsMenuHighlight(path) {
+      // this.routeSplit = path.split('/');
+      // this.routeSplit.shift();
+      // const routeFirst = `/${this.routeSplit[0]}`;
+      const currentSplitRoute = this.columnsAsideList.find((v) => v.path === path);
+      if (!currentSplitRoute) {
+        // this.onColumnsAsideDown(0);
+        return false;
+      }
+      // 延迟拿值,防止取不到
+      setTimeout(() => {
+        this.onColumnsAsideDown(currentSplitRoute.k);
+      }, 0);
+    },
+  },
+  watch: {
+    // 监听 vuex 数据变化
+    '$store.state': {
+      handler(val) {
+        val.themeConfig.themeConfig.columnsAsideStyle === 'columnsRound'
+          ? (this.difference = 3)
+          : (this.difference = 0);
+        if (val.routesList.routesList.length === this.columnsAsideList.length) return false;
+      },
+      deep: true,
+    },
+    // 监听路由的变化
+    $route: {
+      handler(to) {
+        this.setColumnsMenuHighlight(to.path);
+        // this.setColumnsAsideMove();
+        let HeadName = getHeaderName(to, this.columnsAsideList);
+        let asideList = getMenuSider(this.columnsAsideList, HeadName)[0]?.children;
+        const resData = this.setSendChildren(HeadName);
+        if (resData.length <= 0) return false;
+        this.onColumnsAsideDown(resData.item[0].k);
+        this.bus.$emit('oneCatName', resData.item[0].title);
+        this.bus.$emit('setSendColumnsChildren', asideList || []);
+        this.$store.commit('menus/childMenuList', asideList || []);
+      },
+      deep: true,
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.layout-columns-tra-aside {
+  //   width: 70px;
+  height: 100%;
+  background: var(--prev-bg-columnsMenuBar);
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+  overflow-y: hidden;
+  ul {
+    position: relative;
+    display: flex;
+    li {
+      color: var(--prev-bg-columnsMenuBarColor);
+      width: 80px;
+      height: 50px;
+      text-align: center;
+      display: flex;
+      cursor: pointer;
+      position: relative;
+      z-index: 1;
+      .columns-vertical {
+        margin: auto;
+        .columns-vertical-title {
+          //   padding-top: 1px;
+        }
+      }
+      .columns-horizontal {
+        display: flex;
+        height: 50px;
+        width: 100%;
+        align-items: center;
+        justify-content: center;
+        padding: 0 5px;
+        i {
+          margin-right: 5px;
+        }
+        a {
+          display: flex;
+          .columns-horizontal-title {
+            padding-top: 1px;
+          }
+        }
+      }
+      a {
+        text-decoration: none;
+        color: var(--prev-bg-columnsMenuBarColor);
+      }
+    }
+    .layout-columns {
+      transition: 0.3s ease-in-out;
+    }
+    .layout-columns-active,
+    .layout-columns-active a {
+      color: var(--prev-bg-columnsMenuActiveColor);
+      transition: 0.3s ease-in-out;
+    }
+    .columns-round {
+      background: var(--prev-color-primary);
+      // color: var(--prev-color-text-white);
+      position: absolute;
+      left: 0;
+      //   top: 2px;
+      height: 50px;
+      width: 80px;
+      transform: translatey(0%);
+      z-index: 0;
+      transition: 0.3s ease-in-out;
+      border-radius: 5px;
+    }
+    .columns-card {
+      @extend .columns-round;
+      top: 0;
+      height: 50px;
+      width: 80px;
+      border-radius: 0;
+    }
+  }
+}
+/deep/ .el-scrollbar {
+  height: 50px;
+}
+/deep/ .el-scrollbar__bar.is-horizontal {
+  display: none;
+}
+/deep/ .el-scrollbar__thumb {
+  display: none;
+}
+</style>

+ 1 - 1
template/admin/src/layout/navBars/breadcrumb/breadcrumb.vue

@@ -82,7 +82,7 @@ export default {
     // 动态设置经典、横向布局不显示
     isShowBreadcrumb() {
       const { layout, isBreadcrumb } = this.$store.state.themeConfig.themeConfig;
-      if (layout === 'transverse') {
+      if (layout === 'transverse' || layout === 'classic') {
         return 'none';
       } else {
         return isBreadcrumb ? '' : 'none';

+ 7 - 1
template/admin/src/layout/navBars/breadcrumb/index.vue

@@ -3,6 +3,7 @@
     <Logo v-if="setIsShowLogo" />
     <Breadcrumb />
     <Horizontal :menuList="menuList" v-if="isLayoutTransverse" />
+    <transverseAside v-if="isLayoutClassic" />
     <User />
   </div>
 </template>
@@ -12,9 +13,10 @@ import Breadcrumb from '@/layout/navBars/breadcrumb/breadcrumb.vue';
 import User from '@/layout/navBars/breadcrumb/user.vue';
 import Logo from '@/layout/logo/index.vue';
 import Horizontal from '@/layout/navMenu/horizontal.vue';
+import transverseAside from '@/layout/component/transverseAside.vue';
 export default {
   name: 'layoutNavBars',
-  components: { Breadcrumb, User, Logo, Horizontal },
+  components: { Breadcrumb, User, Logo, Horizontal, transverseAside },
   data() {
     return {
       menuList: [],
@@ -31,6 +33,10 @@ export default {
       let { layout, isClassicSplitMenu } = this.$store.state.themeConfig.themeConfig;
       return layout === 'transverse' || (isClassicSplitMenu && layout === 'classic');
     },
+    isLayoutClassic() {
+      let { layout } = this.$store.state.themeConfig.themeConfig;
+      return layout === 'classic';
+    },
   },
   mounted() {
     this.setFilterRoutes();

+ 8 - 2
template/admin/src/layout/navBars/breadcrumb/setings.vue

@@ -275,7 +275,10 @@
             </el-radio-group>
           </div>
         </div>
-        <div class="layout-breadcrumb-seting-bar-flex mt15" :class="{ mb28: getThemeConfig.layout !== 'columns' }">
+        <div
+          class="layout-breadcrumb-seting-bar-flex mt15"
+          :class="{ mb28: getThemeConfig.layout !== 'columns' && getThemeConfig.layout !== 'classic' }"
+        >
           <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveColumnsAsideStyle') }}</div>
           <div class="layout-breadcrumb-seting-bar-flex-value">
             <el-radio-group v-model="getThemeConfig.columnsAsideStyle" size="mini" @change="setLocalThemeConfig">
@@ -284,7 +287,10 @@
             </el-radio-group>
           </div>
         </div>
-        <div class="layout-breadcrumb-seting-bar-flex mt15 mb28" v-if="getThemeConfig.layout === 'columns'">
+        <div
+          class="layout-breadcrumb-seting-bar-flex mt15 mb28"
+          v-if="getThemeConfig.layout === 'columns' || getThemeConfig.layout === 'classic'"
+        >
           <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveColumnsAsideLayout') }}</div>
           <div class="layout-breadcrumb-seting-bar-flex-value">
             <el-radio-group v-model="getThemeConfig.columnsAsideLayout" size="mini" @change="setLocalThemeConfig">

+ 1 - 1
template/admin/src/layout/navBars/tagsView/tagsView.vue

@@ -418,7 +418,7 @@ export default {
       line-height: 26px;
       display: flex;
       align-items: center;
-      border: 1px solid var(--prev-border-color-lighter);
+      border: 1px solid #ebeef5;
       padding: 0 12px 0 15px;
       margin-right: 5px;
       border-radius: 2px;