wangzs пре 5 месеци
родитељ
комит
11fb95cb96

+ 7 - 44
src/components/framework/icon-select/index.vue

@@ -1,7 +1,7 @@
 <!--
   * 图标 选择
   *
-  * @Author:    DCCloud
+  * @Author:    BoundLink
   * @Date:      2022-09-01 23:14:49
 -->
 <template>
@@ -13,7 +13,6 @@
             <a-radio-button value="outlined">线框风格</a-radio-button>
             <a-radio-button value="filled">实底风格</a-radio-button>
             <a-radio-button value="twoTone">双色风格</a-radio-button>
-            <a-radio-button value="custom">自定义图标</a-radio-button>
           </a-radio-group>
         </a-form-item>
         <a-form-item>
@@ -24,11 +23,7 @@
       <template #content>
         <div class="icon-box">
           <div v-for="item in iconLoopArray" :key="item" @click="handleClick(item)" class="icon-content">
-            <svg v-if="isCustomIcon(item)" class="icon" aria-hidden="true">
-              <use :xlink:href="`#${item}`"></use>
-            </svg>
-            <!-- <img v-if="typeof allIcons[item] === 'string'" :src="allIcons[item]" alt="icon" /> -->
-            <component v-else :is="allIcons[item]" />
+            <component :is="$antIcons[item]" />
           </div>
           <div v-show="showMoreIndex > 0">
             <a-button type="link" @click="showMore">点击展开更多图标(因图标较多,可能会卡一小会)</a-button>
@@ -45,34 +40,12 @@
   import { computed, ref, watch } from 'vue';
   import _ from 'lodash';
 
-  //合并图标对象
-  const allIcons = {
-    ...VueIcon,
-  };
-
   //线框风格图标数组
-  const outlinedIconArray = Object.keys(allIcons).filter((e) => _.endsWith(e.toLowerCase(), 'outlined'));
+  const outlinedIconArray = Object.keys(VueIcon).filter((e) => _.endsWith(e.toLowerCase(), 'outlined'));
   //实底风格图标数组
-  const filledIconArray = Object.keys(allIcons).filter((e) => _.endsWith(e.toLowerCase(), 'filled'));
+  const filledIconArray = Object.keys(VueIcon).filter((e) => _.endsWith(e.toLowerCase(), 'filled'));
   //双色风格图标数组
-  const twoToneIconArray = Object.keys(allIcons).filter((e) => _.endsWith(e.toLowerCase(), 'twotone'));
-  // 添加自定义分类
-  const customIconArray = [
-    'icon-liuchengzhongxin',
-    'icon-daijianguanli',
-    'icon-caiwuguanli',
-    'icon-APPguanli',
-    'icon-yewupeizhi',
-    'icon-zuzhijiagou',
-    'icon-baogaoguanli',
-    'icon-shichangguanli',
-    'icon-jiankongfuwu',
-    'icon-daimashengcheng',
-    'icon-zhuanjiaku',
-    'icon-zhengfuweituo',
-  ];
-
-  const isCustomIcon = (iconName) => customIconArray.includes(iconName);
+  const twoToneIconArray = Object.keys(VueIcon).filter((e) => _.endsWith(e.toLowerCase(), 'twotone'));
 
   // ------------ 显示/隐藏 ------------
   const visible = ref(false);
