pom.xml
@@ -434,3 +434,4 @@ </profiles> </project> ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -247,4 +247,5 @@ public R<List<Tree<Long>>> deptTree(SysDept dept) { return R.ok(deptService.selectDeptTreeList(dept)); } } ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -18,6 +18,11 @@ String GBK = "GBK"; /** * www主å */ String WWW = "www."; /** * httpè¯·æ± */ String HTTP = "http://"; ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
@@ -447,7 +447,7 @@ * @return */ public String innerLinkReplaceEach(String path) { return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS}, return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "." }, new String[]{"", ""}); } } ruoyi-ui/src/assets/styles/transition.scss
@@ -12,11 +12,16 @@ } /* fade-transform */ .fade-transform--move, .fade-transform-leave-active, .fade-transform-enter-active { transition: all .5s; } .fade-transform-leave-active { position: absolute; } .fade-transform-enter { opacity: 0; transform: translateX(-30px); ruoyi-ui/src/components/ImagePreview/index.vue
@@ -18,7 +18,7 @@ props: { src: { type: String, required: true default: "" }, width: { type: [Number, String], @@ -31,10 +31,16 @@ }, computed: { realSrc() { if (!this.src) { return; } let real_src = this.src.split(",")[0]; return real_src; }, realSrcList() { if (!this.src) { return; } let real_src_list = this.src.split(","); let srcList = []; real_src_list.forEach(item => { ruoyi-ui/src/components/ImageUpload/index.vue
@@ -208,7 +208,7 @@ } } return strs != "" ? strs.substr(0, strs.length - 1) : ""; }, } } }; </script> ruoyi-ui/src/layout/components/AppMain.vue
@@ -2,15 +2,19 @@ <section class="app-main"> <transition name="fade-transform" mode="out-in"> <keep-alive :include="cachedViews"> <router-view :key="key" /> <router-view v-if="!$route.meta.link" :key="key" /> </keep-alive> </transition> <iframe-toggle /> </section> </template> <script> import iframeToggle from "./IframeToggle/index" export default { name: 'AppMain', components: { iframeToggle }, computed: { cachedViews() { return this.$store.state.tagsView.cachedViews @@ -31,7 +35,7 @@ overflow: hidden; } .fixed-header+.app-main { .fixed-header + .app-main { padding-top: 50px; } @@ -41,7 +45,7 @@ min-height: calc(100vh - 84px); } .fixed-header+.app-main { .fixed-header + .app-main { padding-top: 84px; } } ruoyi-ui/src/layout/components/IframeToggle/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ <template> <transition-group name="fade-transform" mode="out-in"> <inner-link v-for="(item, index) in iframeViews" :key="item.path" :iframeId="'iframe' + index" v-show="$route.path === item.path" :src="item.meta.link" ></inner-link> </transition-group> </template> <script> import InnerLink from "../InnerLink/index" export default { components: { InnerLink }, computed: { iframeViews() { return this.$store.state.tagsView.iframeViews } } } </script> ruoyi-ui/src/layout/components/InnerLink/index.vue
@@ -1,27 +1,47 @@ <template> <div :style="'height:' + height" v-loading="loading" element-loading-text="æ£å¨å 载页é¢ï¼è¯·ç¨åï¼"> <iframe :id="iframeId" style="width: 100%; height: 100%" :src="src" frameborder="no" ></iframe> </div> </template> <script> export default { data() { return {}; }, render() { const { $route: { meta: { link } }, } = this; if ({ link }.link === "") { return "404"; props: { src: { type: String, default: "/" }, iframeId: { type: String } let url = { link }.link; const height = document.documentElement.clientHeight - 94.5 + "px"; const style = { height: height }; return ( <div style={style}> <iframe src={url} frameborder="no" style="width: 100%; height: 100%" scrolling="auto" ></iframe> </div> ); }, data() { return { loading: false, height: document.documentElement.clientHeight - 94.5 + "px;" }; }, mounted() { var _this = this; const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/"); const iframe = document.querySelector(iframeId); // iframe页é¢loadingæ§å¶ if (iframe.attachEvent) { this.loading = true; iframe.attachEvent("onload", function () { _this.loading = false; }); } else { this.loading = true; iframe.onload = function () { _this.loading = false; }; } } }; </script> ruoyi-ui/src/layout/components/TagsView/index.vue
@@ -133,6 +133,9 @@ const { name } = this.$route if (name) { this.$store.dispatch('tagsView/addView', this.$route) if (this.$route.meta.link) { this.$store.dispatch('tagsView/addIframeView', this.$route) } } return false }, @@ -153,6 +156,9 @@ }, refreshSelectedTag(view) { this.$tab.refreshPage(view); if (this.$route.meta.link) { this.$store.dispatch('tagsView/delIframeView', this.$route) } }, closeSelectedTag(view) { this.$tab.closePage(view).then(({ visitedViews }) => { ruoyi-ui/src/store/modules/tagsView.js
@@ -1,9 +1,18 @@ const state = { visitedViews: [], cachedViews: [] cachedViews: [], iframeViews: [] } const mutations = { ADD_IFRAME_VIEW: (state, view) => { if (state.iframeViews.some(v => v.path === view.path)) return state.iframeViews.push( Object.assign({}, view, { title: view.meta.title || 'no-name' }) ) }, ADD_VISITED_VIEW: (state, view) => { if (state.visitedViews.some(v => v.path === view.path)) return state.visitedViews.push( @@ -18,7 +27,6 @@ state.cachedViews.push(view.name) } }, DEL_VISITED_VIEW: (state, view) => { for (const [i, v] of state.visitedViews.entries()) { if (v.path === view.path) { @@ -26,6 +34,10 @@ break } } state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) }, DEL_IFRAME_VIEW: (state, view) => { state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) }, DEL_CACHED_VIEW: (state, view) => { const index = state.cachedViews.indexOf(view.name) @@ -36,6 +48,7 @@ state.visitedViews = state.visitedViews.filter(v => { return v.meta.affix || v.path === view.path }) state.iframeViews = state.iframeViews.filter(item => item.path === view.path) }, DEL_OTHERS_CACHED_VIEWS: (state, view) => { const index = state.cachedViews.indexOf(view.name) @@ -45,16 +58,15 @@ state.cachedViews = [] } }, DEL_ALL_VISITED_VIEWS: state => { // keep affix tags const affixTags = state.visitedViews.filter(tag => tag.meta.affix) state.visitedViews = affixTags state.iframeViews = [] }, DEL_ALL_CACHED_VIEWS: state => { state.cachedViews = [] }, UPDATE_VISITED_VIEW: (state, view) => { for (let v of state.visitedViews) { if (v.path === view.path) { @@ -63,7 +75,6 @@ } } }, DEL_RIGHT_VIEWS: (state, view) => { const index = state.visitedViews.findIndex(v => v.path === view.path) if (index === -1) { @@ -77,10 +88,13 @@ if (i > -1) { state.cachedViews.splice(i, 1) } if(item.meta.link) { const fi = state.iframeViews.findIndex(v => v.path === item.path) state.iframeViews.splice(fi, 1) } return false }) }, DEL_LEFT_VIEWS: (state, view) => { const index = state.visitedViews.findIndex(v => v.path === view.path) if (index === -1) { @@ -94,6 +108,10 @@ if (i > -1) { state.cachedViews.splice(i, 1) } if(item.meta.link) { const fi = state.iframeViews.findIndex(v => v.path === item.path) state.iframeViews.splice(fi, 1) } return false }) } @@ -104,13 +122,15 @@ dispatch('addVisitedView', view) dispatch('addCachedView', view) }, addIframeView({ commit }, view) { commit('ADD_IFRAME_VIEW', view) }, addVisitedView({ commit }, view) { commit('ADD_VISITED_VIEW', view) }, addCachedView({ commit }, view) { commit('ADD_CACHED_VIEW', view) }, delView({ dispatch, state }, view) { return new Promise(resolve => { dispatch('delVisitedView', view) @@ -127,13 +147,18 @@ resolve([...state.visitedViews]) }) }, delIframeView({ commit, state }, view) { return new Promise(resolve => { commit('DEL_IFRAME_VIEW', view) resolve([...state.iframeViews]) }) }, delCachedView({ commit, state }, view) { return new Promise(resolve => { commit('DEL_CACHED_VIEW', view) resolve([...state.cachedViews]) }) }, delOthersViews({ dispatch, state }, view) { return new Promise(resolve => { dispatch('delOthersVisitedViews', view) @@ -156,7 +181,6 @@ resolve([...state.cachedViews]) }) }, delAllViews({ dispatch, state }, view) { return new Promise(resolve => { dispatch('delAllVisitedViews', view) @@ -179,18 +203,15 @@ resolve([...state.cachedViews]) }) }, updateVisitedView({ commit }, view) { commit('UPDATE_VISITED_VIEW', view) }, delRightTags({ commit }, view) { return new Promise(resolve => { commit('DEL_RIGHT_VIEWS', view) resolve([...state.visitedViews]) }) }, delLeftTags({ commit }, view) { return new Promise(resolve => { commit('DEL_LEFT_VIEWS', view) ruoyi-ui/src/views/system/menu/index.vue
@@ -107,7 +107,7 @@ <el-form ref="form" :model="form" :rules="rules" label-width="100px"> <el-row> <el-col :span="24"> <el-form-item label="ä¸çº§èå"> <el-form-item label="ä¸çº§èå" prop="parentId"> <treeselect v-model="form.parentId" :options="menuOptions" @@ -159,7 +159,7 @@ </el-form-item> </el-col> <el-col :span="12" v-if="form.menuType != 'F'"> <el-form-item> <el-form-item prop="isFrame"> <span slot="label"> <el-tooltip content="éæ©æ¯å¤é¾åè·¯ç±å°åéè¦ä»¥`http(s)://`å¼å¤´" placement="top"> <i class="el-icon-question"></i> @@ -195,7 +195,7 @@ </el-form-item> </el-col> <el-col :span="12" v-if="form.menuType != 'M'"> <el-form-item> <el-form-item prop="perms"> <el-input v-model="form.perms" placeholder="请è¾å ¥æéæ è¯" maxlength="100" /> <span slot="label"> <el-tooltip content="æ§å¶å¨ä¸å®ä¹çæéå符ï¼å¦ï¼@SaCheckPermission('system:user:list')" placement="top"> @@ -206,7 +206,7 @@ </el-form-item> </el-col> <el-col :span="12" v-if="form.menuType == 'C'"> <el-form-item> <el-form-item prop="queryParam"> <el-input v-model="form.queryParam" placeholder="请è¾å ¥è·¯ç±åæ°" maxlength="255" /> <span slot="label"> <el-tooltip content='访é®è·¯ç±çé»è®¤ä¼ éåæ°ï¼å¦ï¼`{"id": 1, "name": "ry"}`' placement="top"> @@ -217,7 +217,7 @@ </el-form-item> </el-col> <el-col :span="12" v-if="form.menuType == 'C'"> <el-form-item> <el-form-item prop="isCache"> <span slot="label"> <el-tooltip content="éæ©æ¯åä¼è¢«`keep-alive`ç¼åï¼éè¦å¹é ç»ä»¶ç`name`åå°åä¿æä¸è´" placement="top"> <i class="el-icon-question"></i> @@ -231,7 +231,7 @@ </el-form-item> </el-col> <el-col :span="12" v-if="form.menuType != 'F'"> <el-form-item> <el-form-item prop="visible"> <span slot="label"> <el-tooltip content="éæ©éèåè·¯ç±å°ä¸ä¼åºç°å¨ä¾§è¾¹æ ï¼ä½ä»ç¶å¯ä»¥è®¿é®" placement="top"> <i class="el-icon-question"></i> @@ -248,7 +248,7 @@ </el-form-item> </el-col> <el-col :span="12" v-if="form.menuType != 'F'"> <el-form-item> <el-form-item prop="status"> <span slot="label"> <el-tooltip content="éæ©åç¨åè·¯ç±å°ä¸ä¼åºç°å¨ä¾§è¾¹æ ï¼ä¹ä¸è½è¢«è®¿é®" placement="top"> <i class="el-icon-question"></i> ruoyi-ui/src/views/system/role/index.vue
@@ -605,3 +605,4 @@ } }; </script> ruoyi-ui/src/views/system/user/profile/index.vue
@@ -49,7 +49,7 @@ <userInfo :user="user" /> </el-tab-pane> <el-tab-pane label="ä¿®æ¹å¯ç " name="resetPwd"> <resetPwd :user="user" /> <resetPwd /> </el-tab-pane> </el-tabs> </el-card>