Просмотр исходного кода

优化页面内嵌iframe切换tab不刷新数据

RuoYi лет назад: 3
Родитель
Сommit
f0bfff1ff3

+ 1 - 1
ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/annotation/DataScope.java

@@ -27,7 +27,7 @@ public @interface DataScope
27
     public String userAlias() default "";
27
     public String userAlias() default "";
28
 
28
 
29
     /**
29
     /**
30
-     * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
30
+     * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@RequiresPermissions获取,多个权限用逗号分隔开来
31
      */
31
      */
32
     public String permission() default "";
32
     public String permission() default "";
33
 }
33
 }

+ 2 - 2
ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java

@@ -247,7 +247,7 @@ public class RedisService
247
      * 删除Hash中的某条数据
247
      * 删除Hash中的某条数据
248
      *
248
      *
249
      * @param key Redis键
249
      * @param key Redis键
250
-     * @param hKey  Hash键
250
+     * @param hKey Hash键
251
      * @return 是否成功
251
      * @return 是否成功
252
      */
252
      */
253
     public boolean deleteCacheMapValue(final String key, final String hKey)
253
     public boolean deleteCacheMapValue(final String key, final String hKey)
@@ -257,7 +257,7 @@ public class RedisService
257
 
257
 
258
     /**
258
     /**
259
      * 获得缓存的基本对象列表
259
      * 获得缓存的基本对象列表
260
-     * 
260
+     *
261
      * @param pattern 字符串前缀
261
      * @param pattern 字符串前缀
262
      * @return 对象列表
262
      * @return 对象列表
263
      */
263
      */

+ 5 - 0
ruoyi-ui/src/assets/styles/transition.scss

@@ -12,11 +12,16 @@
12
 }
12
 }
13
 
13
 
14
 /* fade-transform */
14
 /* fade-transform */
15
+.fade-transform--move,
15
 .fade-transform-leave-active,
16
 .fade-transform-leave-active,
16
 .fade-transform-enter-active {
17
 .fade-transform-enter-active {
17
   transition: all .5s;
18
   transition: all .5s;
18
 }
19
 }
19
 
20
 
