فهرست منبع

update 同步 ruoyi
* update 优化 下拉图标选择组件优化:1.已选择图标高亮回显 2.滚动条采用el-scrollbar
* fix 修复 开启TopNav后一级菜单路由参数设置无效问题
* update 优化 Vue的DictTag组件 当value没有匹配的值时 展示空value
* update 优化 恢复翻页/切换路由滚动功能
* fix 修复 路由跳转被阻止时vue-router内部产生报错信息问题
* fix 修复 缓存列表:多次清除操作,提示不变的问题

疯狂的狮子li 2 سال پیش
والد
کامیت
47379dd702

+ 1 - 1
ruoyi-ui/src/assets/styles/sidebar.scss

@@ -1,7 +1,7 @@
 #app {
 
   .main-container {
-    min-height: 100%;
+    height: 100%;
     transition: margin-left .28s;
     margin-left: $base-sidebar-width;
     position: relative;

+ 43 - 3
ruoyi-ui/src/components/DictTag/index.vue

@@ -7,7 +7,7 @@
           :key="item.value"
           :index="index"
           :class="item.raw.cssClass"
-          >{{ item.label }}</span
+          >{{ item.label + ' ' }}</span
         >
         <el-tag
           v-else
@@ -17,10 +17,13 @@
           :type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
           :class="item.raw.cssClass"
         >
-          {{ item.label }}
+          {{ item.label + ' ' }}
         </el-tag>
       </template>
     </template>
+    <template v-if="unmatch && showValue">
+      {{ unmatchArray | handleArray }}
+    </template>
   </div>
 </template>
 
@@ -33,6 +36,16 @@ export default {
       default: null,
     },
     value: [Number, String, Array],
+    // 当未找到匹配的数据时,显示value
+    showValue: {
+      type: Boolean,
+      default: true,
+    }
+  },
+  data() {
+    return {
+      unmatchArray: [], // 记录未匹配的项
+    }
   },
   computed: {
     values() {
@@ -42,11 +55,38 @@ export default {
         return [];
       }
     },
+    unmatch(){
+      this.unmatchArray = [];
+      if (this.value !== null && typeof this.value !== 'undefined') {
+        // 传入值为非数组
+        if(!Array.isArray(this.value)){
+          if(this.options.some(v=> v.value == this.value )) return false;
+          this.unmatchArray.push(this.value);
+          return true;
+        }
+        // 传入值为Array
+        this.value.forEach(item => {
+          if (!this.options.some(v=> v.value == item )) this.unmatchArray.push(item)
+        });
+        return true;
+      }
+      // 没有value不显示
+      return false;
+    },
+
   },
+  filters: {
+    handleArray(array) {
+      if(array.length===0) return '';
+      return array.reduce((pre, cur) => {
+        return pre + ' ' + cur;
+      })
+    },
+  }
 };
 </script>
 <style scoped>
 .el-tag + .el-tag {
   margin-left: 10px;
 }
-</style>
+</style>

+ 54 - 18
ruoyi-ui/src/components/IconSelect/index.vue

@@ -1,13 +1,17 @@
 <!-- @author zhengjie -->
 <template>
   <div class="icon-body">
-    <el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">
+    <el-input v-model="name" class="icon-search" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">
       <i slot="suffix" class="el-icon-search el-input__icon" />
     </el-input>
     <div class="icon-list">
-      <div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
-        <svg-icon :icon-class="item" style="height: 30px;width: 16px;" />
-        <span>{{ item }}</span>
+      <div class="list-container">
+        <div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)">
+          <div :class="['icon-item', { active: activeIcon === item }]">
+            <svg-icon :icon-class="item" class-name="icon" style="height: 25px;width: 16px;"/>
+            <span>{{ item }}</span>
+          </div>
+        </div>
       </div>
     </div>
   </div>