@@ -99,15 +72,13 @@
 
   let searchValue = ref('');
   function updateSelectIconArray() {
-    let tempArray = [];
+    let tempArray = null;
     if (iconStyle.value === 'outlined') {
       tempArray = outlinedIconArray;
     } else if (iconStyle.value === 'filled') {
       tempArray = filledIconArray;
-    } else if (iconStyle.value === 'twoTone') {
+    } else {
       tempArray = twoToneIconArray;
-    } else if (iconStyle.value === 'custom') {
-      tempArray = customIconArray;
     }
     if (!searchValue.value) {
       selectIconArray.value = tempArray;
@@ -129,13 +100,6 @@
 </script>
 
 <style scoped lang="less">
-  .icon {
-    width: 20px;
-    height: 20px;
-    vertical-align: -0.25em;
-    fill: #000;
-    overflow: hidden;
-  }
   .icon-box {
     overflow: auto;
     font-size: 20px;
@@ -155,7 +119,6 @@
     text-align: center;
     border-radius: 6px;
     border: 1px solid #ccc;
-    background: #ccc;
 
     .more-icon {
       font-size: 14px;

+ 156 - 156
src/layout/components/page-tag/components/default-tab.vue

@@ -1,7 +1,7 @@
 <!--
   * 标签页
   *
-  * @Author:    DCCloud
+  * @Author:    BoundLink
   * @Date:      2022-09-06 20:29:12
 -->
 <template>
@@ -13,7 +13,7 @@
           @tabClick="selectTab">
           <a-tab-pane v-for="item in tagNav" :key="item.menuName">
             <template #tab>
-              <span style="font-size: 16px;">
+              <span>
                 {{ item.menuTitle }}
                 <close-outlined @click.stop="closeTag(item, false)" v-if="item.menuName !== HOME_PAGE_NAME"
                   class="smart-page-tag-close" />
@@ -51,182 +51,182 @@
 </template>
 
 <script setup>
-import { AppstoreOutlined, CloseOutlined } from '@ant-design/icons-vue';
-import { computed, ref, watch } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
-import { useAppConfigStore } from '/@/store/modules/system/app-config';
-import { useUserStore } from '/@/store/modules/system/user';
-import { theme } from 'ant-design-vue';
-
-//标签页 是否显示
-const pageTagFlag = computed(() => useAppConfigStore().$state.pageTagFlag);
-
-const router = useRouter();
-const route = useRoute();
-const mode = ref('top');
-const tagNav = computed(() => useUserStore().getTagNav || []);
-const selectedKey = ref(route.name);
-const emit = defineEmits(['refresh-event']);
-
-watch(
-  () => route.name,
-  (newValue, oldValue) => {
-    selectedKey.value = newValue;
-  },
-  { immediate: true }
-);
-
-//刷新Tab页面
-function refreshTab() {
-  emit('refresh-event');
-}
-
-//选择某个标签页
-function selectTab(name) {
-  if (selectedKey.value === name) {
-    return;
+  import { AppstoreOutlined, CloseOutlined } from '@ant-design/icons-vue';
+  import { computed, ref, watch } from 'vue';
+  import { useRoute, useRouter } from 'vue-router';
+  import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
+  import { useAppConfigStore } from '/@/store/modules/system/app-config';
+  import { useUserStore } from '/@/store/modules/system/user';
+  import { theme } from 'ant-design-vue';
+
+  //标签页 是否显示
+  const pageTagFlag = computed(() => useAppConfigStore().$state.pageTagFlag);
+
+  const router = useRouter();
+  const route = useRoute();
+  const mode = ref('top');
+  const tagNav = computed(() => useUserStore().getTagNav || []);
+  const selectedKey = ref(route.name);
+  const emit = defineEmits(['refresh-event']);
+
+  watch(
+    () => route.name,
+    (newValue, oldValue) => {
+      selectedKey.value = newValue;
+    },
+    { immediate: true }
+  );
+
+  //刷新Tab页面
+  function refreshTab() {
+    emit('refresh-event');
   }
-  // 寻找tag
-  let tag = tagNav.value.find((e) => e.menuName === name);
-  if (!tag) {
-    router.push({ name: HOME_PAGE_NAME });
-    return;
-  }
-  // router.push({ name, query: Object.assign({ _keepAlive: 1 }, tag.menuQuery) });
-  router.push({ name, query: tag.menuQuery });
-}
-
-//通过菜单关闭
-function closeByMenu(closeAll) {
-  let find = tagNav.value.find((e) => e.menuName === selectedKey.value);
-  if (!find || closeAll) {
-    closeTag(null, true);
-  } else {
-    closeTag(find, true);
+
+  //选择某个标签页
+  function selectTab(name) {
+    if (selectedKey.value === name) {
+      return;
+    }
+    // 寻找tag
+    let tag = tagNav.value.find((e) => e.menuName === name);
+    if (!tag) {
+      router.push({ name: HOME_PAGE_NAME });
+      return;
+    }
+    // router.push({ name, query: Object.assign({ _keepAlive: 1 }, tag.menuQuery) });
+    router.push({ name, query: tag.menuQuery });
   }
-}
-
-//直接关闭
-function closeTag(item, closeAll) {
-  // 关闭单个tag
-  if (item && !closeAll) {
-    let goName = HOME_PAGE_NAME;
-    let goQuery = undefined;
-    if (item.fromMenuName && item.fromMenuName !== item.menuName && tagNav.value.some((e) => e.menuName === item.fromMenuName)) {
-      goName = item.fromMenuName;
-      goQuery = item.fromMenuQuery;
+
+  //通过菜单关闭
+  function closeByMenu(closeAll) {
+    let find = tagNav.value.find((e) => e.menuName === selectedKey.value);
+    if (!find || closeAll) {
+      closeTag(null, true);
     } else {
-      // 查询左侧tag
-      let index = tagNav.value.findIndex((e) => e.menuName === item.menuName);
-      if (index > 0) {
+      closeTag(find, true);
+    }
+  }
+
+  //直接关闭
+  function closeTag(item, closeAll) {
+    // 关闭单个tag
+    if (item && !closeAll) {
+      let goName = HOME_PAGE_NAME;
+      let goQuery = undefined;
+      if (item.fromMenuName && item.fromMenuName !== item.menuName && tagNav.value.some((e) => e.menuName === item.fromMenuName)) {
+        goName = item.fromMenuName;
+        goQuery = item.fromMenuQuery;
+      } else {
         // 查询左侧tag
-        let leftTagNav = tagNav.value[index - 1];
-        goName = leftTagNav.menuName;
-        goQuery = leftTagNav.menuQuery;
+        let index = tagNav.value.findIndex((e) => e.menuName === item.menuName);
+        if (index > 0) {
+          // 查询左侧tag
+          let leftTagNav = tagNav.value[index - 1];
+          goName = leftTagNav.menuName;
+          goQuery = leftTagNav.menuQuery;
+        }
       }
+      // router.push({ name: goName, query: Object.assign({ _keepAlive: 1 }, goQuery) });
+      router.push({ name: goName, query: goQuery });
+    } else if (!item && closeAll) {
+      // 关闭所有tag
+      router.push({ name: HOME_PAGE_NAME });
     }
-    // router.push({ name: goName, query: Object.assign({ _keepAlive: 1 }, goQuery) });
-    router.push({ name: goName, query: goQuery });
-  } else if (!item && closeAll) {
-    // 关闭所有tag
-    router.push({ name: HOME_PAGE_NAME });
+    // 关闭其他tag不做处理 直接调用closeTagNav
+    useUserStore().closeTagNav(item ? item.menuName : null, closeAll);
   }
-  // 关闭其他tag不做处理 直接调用closeTagNav
-  useUserStore().closeTagNav(item ? item.menuName : null, closeAll);
-}
 
-const { useToken } = theme;
-const { token } = useToken();
-const borderRadius = token.value.borderRadius + 'px';
+  const { useToken } = theme;
+  const { token } = useToken();
+  const borderRadius = token.value.borderRadius + 'px';
 </script>
 
 <style scoped lang="less">
-@smart-page-tag-operate-width: 40px;
-@color-primary: v-bind('token.colorPrimary');
-
-.smart-page-tag-operate {
-  width: @smart-page-tag-operate-width;
-  height: @smart-page-tag-operate-width;
-  background-color: #ffffff;
-  font-size: 17px;
-  text-align: center;
-  vertical-align: middle;
-  line-height: @smart-page-tag-operate-width;
-  padding-right: 10px;
-  cursor: pointer;
-  color: #606266;
-
-  .smart-page-tag-operate-icon {
-    width: 20px;
-    height: 20px;
-    transition: all 1s;
-    transform-origin: 10px 20px;
-  }
+  @smart-page-tag-operate-width: 40px;
+  @color-primary: v-bind('token.colorPrimary');
+
+  .smart-page-tag-operate {
+    width: @smart-page-tag-operate-width;
+    height: @smart-page-tag-operate-width;
+    background-color: #ffffff;
+    font-size: 17px;
+    text-align: center;
+    vertical-align: middle;
+    line-height: @smart-page-tag-operate-width;
+    padding-right: 10px;
+    cursor: pointer;
+    color: #606266;
+
+    .smart-page-tag-operate-icon {
+      width: 20px;
+      height: 20px;
+      transition: all 1s;
+      transform-origin: 10px 20px;
+    }
 
-  .smart-page-tag-operate-icon:hover {
-    width: 20px;
-    height: 20px;
-    transform: rotate(360deg);
+    .smart-page-tag-operate-icon:hover {
+      width: 20px;
+      height: 20px;
+      transform: rotate(360deg);
+    }
   }
-}
-
-.smart-page-tag-operate:hover {
-  color: @color-primary;
-}
-
-.smart-page-tag {
-  position: relative;
-  box-sizing: border-box;
-  display: flex;
-  align-content: center;
-  align-items: center;
-  justify-content: space-between;
-  min-height: @page-tag-height;
-  padding-right: 20px;
-  padding-left: 20px;
-  user-select: none;
-  background: #fff;
-  width: calc(100% - @smart-page-tag-operate-width);
-
-  .smart-page-tag-close {
-    margin-left: 5px;
-    font-size: 10px;
-    color: #666666;
+
+  .smart-page-tag-operate:hover {
+    color: @color-primary;
   }
 
-  /**  覆盖 ant design vue的 tabs 样式,变小一点 **/
+  .smart-page-tag {
+    position: relative;
+    box-sizing: border-box;
+    display: flex;
+    align-content: center;
+    align-items: center;
+    justify-content: space-between;
+    min-height: @page-tag-height;
+    padding-right: 20px;
+    padding-left: 20px;
+    user-select: none;
+    background: #fff;
+    width: calc(100% - @smart-page-tag-operate-width);
 
-  :deep(.ant-tabs-nav) {
-    margin: 0;
-    padding: 0 0 2px 0;
-    max-height: 32px;
-  }
+    .smart-page-tag-close {
+      margin-left: 5px;
+      font-size: 10px;
+      color: #666666;
+    }
 
-  :deep(.ant-tabs-nav::before) {
-    border-bottom: 1px solid #ffffff;
-  }
+    /**  覆盖 ant design vue的 tabs 样式,变小一点 **/
 
-  :deep(.ant-tabs-small > .ant-tabs-nav .ant-tabs-tab) {
-    padding: 5px 8px 3px 20px;
-    border-radius: v-bind(borderRadius);
-    margin: 0 0 0 5px !important;
-  }
+    :deep(.ant-tabs-nav) {
+      margin: 0;
+      padding: 0 0 2px 0;
+      max-height: 32px;
+    }
 
-  :deep(.ant-tabs-tab-active) {
-    background-color: #eeeeee;
+    :deep(.ant-tabs-nav::before) {
+      border-bottom: 1px solid #ffffff;
+    }
 
-    .smart-page-tag-close {
-      color: @color-primary;
+    :deep(.ant-tabs-small > .ant-tabs-nav .ant-tabs-tab) {
+      padding: 5px 8px 3px 20px;
+      border-radius: v-bind(borderRadius);
+      margin: 0 0 0 5px !important;
     }
-  }
 
-  :deep(.ant-tabs-nav .ant-tabs-tab:hover) {
-    background-color: #eeeeee;
+    :deep(.ant-tabs-tab-active) {
+      background-color: #eeeeee;
 
-    .smart-page-tag-close {
-      color: @color-primary;
+      .smart-page-tag-close {
+        color: @color-primary;
+      }
+    }
+
+    :deep(.ant-tabs-nav .ant-tabs-tab:hover) {
+      background-color: #eeeeee;
+
+      .smart-page-tag-close {
+        color: @color-primary;
+      }
     }
   }
-}
-</style>
+</style>

+ 6 - 39
src/layout/components/side-menu/recursion-menu.vue

@@ -1,8 +1,8 @@
 <!--
   * 传统菜单-递归菜单
-  *
-  * @Author:    DCCloud
-  * @Date:      2022-09-06 20:29:12
+  * 
+  * @Author:    BoundLink 
+  * @Date:      2022-09-06 20:29:12 
 -->
 <template>
   <a-menu v-model:openKeys="openKeys" v-model:selectedKeys="selectedKeys" class="smart-menu" mode="inline"
@@ -12,20 +12,13 @@
         <template v-if="$lodash.isEmpty(item.children)">
           <a-menu-item :key="item.menuId" @click="turnToPage(item)">
             <template #icon>
-              <svg v-if="isCustomIcon(item.icon)" class="icon" aria-hidden="true">
-                <use :xlink:href="`#${item.icon}`"></use>
-              </svg>
-              <component v-else :is="$antIcons[item.icon]" />
+              <component :is="$antIcons[item.icon]" />
             </template>
-            <span style="font-size: 16px;">
-              {{ item.menuName }}
-            </span>
+            {{ item.menuName }}
           </a-menu-item>
         </template>
         <template v-else>
           <SubMenu :menu-info="item" :key="item.menuId" @turnToPage="turnToPage" />
-          <div v-if="collapsed" style="text-align: center; margin: 6px 0 22px 0;font-size: 16px;">{{ item.menuName }}
-          </div>
         </template>
       </template>
     </template>
@@ -49,25 +42,7 @@ const props = defineProps({
   },
 });
 
-// 添加自定义分类
-const customIconArray = [
-  'icon-liuchengzhongxin',
-  'icon-daijianguanli',
-  'icon-caiwuguanli',
-  'icon-APPguanli',
-  'icon-yewupeizhi',
-  'icon-zuzhijiagou',
-  'icon-baogaoguanli',
-  'icon-shichangguanli',
-  'icon-jiankongfuwu',
-  'icon-daimashengcheng',
-  'icon-zhuanjiaku',
-  'icon-zhengfuweituo',
-];
-const isCustomIcon = (iconName) => customIconArray.includes(iconName);
-
 const menuTree = computed(() => useUserStore().getMenuTree || []);
-// console.log('menuTree', menuTree);
 
 //展开的菜单
 let currentRoute = useRoute();
@@ -81,7 +56,7 @@ function turnToPage(menu) {
 }
 
 /**
- * DCCloud中 router的name 就是 后端存储menu的id
+ * BoundLink中 router的name 就是 后端存储menu的id
  * 所以此处可以直接监听路由,根据路由更新菜单的选中和展开
  */
 function updateOpenKeysAndSelectKeys() {
@@ -121,13 +96,5 @@ defineExpose({
 <style lang="less" scoped>
 .smart-menu {
   position: relative;
-
-  .icon {
-    width: 20px;
-    height: 20px;
-    vertical-align: -0.25em;
-    fill: #fff;
-    overflow: hidden;
-  }
 }
 </style>

+ 7 - 45
src/layout/components/side-menu/sub-menu.vue

@@ -1,35 +1,23 @@
 <!--
   * 传统菜单-递归菜单
-  *
-  * @Author:    DCCloud
-  * @Date:      2022-09-06 20:29:12
+  * 
+  * @Author:    BoundLink 
+  * @Date:      2022-09-06 20:29:12 
 -->
 <template>
   <a-sub-menu :key="menuInfo.menuId">
     <template #icon>
-      <svg v-if="isCustomIcon(menuInfo.icon)" class="icon" aria-hidden="true">
-        <use :xlink:href="`#${menuInfo.icon}`"></use>
-      </svg>
-      <component v-else :is="$antIcons[menuInfo.icon]" />
-    </template>
-    <template #title>
-      <span style="font-size: 16px;">
-        {{ menuInfo.menuName }}
-      </span>
+      <component :is="$antIcons[menuInfo.icon]" />
     </template>
+    <template #title>{{ menuInfo.menuName }}</template>
     <template v-for="item in menuInfo.children" :key="item.menuId">
       <template v-if="item.visibleFlag && !item.disabledFlag">
         <template v-if="!item.children">
           <a-menu-item :key="item.menuId" @click="turnToPage(item)">
             <template #icon>
-              <svg v-if="isCustomIcon(item.icon)" class="icon" aria-hidden="true">
-                <use :xlink:href="`#${item.icon}`"></use>
-              </svg>
-              <component v-else :is="$antIcons[item.icon]" />
+              <component :is="$antIcons[item.icon]" />
             </template>
-            <span style="font-size: 16px;">
-              {{ item.menuName }}
-            </span>
+            {{ item.menuName }}
           </a-menu-item>
         </template>
         <template v-else>
@@ -51,30 +39,4 @@ const emits = defineEmits(['turnToPage']);
 const turnToPage = (menu) => {
   emits('turnToPage', menu);
 };
-
-// 添加自定义分类
-const customIconArray = [
-  'icon-liuchengzhongxin',
-  'icon-daijianguanli',
-  'icon-caiwuguanli',
-  'icon-APPguanli',
-  'icon-yewupeizhi',
-  'icon-zuzhijiagou',
-  'icon-baogaoguanli',
-  'icon-shichangguanli',
-  'icon-jiankongfuwu',
-  'icon-daimashengcheng',
-  'icon-zhuanjiaku',
-  'icon-zhengfuweituo',
-];
-const isCustomIcon = (iconName) => customIconArray.includes(iconName);
 </script>
-<style>
-.icon {
-  width: 14px;
-  height: 14px;
-  vertical-align: -0.25em;
-  fill: #a6adb4;
-  overflow: hidden;
-}
-</style>

+ 203 - 193
src/layout/side-layout.vue

@@ -37,11 +37,15 @@
       <!--中间内容-->
       <a-layout-content id="smartAdminLayoutContent" class="admin-layout-content">
         <!--不keepAlive的iframe使用单个iframe组件-->
-        <IframeIndex v-if="iframeNotKeepAlivePageFlag" :key="route.name" :name="route.name"
-          :url="route.meta.frameUrl" />
+        <IframeIndex v-if="iframeNotKeepAlivePageFlag" :key="route.name" :name="route.name" :url="route.meta.frameUrl" />
         <!--keepAlive的iframe 每个页面一个iframe组件-->
-        <IframeIndex v-for="item in keepAliveIframePages" v-show="route.name == item.name" :key="item.name"
-          :name="item.name" :url="item.meta.frameUrl" />
+        <IframeIndex
+          v-for="item in keepAliveIframePages"
+          v-show="route.name == item.name"
+          :key="item.name"
+          :name="item.name"
+          :url="item.meta.frameUrl"
+        />
         <!--非iframe使用router-view-->
         <div v-show="!iframeNotKeepAlivePageFlag && keepAliveIframePages.every((e) => route.name != e.name)">
           <router-view v-slot="{ Component }" v-if="isRouterAlive">
@@ -67,237 +71,243 @@
       <a-back-top :target="backTopTarget" :visibilityHeight="80" />
     </a-layout>
     <!-- 右侧帮助文档 help-doc -->
-    <a-layout-sider v-if="helpDocFlag" v-show="helpDocExpandFlag" theme="light" :width="180" class="help-doc-sider"
-      :trigger="null" style="min-height: 100%">
+    <a-layout-sider
+      v-if="helpDocFlag"
+      v-show="helpDocExpandFlag"
+      theme="light"
+      :width="180"
+      class="help-doc-sider"
+      :trigger="null"
+      style="min-height: 100%"
+    >
       <SideHelpDoc />
     </a-layout-sider>
   </a-layout>
 </template>
 
 <script setup>
-import { computed, onMounted, ref, watch, nextTick } from 'vue';
-import { useAppConfigStore } from '../store/modules/system/app-config';
-import HeaderUserSpace from './components/header-user-space/index.vue';
-import MenuLocationBreadcrumb from './components/menu-location-breadcrumb/index.vue';
-import PageTag from './components/page-tag/index.vue';
-import SideMenu from './components/side-menu/index.vue';
-import SmartFooter from './components/smart-footer/index.vue';
-import { smartKeepAlive } from './components/smart-keep-alive';
-import IframeIndex from '/@/components/framework/iframe/iframe-index.vue';
-import watermark from '../lib/smart-watermark';
-import { useUserStore } from '/@/store/modules/system/user';
-import SideHelpDoc from './components/side-help-doc/index.vue';
-import { useRouter } from 'vue-router';
-import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
-
-const windowHeight = ref(window.innerHeight);
-//菜单宽度
-const sideMenuWidth = computed(() => useAppConfigStore().$state.sideMenuWidth);
-//主题颜色
-const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
-//是否显示标签页
-const pageTagFlag = computed(() => useAppConfigStore().$state.pageTagFlag);
-// 是否显示帮助文档
-const helpDocFlag = computed(() => useAppConfigStore().$state.helpDocFlag);
-// 是否默认展开帮助文档
-const helpDocExpandFlag = computed(() => useAppConfigStore().$state.helpDocExpandFlag);
-// 是否显示页脚
-const footerFlag = computed(() => useAppConfigStore().$state.footerFlag);
-// 是否显示水印
-const watermarkFlag = computed(() => useAppConfigStore().$state.watermarkFlag);
-// 多余高度
-const dueHeight = computed(() => {
-  let due = 40;
-  if (useAppConfigStore().$state.pageTagFlag) {
-    due = due + 40;
-  }
-  if (useAppConfigStore().$state.footerFlag) {
-    due = due + 40;
-  }
-  return due;
-});
-//是否隐藏菜单
-const collapsed = ref(false);
-
-
-//页面初始化的时候加载水印
-onMounted(() => {
-  if (watermarkFlag.value) {
-    watermark.set('smartAdminLayoutContent', useUserStore().actualName);
-  } else {
-    watermark.clear();
-  }
-});
-
-watch(
-  () => watermarkFlag.value,
-  (newValue) => {
-    if (newValue) {
+  import { computed, onMounted, ref, watch, nextTick } from 'vue';
+  import { useAppConfigStore } from '../store/modules/system/app-config';
+  import HeaderUserSpace from './components/header-user-space/index.vue';
+  import MenuLocationBreadcrumb from './components/menu-location-breadcrumb/index.vue';
+  import PageTag from './components/page-tag/index.vue';
+  import SideMenu from './components/side-menu/index.vue';
+  import SmartFooter from './components/smart-footer/index.vue';
+  import { smartKeepAlive } from './components/smart-keep-alive';
+  import IframeIndex from '/@/components/framework/iframe/iframe-index.vue';
+  import watermark from '../lib/smart-watermark';
+  import { useUserStore } from '/@/store/modules/system/user';
+  import SideHelpDoc from './components/side-help-doc/index.vue';
+  import { useRouter } from 'vue-router';
+  import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
+
+  const windowHeight = ref(window.innerHeight);
+  //菜单宽度
+  const sideMenuWidth = computed(() => useAppConfigStore().$state.sideMenuWidth);
+  //主题颜色
+  const theme = computed(() => useAppConfigStore().$state.sideMenuTheme);
+  //是否显示标签页
+  const pageTagFlag = computed(() => useAppConfigStore().$state.pageTagFlag);
+  // 是否显示帮助文档
+  const helpDocFlag = computed(() => useAppConfigStore().$state.helpDocFlag);
+  // 是否默认展开帮助文档
+  const helpDocExpandFlag = computed(() => useAppConfigStore().$state.helpDocExpandFlag);
+  // 是否显示页脚
+  const footerFlag = computed(() => useAppConfigStore().$state.footerFlag);
+  // 是否显示水印
+  const watermarkFlag = computed(() => useAppConfigStore().$state.watermarkFlag);
+  // 多余高度
+  const dueHeight = computed(() => {
+    let due = 40;
+    if (useAppConfigStore().$state.pageTagFlag) {
+      due = due + 40;
+    }
+    if (useAppConfigStore().$state.footerFlag) {
+      due = due + 40;
+    }
+    return due;
+  });
+  //是否隐藏菜单
+  const collapsed = ref(false);
+
+  //页面初始化的时候加载水印
+  onMounted(() => {
+    if (watermarkFlag.value) {
       watermark.set('smartAdminLayoutContent', useUserStore().actualName);
     } else {
       watermark.clear();
     }
+  });
+
+  watch(
+    () => watermarkFlag.value,
+    (newValue) => {
+      if (newValue) {
+        watermark.set('smartAdminLayoutContent', useUserStore().actualName);
+      } else {
+        watermark.clear();
+      }
+    }
+  );
+
+  //回到顶部
+  const backTopTarget = () => {
+    return document.getElementById('smartAdminMain');
+  };
+
+  const router = useRouter();
+  function goHome() {
+    router.push({ name: HOME_PAGE_NAME });
   }
-);
-
-//回到顶部
-const backTopTarget = () => {
-  return document.getElementById('smartAdminMain');
-};
-
-const router = useRouter();
-function goHome() {
-  router.push({ name: HOME_PAGE_NAME });
-}
-
-//刷新当前页面
-const isRouterAlive = ref(true);
-function hanldeRefresh() {
-  isRouterAlive.value = false
-  nextTick(() => {
-    isRouterAlive.value = true
-  })
-}
-
-window.addEventListener('resize', function () {
-  windowHeight.value = window.innerHeight;
-});
-
-// ----------------------- keep-alive相关 -----------------------
-let { route, keepAliveIncludes, iframeNotKeepAlivePageFlag, keepAliveIframePages } = smartKeepAlive();
+
+  //刷新当前页面
+  const isRouterAlive = ref(true);
+  function hanldeRefresh() {
+    isRouterAlive.value = false;
+    nextTick(() => {
+      isRouterAlive.value = true;
+    });
+  }
+
+  window.addEventListener('resize', function () {
+    windowHeight.value = window.innerHeight;
+  });
+
+  // ----------------------- keep-alive相关 -----------------------
+  let { route, keepAliveIncludes, iframeNotKeepAlivePageFlag, keepAliveIframePages } = smartKeepAlive();
 </script>
 
 <style lang="less" scoped>
-:deep(.ant-layout-header) {
-  height: auto;
-}
-
-:deep(.layout-header) {
-  height: auto;
-}
-
-.layout-header {
-  background: #fff;
-  padding: 0;
-  z-index: 21;
-}
-
-.layout-header-user {
-  height: @header-user-height;
-  border-bottom: 1px solid #f6f6f6;
-}
-
-.layout-header-left {
-  display: flex;
-  height: @header-user-height;
-
-  .collapsed-button {
-    margin-left: 10px;
-    line-height: @header-user-height;
+  :deep(.ant-layout-header) {
+    height: auto;
   }
 
-  .home-button {
-    margin-left: 15px;
-    cursor: pointer;
-    padding: 0 5px;
-    line-height: @header-user-height;
+  :deep(.layout-header) {
+    height: auto;
   }
 
-  .home-button:hover {
-    background-color: #efefef;
+  .layout-header {
+    background: #fff;
+    padding: 0;
+    z-index: 21;
   }
 
-  .location-breadcrumb {
-    margin-left: 15px;
-    line-height: @header-user-height;
+  .layout-header-user {
+    height: @header-user-height;
+    border-bottom: 1px solid #f6f6f6;
   }
-}
 
-.layout-header-right {
-  display: flex;
-  height: @header-user-height;
-}
+  .layout-header-left {
+    display: flex;
+    height: @header-user-height;
 
-.layout-container {
-  height: calc(100vh - @header-height);
-  overflow-x: hidden;
-}
+    .collapsed-button {
+      margin-left: 10px;
+      line-height: @header-user-height;
+    }
 
-.admin-layout {
-  .side-menu {
-    height: 100vh;
-    overflow-x: hidden;
-    overflow-y: scroll;
+    .home-button {
+      margin-left: 15px;
+      cursor: pointer;
+      padding: 0 5px;
+      line-height: @header-user-height;
+    }
 
-    &.fixed-side {
-      position: fixed;
-      height: 100vh;
-      left: 0;
-      top: 0;
+    .home-button:hover {
+      background-color: #efefef;
     }
-  }
 
-  .side-menu::-webkit-scrollbar {
-    width: 4px;
+    .location-breadcrumb {
+      margin-left: 15px;
+      line-height: @header-user-height;
+    }
   }
 
-  .side-menu::-webkit-scrollbar-thumb {
-    border-radius: 10px;
-    background: rgba(0, 0, 0, 0.2);
+  .layout-header-right {
+    display: flex;
+    height: @header-user-height;
   }
 
-  .side-menu::-webkit-scrollbar-track {
-    border-radius: 0;
-    background: rgba(0, 0, 0, 0.1);
+  .layout-container {
+    height: calc(100vh - @header-height);
+    overflow-x: hidden;
   }
 
-  .help-doc-sider {
-    flex: 0 !important;
-    min-width: 100px;
-    height: 100vh;
-    max-width: 100px;
-    width: auto !important;
+  .admin-layout {
+    .side-menu {
+      height: 100vh;
+      overflow-x: hidden;
+      overflow-y: scroll;
+
+      &.fixed-side {
+        position: fixed;
+        height: 100vh;
+        left: 0;
+        top: 0;
+      }
+    }
+
+    .side-menu::-webkit-scrollbar {
+      width: 4px;
+    }
+
+    .side-menu::-webkit-scrollbar-thumb {
+      border-radius: 10px;
+      background: rgba(0, 0, 0, 0.2);
+    }
+
+    .side-menu::-webkit-scrollbar-track {
+      border-radius: 0;
+      background: rgba(0, 0, 0, 0.1);
+    }
 
-    &.fixed-side {
-      position: fixed;
+    .help-doc-sider {
+      flex: 0 !important;
+      min-width: 100px;
       height: 100vh;
-      right: 0;
-      top: 0;
+      max-width: 100px;
+      width: auto !important;
+
+      &.fixed-side {
+        position: fixed;
+        height: 100vh;
+        right: 0;
+        top: 0;
+      }
     }
-  }
 
-  .virtual-side {
-    transition: all 0.2s;
-  }
+    .virtual-side {
+      transition: all 0.2s;
+    }
 
-  .virtual-header {
-    transition: all 0.2s;
-    opacity: 0;
+    .virtual-header {
+      transition: all 0.2s;
+      opacity: 0;
 
-    &.fixed-tabs.multi-page:not(.fixed-header) {
-      height: 0;
+      &.fixed-tabs.multi-page:not(.fixed-header) {
+        height: 0;
+      }
     }
-  }
 
-  .admin-layout-main {
-    overflow-y: hidden;
-    overflow-x: hidden;
+    .admin-layout-main {
+      overflow-y: hidden;
+      overflow-x: hidden;
+    }
+
+    .admin-layout-content {
+      background-color: inherit;
+      min-height: auto;
+      position: relative;
+      overflow-x: hidden;
+      padding: 10px 10px 10px 10px;
+      height: calc(100% - v-bind(dueHeight) px);
+    }
   }
 
-  .admin-layout-content {
-    background-color: inherit;
-    min-height: auto;
+  .layout-footer {
     position: relative;
-    overflow-x: hidden;
-    padding: 10px 10px 10px 10px;
-    height: calc(100% - v-bind(dueHeight) px);
+    padding: 7px 0px;
+    display: flex;
+    justify-content: center;
   }
-}
-
-.layout-footer {
-  position: relative;
-  padding: 7px 0px;
-  display: flex;
-  justify-content: center;
-}
-</style>
+</style>

+ 0 - 1
src/main.js

@@ -29,7 +29,6 @@ import 'vue3-tabs-chrome/dist/vue3-tabs-chrome.css';
 import '/@/theme/index.less';
 import { localRead } from '/@/utils/local-util.js';
 import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
-import '/@/assets/iconfont/iconfont.js';
 
 // 引入vxe-table
 import VxeUI from 'vxe-pc-ui'

+ 20 - 14
src/store/modules/system/user.js

@@ -5,14 +5,14 @@
  * @Date:      2022-09-06 20:55:09
  */
 import _ from 'lodash';
-import {defineStore} from 'pinia';
+import { defineStore } from 'pinia';
 import localKey from '/@/constants/local-storage-key-const';
-import {HOME_PAGE_NAME} from '/@/constants/system/home-const';
-import {MENU_TYPE_ENUM} from '/@/constants/system/menu-const';
-import {messageApi} from '/@/api/support/message-api.js';
-import {smartSentry} from '/@/lib/smart-sentry.js';
-import {loginApi} from '/@/api/system/login-api';
-import {localRead, localSave, localRemove} from '/@/utils/local-util';
+import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
+import { MENU_TYPE_ENUM } from '/@/constants/system/menu-const';
+import { messageApi } from '/@/api/support/message-api.js';
+import { smartSentry } from '/@/lib/smart-sentry.js';
+import { loginApi } from '/@/api/system/login-api';
+import { localRead, localSave, localRemove } from '/@/utils/local-util';
 import { autoCompleteProps } from 'ant-design-vue/lib/auto-complete';
 
 export const useUserStore = defineStore({
@@ -115,13 +115,13 @@ export const useUserStore = defineStore({
 
     actions: {
         autoLogin(name) {
-          return new Promise((resolve, reject) => {
+            return new Promise((resolve, reject) => {
                 loginApi.autoLogin(name).then(res => {
                     resolve(res)
                 }).catch(error => {
                     reject(error)
                 })
-            })  
+            })
         },
         setSSO(info) {
             return new Promise((resolve, reject) => {
@@ -216,6 +216,12 @@ export const useUserStore = defineStore({
                 // @ts-ignore
                 findTag.fromMenuName = from.name;
                 findTag.fromMenuQuery = from.query;
+
+                for (const i of this.tagNav) {
+                    if (i.menuName === name) {
+                        i.menuQuery = route.query
+                    }
+                }
             } else {
                 // @ts-ignore
                 this.tagNav.push({
@@ -259,20 +265,20 @@ export const useUserStore = defineStore({
         closePage(route, router, path) {
             if (!this.getTagNav || _.isEmpty(this.getTagNav)) return;
             if (path) {
-                router.push({path});
+                router.push({ path });
             } else {
                 // 寻找tagNav
                 let index = this.getTagNav.findIndex((e) => e.menuName === route.name);
                 if (index === -1) {
-                    router.push({name: HOME_PAGE_NAME});
+                    router.push({ name: HOME_PAGE_NAME });
                 } else {
                     let tagNav = this.getTagNav[index];
                     if (tagNav.fromMenuName && this.getTagNav.some((e) => e.menuName === tagNav.fromMenuName)) {
-                        router.push({name: tagNav.fromMenuName, query: tagNav.fromMenuQuery});
+                        router.push({ name: tagNav.fromMenuName, query: tagNav.fromMenuQuery });
                     } else {
                         // 查询左侧tag
                         let leftTagNav = this.getTagNav[index - 1];
-                        router.push({name: leftTagNav.menuName, query: leftTagNav.menuQuery});
+                        router.push({ name: leftTagNav.menuName, query: leftTagNav.menuQuery });
                     }
                 }
             }
@@ -333,7 +339,7 @@ function recursiveBuildMenuParentIdListMap(menuList, parentMenuList, menuParentI
         let cloneParentMenuList = _.cloneDeep(parentMenuList);
         if (!_.isEmpty(e.children) && e.menuName) {
             // 递归
-            cloneParentMenuList.push({name: menuIdStr, title: e.menuName});
+            cloneParentMenuList.push({ name: menuIdStr, title: e.menuName });
             recursiveBuildMenuParentIdListMap(e.children, cloneParentMenuList, menuParentIdListMap);
         } else {
             menuParentIdListMap.set(menuIdStr, cloneParentMenuList);

+ 1 - 29
src/views/system/menu/components/menu-operate-modal.vue

@@ -32,10 +32,7 @@
           <IconSelect @updateIcon="selectIcon">
             <template #iconSelect>
               <a-input v-model:value="form.icon" placeholder="请输入菜单图标" style="width: 200px" />
-              <svg v-if="isCustomIcon(form.icon)" class="icon" aria-hidden="true">
-                <use :xlink:href="`#${form.icon}`"></use>
-              </svg>
-              <component v-else :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px" />
+              <component :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px" />
             </template>
           </IconSelect>
         </a-form-item>
@@ -143,23 +140,6 @@
   const contextMenuTreeSelect = ref();
   const parentMenuTreeSelect = ref();
 
-  // 添加自定义分类
-  const customIconArray = [
-    'icon-liuchengzhongxin',
-    'icon-daijianguanli',
-    'icon-caiwuguanli',
-    'icon-APPguanli',
-    'icon-yewupeizhi',
-    'icon-zuzhijiagou',
-    'icon-baogaoguanli',
-    'icon-shichangguanli',
-    'icon-jiankongfuwu',
-    'icon-daimashengcheng',
-    'icon-zhuanjiaku',
-    'icon-zhengfuweituo',
-  ];
-  const isCustomIcon = (iconName) => customIconArray.includes(iconName);
-
   //展开编辑窗口
   async function showDrawer(rowData) {
     Object.assign(form, formDefault);
@@ -302,14 +282,6 @@
   });
 </script>
 <style lang="less" scoped>
-  .icon {
-    width: 20px;
-    height: 20px;
-    vertical-align: -0.25em;
-    fill: #000;
-    overflow: hidden;
-    margin-left: 16px;
-  }
   .footer {
     position: absolute;
     right: 0;

+ 2 - 22
src/views/system/menu/menu-list.vue

@@ -1,7 +1,7 @@
 <!--
   * 菜单列表
   *
-  * @Author:    DCCloud
+  * @Author:    BoundLink
   * @Date:      2022-06-12 20:11:39
 -->
 <template>
@@ -123,10 +123,7 @@
           </template>
 
           <template v-if="column.dataIndex === 'icon'">
-            <svg v-if="isCustomIcon(text)" class="icon" aria-hidden="true" style="fill: #1c1c1c">
-              <use :xlink:href="`#${text}`"></use>
-            </svg>
-            <component v-else :is="$antIcons[text]" />
+            <component :is="$antIcons[text]" />
           </template>
 
           <template v-if="column.dataIndex === 'operate'">
@@ -173,23 +170,6 @@
   //展开更多查询参数
   const moreQueryConditionFlag = ref(true);
 
-  // 添加自定义分类
-  const customIconArray = [
-    'icon-liuchengzhongxin',
-    'icon-daijianguanli',
-    'icon-caiwuguanli',
-    'icon-APPguanli',
-    'icon-yewupeizhi',
-    'icon-zuzhijiagou',
-    'icon-baogaoguanli',
-    'icon-shichangguanli',
-    'icon-jiankongfuwu',
-    'icon-daimashengcheng',
-    'icon-zhuanjiaku',
-    'icon-zhengfuweituo',
-  ];
-  const isCustomIcon = (iconName) => customIconArray.includes(iconName);
-
   // ------------------------ table表格数据和查询方法 ------------------------
 
   const tableLoading = ref(false);