21
+.fade-transform-leave-active {
22
+  position: absolute;
23
+}
24
+
20
 .fade-transform-enter {
25
 .fade-transform-enter {
21
   opacity: 0;
26
   opacity: 0;
22
   transform: translateX(-30px);
27
   transform: translateX(-30px);

+ 7 - 3
ruoyi-ui/src/layout/components/AppMain.vue

@@ -2,15 +2,19 @@
2
   <section class="app-main">
2
   <section class="app-main">
3
     <transition name="fade-transform" mode="out-in">
3
     <transition name="fade-transform" mode="out-in">
4
       <keep-alive :include="cachedViews">
4
       <keep-alive :include="cachedViews">
5
-        <router-view :key="key" />
5
+        <router-view v-if="!$route.meta.link" :key="key" />
6
       </keep-alive>
6
       </keep-alive>
7
     </transition>
7
     </transition>
8
+    <iframe-toggle />
8
   </section>
9
   </section>
9
 </template>
10
 </template>
10
 
11
 
11
 <script>
12
 <script>
13
+import iframeToggle from "./IframeToggle/index"
14
+
12
 export default {
15
 export default {
13
   name: 'AppMain',
16
   name: 'AppMain',
17
+  components: { iframeToggle },
14
   computed: {
18
   computed: {
15
     cachedViews() {
19
     cachedViews() {
16
       return this.$store.state.tagsView.cachedViews
20
       return this.$store.state.tagsView.cachedViews
@@ -31,7 +35,7 @@ export default {
31
   overflow: hidden;
35
   overflow: hidden;
32
 }
36
 }
33
 
37
 
34
-.fixed-header+.app-main {
38
+.fixed-header + .app-main {
35
   padding-top: 50px;
39
   padding-top: 50px;
36
 }
40
 }
37
 
41
 
@@ -41,7 +45,7 @@ export default {
41
     min-height: calc(100vh - 84px);
45
     min-height: calc(100vh - 84px);
42
   }
46
   }
43
 
47
 
44
-  .fixed-header+.app-main {
48
+  .fixed-header + .app-main {
45
     padding-top: 84px;
49
     padding-top: 84px;
46
   }
50
   }
47
 }
51
 }

+ 24 - 0
ruoyi-ui/src/layout/components/IframeToggle/index.vue

@@ -0,0 +1,24 @@
1
+<template>
2
+  <transition-group name="fade-transform" mode="out-in">
3
+    <inner-link
4
+      v-for="(item, index) in iframeViews"
5
+      :key="item.path"
6
+      :iframeId="'iframe' + index"
7
+      v-show="$route.path === item.path"
8
+      :src="item.meta.link"
9
+    ></inner-link>
10
+  </transition-group>
11
+</template>
12
+
13
+<script>
14
+import InnerLink from "../InnerLink/index"
15
+
16
+export default {
17
+  components: { InnerLink },
18
+  computed: {
19
+    iframeViews() {
20
+      return this.$store.state.tagsView.iframeViews
21
+    }
22
+  }
23
+}
24
+</script>

+ 40 - 20
ruoyi-ui/src/layout/components/InnerLink/index.vue

@@ -1,27 +1,47 @@
1
+<template>
2
+  <div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!">
3
+    <iframe
4
+      :id="iframeId"
5
+      style="width: 100%; height: 100%"
6
+      :src="src"
7
+      frameborder="no"
8
+    ></iframe>
9
+  </div>
10
+</template>
11
+
1
 <script>
12
 <script>
2
 export default {
13
 export default {
14
+  props: {
15
+    src: {
16
+      type: String,
17
+      default: "/"
18
+    },
19
+    iframeId: {
20
+      type: String
21
+    }
22
+  },
3
   data() {
23
   data() {
4
-    return {};
24
+    return {
25
+      loading: false,
26
+      height: document.documentElement.clientHeight - 94.5 + "px;"
27
+    };
5
   },
28
   },
6
-  render() {
7
-    const { $route: { meta: { link } }, } = this;
8
-    if ({ link }.link === "") {
9
-      return "404";
29
+  mounted() {
30
+    var _this = this;
31
+    const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
32
+    const iframe = document.querySelector(iframeId);
33
+    // iframe页面loading控制
34
+    if (iframe.attachEvent) {
35
+      this.loading = true;
36
+      iframe.attachEvent("onload", function () {
37
+        _this.loading = false;
38
+      });
39
+    } else {
40
+      this.loading = true;
41
+      iframe.onload = function () {
42
+        _this.loading = false;
43
+      };
10
     }
44
     }
11
-    let url = { link }.link;
12
-    const height = document.documentElement.clientHeight - 94.5 + "px";
13
-    const style = { height: height };
14
-
15
-    return (
16
-      <div style={style}>
17
-        <iframe
18
-          src={url}
19
-          frameborder="no"
20
-          style="width: 100%; height: 100%"
21
-          scrolling="auto"
22
-        ></iframe>
23
-      </div>
24
-    );
25
-  },
45
+  }
26
 };
46
 };
27
 </script>
47
 </script>

+ 6 - 0
ruoyi-ui/src/layout/components/TagsView/index.vue

@@ -133,6 +133,9 @@ export default {
133
       const { name } = this.$route
133
       const { name } = this.$route
134
       if (name) {
134
       if (name) {
135
         this.$store.dispatch('tagsView/addView', this.$route)
135
         this.$store.dispatch('tagsView/addView', this.$route)
136
+        if (this.$route.meta.link) {
137
+          this.$store.dispatch('tagsView/addIframeView', this.$route)
138
+        }
136
       }
139
       }
137
       return false
140
       return false
138
     },
141
     },
@@ -153,6 +156,9 @@ export default {
153
     },
156
     },
154
     refreshSelectedTag(view) {
157
     refreshSelectedTag(view) {
155
       this.$tab.refreshPage(view);
158
       this.$tab.refreshPage(view);
159
+      if (this.$route.meta.link) {
160
+        this.$store.dispatch('tagsView/delIframeView', this.$route)
161
+      }
156
     },
162
     },
157
     closeSelectedTag(view) {
163
     closeSelectedTag(view) {
158
       this.$tab.closePage(view).then(({ visitedViews }) => {
164
       this.$tab.closePage(view).then(({ visitedViews }) => {

+ 28 - 12
ruoyi-ui/src/store/modules/tagsView.js

@@ -1,9 +1,17 @@
1
 const state = {
1
 const state = {
2
   visitedViews: [],
2
   visitedViews: [],
3
-  cachedViews: []
3
+  cachedViews: [],
4
+  iframeViews: []
4
 }
5
 }
5
 
6
 
6
 const mutations = {
7
 const mutations = {
8
+  ADD_IFRAME_VIEW: (state, view) => {
9
+    if (state.iframeViews.some(v => v.path === view.path)) {
10
+      return
11
+    } else {
12
+      state.iframeViews.push(view)
13
+    }
14
+  },
7
   ADD_VISITED_VIEW: (state, view) => {
15
   ADD_VISITED_VIEW: (state, view) => {
8
     if (state.visitedViews.some(v => v.path === view.path)) return
16
     if (state.visitedViews.some(v => v.path === view.path)) return
9
     state.visitedViews.push(
17
     state.visitedViews.push(
@@ -18,7 +26,6 @@ const mutations = {
18
       state.cachedViews.push(view.name)
26
       state.cachedViews.push(view.name)
19
     }
27
     }
20
   },
28
   },
21
-
22
   DEL_VISITED_VIEW: (state, view) => {
29
   DEL_VISITED_VIEW: (state, view) => {
23
     for (const [i, v] of state.visitedViews.entries()) {
30
     for (const [i, v] of state.visitedViews.entries()) {
24
       if (v.path === view.path) {
31
       if (v.path === view.path) {
@@ -26,6 +33,10 @@ const mutations = {
26
         break
33
         break
27
       }
34
       }
28
     }
35
     }
36
+    state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
37
+  },
38
+  DEL_IFRAME_VIEW: (state, view) => {
39
+    state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
29
   },
40
   },
30
   DEL_CACHED_VIEW: (state, view) => {
41
   DEL_CACHED_VIEW: (state, view) => {
31
     const index = state.cachedViews.indexOf(view.name)
42
     const index = state.cachedViews.indexOf(view.name)
@@ -36,6 +47,7 @@ const mutations = {
36
     state.visitedViews = state.visitedViews.filter(v => {
47
     state.visitedViews = state.visitedViews.filter(v => {
37
       return v.meta.affix || v.path === view.path
48
       return v.meta.affix || v.path === view.path
38
     })
49
     })
50
+    state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
39
   },
51
   },
40
   DEL_OTHERS_CACHED_VIEWS: (state, view) => {
52
   DEL_OTHERS_CACHED_VIEWS: (state, view) => {
41
     const index = state.cachedViews.indexOf(view.name)
53
     const index = state.cachedViews.indexOf(view.name)
@@ -45,16 +57,15 @@ const mutations = {
45
       state.cachedViews = []
57
       state.cachedViews = []
46
     }
58
     }
47
   },
59
   },
48
-
49
   DEL_ALL_VISITED_VIEWS: state => {
60
   DEL_ALL_VISITED_VIEWS: state => {
50
     // keep affix tags
61
     // keep affix tags
51
     const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
62
     const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
52
     state.visitedViews = affixTags
63
     state.visitedViews = affixTags
64
+    state.iframeViews = []
53
   },
65
   },
54
   DEL_ALL_CACHED_VIEWS: state => {
66
   DEL_ALL_CACHED_VIEWS: state => {
55
     state.cachedViews = []
67
     state.cachedViews = []
56
   },
68
   },
57
-
58
   UPDATE_VISITED_VIEW: (state, view) => {
69
   UPDATE_VISITED_VIEW: (state, view) => {
59
     for (let v of state.visitedViews) {
70
     for (let v of state.visitedViews) {
60
       if (v.path === view.path) {
71
       if (v.path === view.path) {
@@ -63,7 +74,6 @@ const mutations = {
63
       }
74
       }
64
     }
75
     }
65
   },
76
   },
66
-  
67
   DEL_RIGHT_VIEWS: (state, view) => {
77
   DEL_RIGHT_VIEWS: (state, view) => {
68
     const index = state.visitedViews.findIndex(v => v.path === view.path)
78
     const index = state.visitedViews.findIndex(v => v.path === view.path)
69
     if (index === -1) {
79
     if (index === -1) {
@@ -79,8 +89,9 @@ const mutations = {
79
       }
89
       }
80
       return false
90
       return false
81
     })
91
     })
92
+    const iframeIndex = state.iframeViews.findIndex(v => v.path === view.path)
93
+    state.iframeViews = state.iframeViews.filter((item, idx) => idx <= iframeIndex)
82
   },
94
   },
83
-
84
   DEL_LEFT_VIEWS: (state, view) => {
95
   DEL_LEFT_VIEWS: (state, view) => {
85
     const index = state.visitedViews.findIndex(v => v.path === view.path)
96
     const index = state.visitedViews.findIndex(v => v.path === view.path)
86
     if (index === -1) {
97
     if (index === -1) {
@@ -96,6 +107,8 @@ const mutations = {
96
       }
107
       }
97
       return false
108
       return false
98
     })
109
     })
110
+    const iframeIndex = state.iframeViews.findIndex(v => v.path === view.path)
111
+    state.iframeViews = state.iframeViews.filter((item, idx) => idx >= iframeIndex)
99
   }
112
   }
100
 }
113
 }
101
 
114
 
@@ -104,13 +117,15 @@ const actions = {
104
     dispatch('addVisitedView', view)
117
     dispatch('addVisitedView', view)
105
     dispatch('addCachedView', view)
118
     dispatch('addCachedView', view)
106
   },
119
   },
120
+  addIframeView({ commit }, view) {
121
+    commit('ADD_IFRAME_VIEW', view)
122
+  },
107
   addVisitedView({ commit }, view) {
123
   addVisitedView({ commit }, view) {
108
     commit('ADD_VISITED_VIEW', view)
124
     commit('ADD_VISITED_VIEW', view)
109
   },
125
   },
110
   addCachedView({ commit }, view) {
126
   addCachedView({ commit }, view) {
111
     commit('ADD_CACHED_VIEW', view)
127
     commit('ADD_CACHED_VIEW', view)
112
   },
128
   },
113
-
114
   delView({ dispatch, state }, view) {
129
   delView({ dispatch, state }, view) {
115
     return new Promise(resolve => {
130
     return new Promise(resolve => {
116
       dispatch('delVisitedView', view)
131
       dispatch('delVisitedView', view)
@@ -127,13 +142,18 @@ const actions = {
127
       resolve([...state.visitedViews])
142
       resolve([...state.visitedViews])
128
     })
143
     })
129
   },
144
   },
145
+  delIframeView({ commit, state }, view) {
146
+    return new Promise(resolve => {
147
+      commit('DEL_IFRAME_VIEW', view)
148
+      resolve([...state.iframeViews])
149
+    })
150
+  },
130
   delCachedView({ commit, state }, view) {
151
   delCachedView({ commit, state }, view) {
131
     return new Promise(resolve => {
152
     return new Promise(resolve => {
132
       commit('DEL_CACHED_VIEW', view)
153
       commit('DEL_CACHED_VIEW', view)
133
       resolve([...state.cachedViews])
154
       resolve([...state.cachedViews])
134
     })
155
     })
135
   },
156
   },
136
-
137
   delOthersViews({ dispatch, state }, view) {
157
   delOthersViews({ dispatch, state }, view) {
138
     return new Promise(resolve => {
158
     return new Promise(resolve => {
139
       dispatch('delOthersVisitedViews', view)
159
       dispatch('delOthersVisitedViews', view)
@@ -156,7 +176,6 @@ const actions = {
156
       resolve([...state.cachedViews])
176
       resolve([...state.cachedViews])
157
     })
177
     })
158
   },
178
   },
159
-
160
   delAllViews({ dispatch, state }, view) {
179
   delAllViews({ dispatch, state }, view) {
161
     return new Promise(resolve => {
180
     return new Promise(resolve => {
162
       dispatch('delAllVisitedViews', view)
181
       dispatch('delAllVisitedViews', view)
@@ -179,18 +198,15 @@ const actions = {
179
       resolve([...state.cachedViews])
198
       resolve([...state.cachedViews])
180
     })
199
     })
181
   },
200
   },
182
-
183
   updateVisitedView({ commit }, view) {
201
   updateVisitedView({ commit }, view) {
184
     commit('UPDATE_VISITED_VIEW', view)
202
     commit('UPDATE_VISITED_VIEW', view)
185
   },
203
   },
186
-
187
   delRightTags({ commit }, view) {
204
   delRightTags({ commit }, view) {
188
     return new Promise(resolve => {
205
     return new Promise(resolve => {
189
       commit('DEL_RIGHT_VIEWS', view)
206
       commit('DEL_RIGHT_VIEWS', view)
190
       resolve([...state.visitedViews])
207
       resolve([...state.visitedViews])
191
     })
208
     })
192
   },
209
   },
193
-
194
   delLeftTags({ commit }, view) {
210
   delLeftTags({ commit }, view) {
195
     return new Promise(resolve => {
211
     return new Promise(resolve => {
196
       commit('DEL_LEFT_VIEWS', view)
212
       commit('DEL_LEFT_VIEWS', view)