@@ -17,6 +21,11 @@
 import icons from './requireIcons'
 export default {
   name: 'IconSelect',
+  props: {
+    activeIcon: {
+      type: String
+    }
+  },
   data() {
     return {
       name: '',
@@ -46,22 +55,49 @@ export default {
   .icon-body {
     width: 100%;
     padding: 10px;
+    .icon-search {
+      position: relative;
+      margin-bottom: 5px;
+    }
     .icon-list {
       height: 200px;
-      overflow-y: scroll;
-      div {
-        height: 30px;
-        line-height: 30px;
-        margin-bottom: -5px;
-        cursor: pointer;
-        width: 33%;
-        float: left;
-      }
-      span {
-        display: inline-block;
-        vertical-align: -0.15em;
-        fill: currentColor;
-        overflow: hidden;
+      overflow: auto;
+      .list-container {
+        display: flex;
+        flex-wrap: wrap;
+        .icon-item-wrapper {
+          width: calc(100% / 3);
+          height: 25px;
+          line-height: 25px;
+          cursor: pointer;
+          display: flex;
+          .icon-item {
+            display: flex;
+            max-width: 100%;
+            height: 100%;
+            padding: 0 5px;
+            &:hover {
+              background: #ececec;
+              border-radius: 5px;
+            }
+            .icon {
+              flex-shrink: 0;
+            }
+            span {
+              display: inline-block;
+              vertical-align: -0.15em;
+              fill: currentColor;
+              padding-left: 2px;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+            }
+          }
+          .icon-item.active {
+            background: #ececec;
+            border-radius: 5px;
+          }
+        }
       }
     }
   }

+ 7 - 1
ruoyi-ui/src/components/TopNav/index.vue

@@ -127,7 +127,13 @@ export default {
         window.open(key, "_blank");
       } else if (!route || !route.children) {
         // 没有子路由路径内部打开
-        this.$router.push({ path: key });
+        const routeMenu = this.childrenMenus.find(item => item.path === key);
+        if (routeMenu && routeMenu.query) {
+          let query = JSON.parse(routeMenu.query);
+          this.$router.push({ path: key, query: query });
+        } else {
+          this.$router.push({ path: key });
+        }
         this.$store.dispatch('app/toggleSideBarHide', true);
       } else {
         // 显示左侧联动菜单

+ 23 - 0
ruoyi-ui/src/layout/components/AppMain.vue

@@ -50,3 +50,26 @@ export default {
   }
 }
 </style>
+
+<style lang="scss">
+// fix css style bug in open el-dialog
+.el-popup-parent--hidden {
+  .fixed-header {
+    padding-right: 6px;
+  }
+}
+
+::-webkit-scrollbar {
+  width: 6px;
+  height: 6px;
+}
+
+::-webkit-scrollbar-track {
+  background-color: #f1f1f1;
+}
+
+::-webkit-scrollbar-thumb {
+  background-color: #c0c0c0;
+  border-radius: 3px;
+}
+</style>

+ 1 - 1
ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue

@@ -87,7 +87,7 @@ export default {
       bottom: 0px;
     }
     .el-scrollbar__wrap {
-      height: 49px;
+      height: 39px;
     }
   }
 }

+ 11 - 25
ruoyi-ui/src/layout/index.vue

@@ -1,19 +1,17 @@
 <template>
   <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
-    <el-scrollbar>
-      <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
-      <sidebar v-if="!sidebar.hide" class="sidebar-container" />
-      <div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
-        <div :class="{'fixed-header':fixedHeader}">
-          <navbar />
-          <tags-view v-if="needTagsView" />
-        </div>
-        <app-main />
-        <right-panel>
-          <settings />
-        </right-panel>
+    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
+    <sidebar v-if="!sidebar.hide" class="sidebar-container"/>
+    <div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
+      <div :class="{'fixed-header':fixedHeader}">
+        <navbar/>
+        <tags-view v-if="needTagsView"/>
       </div>
-    </el-scrollbar>
+      <app-main/>
+      <right-panel>
+        <settings/>
+      </right-panel>
+    </div>
   </div>
 </template>
 
@@ -74,18 +72,6 @@ export default {
     height: 100%;
     width: 100%;
 
-    .el-scrollbar{
-      height: 100%;
-    }
-
-    ::v-deep .el-scrollbar__bar.is-vertical {
-      z-index: 10;
-    }
-
-    ::v-deep .el-scrollbar__wrap {
-      overflow-x: hidden;
-    }
-
     &.mobile.openSidebar {
       position: fixed;
       top: 0;

+ 6 - 0
ruoyi-ui/src/router/index.js

@@ -166,9 +166,15 @@ export const dynamicRoutes = [
 
 // 防止连续点击多次路由报错
 let routerPush = Router.prototype.push;
+let routerReplace = Router.prototype.replace;
+// push
 Router.prototype.push = function push(location) {
   return routerPush.call(this, location).catch(err => err)
 }
+// replace
+Router.prototype.replace = function push(location) {
+  return routerReplace.call(this, location).catch(err => err)
+}
 
 export default new Router({
   base: process.env.VUE_APP_CONTEXT_PATH,

+ 1 - 1
ruoyi-ui/src/views/monitor/cache/list.vue

@@ -187,7 +187,7 @@ export default {
     /** 清理指定名称缓存 */
     handleClearCacheName(row) {
       clearCacheName(row.cacheName).then(response => {
-        this.$modal.msgSuccess("清理缓存名称[" + this.nowCacheName + "]成功");
+        this.$modal.msgSuccess("清理缓存名称[" + row.cacheName + "]成功");
         this.getCacheKeys();
       });
     },

+ 1 - 1
ruoyi-ui/src/views/system/menu/index.vue

@@ -134,7 +134,7 @@
                 trigger="click"
                 @show="$refs['iconSelect'].reset()"
               >
-                <IconSelect ref="iconSelect" @selected="selected" />
+                <IconSelect ref="iconSelect" @selected="selected" :active-icon="form.icon" />
                 <el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
                   <svg-icon
                     v-if="form.icon"