Browse Source

增加menu可配置是否自动关闭功能 增加单页面刷新功能

main
蒋吉兆 4 years ago
parent
commit
072bf62ea5
  1. 1
      server/model/sys_base_menu.go
  2. 1
      web/src/store/module/router.js
  3. 290
      web/src/view/layout/aside/historyComponent/history.vue
  4. 15
      web/src/view/layout/index.vue
  5. 14
      web/src/view/layout/search/search.vue
  6. 7
      web/src/view/superAdmin/menu/menu.vue

1
server/model/sys_base_menu.go

@ -24,6 +24,7 @@ type Meta struct {
DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"`
Title string `json:"title" gorm:"comment:菜单名"` Title string `json:"title" gorm:"comment:菜单名"`
Icon string `json:"icon" gorm:"comment:菜单图标"` Icon string `json:"icon" gorm:"comment:菜单图标"`
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"`
} }
type SysBaseMenuParameter struct { type SysBaseMenuParameter struct {

1
web/src/store/module/router.js

@ -8,7 +8,6 @@ const formatRouter = (routes) => {
if ((!item.children || item.children.every(ch => ch.hidden)) && item.name != '404') { if ((!item.children || item.children.every(ch => ch.hidden)) && item.name != '404') {
routerList.push({ label: item.meta.title, value: item.name }) routerList.push({ label: item.meta.title, value: item.name })
} }
item.meta.hidden = item.hidden
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
formatRouter(item.children) formatRouter(item.children)
} }

290
web/src/view/layout/aside/historyComponent/history.vue

@ -9,9 +9,9 @@
v-model="activeValue" v-model="activeValue"
> >
<el-tab-pane <el-tab-pane
:key="item.name"
:key="item.name + JSON.stringify(item.query)+JSON.stringify(item.params)"
:label="item.meta.title" :label="item.meta.title"
:name="item.name"
:name="item.name + JSON.stringify(item.query)+JSON.stringify(item.params)"
:tab="item" :tab="item"
v-for="item in historys" v-for="item in historys"
></el-tab-pane> ></el-tab-pane>
@ -27,73 +27,75 @@
</div> </div>
</template> </template>
<script> <script>
import {mapGetters} from "vuex"
import { mapGetters } from "vuex";
export default { export default {
name: 'HistoryComponent',
name: "HistoryComponent",
data() { data() {
return { return {
historys: [], historys: [],
activeValue: '',
activeValue: "",
contextMenuVisible: false, contextMenuVisible: false,
left: 0, left: 0,
top: 0, top: 0,
isCollapse: false, isCollapse: false,
isMobile: false, isMobile: false,
rightActive: ''
}
rightActive: ""
};
}, },
computed:{
...mapGetters("user",["userInfo"]),
defaultRouter(){
return this.userInfo.authority.defaultRouter
computed: {
...mapGetters("user", ["userInfo"]),
defaultRouter() {
return this.userInfo.authority.defaultRouter;
} }
}, },
created() { created() {
this.activeValue = this.defaultRouter
this.$bus.on('mobile', isMobile => {
this.isMobile = isMobile
})
this.$bus.on('collapse', isCollapse => {
this.isCollapse = isCollapse
})
this.$bus.on("mobile", isMobile => {
this.isMobile = isMobile;
});
this.$bus.on("collapse", isCollapse => {
this.isCollapse = isCollapse;
});
const initHistorys = [ const initHistorys = [
{ {
name: this.defaultRouter, name: this.defaultRouter,
meta: { meta: {
title: '首页'
}
title: "首页"
},
query: {},
params: {}
} }
]
];
this.historys = this.historys =
JSON.parse(sessionStorage.getItem('historys')) || initHistorys
this.setTab(this.$route)
JSON.parse(sessionStorage.getItem("historys")) || initHistorys;
this.activeValue = window.sessionStorage.getItem("activeValue");
this.setTab(this.$route);
}, },
beforeDestroy() { beforeDestroy() {
this.$bus.off('collapse')
this.$bus.off('mobile')
this.$bus.off("collapse");
this.$bus.off("mobile");
}, },
methods: { methods: {
openContextMenu(e) { openContextMenu(e) {
if (this.historys.length == 1 && this.$route.name == this.defaultRouter) { if (this.historys.length == 1 && this.$route.name == this.defaultRouter) {
return false
return false;
} }
if (e.srcElement.id) { if (e.srcElement.id) {
this.contextMenuVisible = true
let width
this.contextMenuVisible = true;
let width;
if (this.isCollapse) { if (this.isCollapse) {
width = 54
width = 54;
} else { } else {
width = 220
width = 220;
} }
if (this.isMobile) { if (this.isMobile) {
width = 0
width = 0;
} }
this.left = e.clientX - width
this.top = e.clientY + 10
this.rightActive = e.srcElement.id.split('-')[1]
this.left = e.clientX - width;
this.top = e.clientY + 10;
this.rightActive = e.srcElement.id.split("-")[1];
} }
}, },
closeAll() { closeAll() {
@ -101,115 +103,197 @@ export default {
{ {
name: this.defaultRouter, name: this.defaultRouter,
meta: { meta: {
title: '首页'
}
title: "首页"
},
query: {},
params: {}
} }
]
this.$router.push({ name: this.defaultRouter })
this.contextMenuVisible = false
sessionStorage.setItem('historys', JSON.stringify(this.historys))
];
this.$router.push({ name: this.defaultRouter });
this.contextMenuVisible = false;
sessionStorage.setItem("historys", JSON.stringify(this.historys));
}, },
closeLeft() { closeLeft() {
let right
const rightIndex = this.historys.findIndex(
item => {
if(item.name == this.rightActive){
right = item
}
return item.name == this.rightActive
let right;
const rightIndex = this.historys.findIndex(item => {
if (
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.rightActive
) {
right = item;
} }
)
return (
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.rightActive
);
});
const activeIndex = this.historys.findIndex( const activeIndex = this.historys.findIndex(
item => item.name == this.activeValue
)
this.historys.splice(0, rightIndex)
item =>
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.activeValue
);
this.historys.splice(0, rightIndex);
if (rightIndex > activeIndex) { if (rightIndex > activeIndex) {
this.$router.push(right)
this.$router.push(right);
} }
sessionStorage.setItem('historys', JSON.stringify(this.historys))
sessionStorage.setItem("historys", JSON.stringify(this.historys));
}, },
closeRight() { closeRight() {
let right
const leftIndex = this.historys.findIndex(
item => {
if(item.name == this.rightActive){
right = item
let right;
const leftIndex = this.historys.findIndex(item => {
if (
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.rightActive
) {
right = item;
} }
return item.name == this.rightActive
}
)
return (
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.rightActive
);
});
const activeIndex = this.historys.findIndex( const activeIndex = this.historys.findIndex(
item => item.name == this.activeValue
)
this.historys.splice(leftIndex + 1, this.historys.length)
item =>
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.activeValue
);
this.historys.splice(leftIndex + 1, this.historys.length);
if (leftIndex < activeIndex) { if (leftIndex < activeIndex) {
this.$router.push(right)
this.$router.push(right);
} }
sessionStorage.setItem('historys', JSON.stringify(this.historys))
sessionStorage.setItem("historys", JSON.stringify(this.historys));
}, },
closeOther() { closeOther() {
let right
this.historys = this.historys.filter(
item => {
if(item.name == this.rightActive){
right = item
let right;
this.historys = this.historys.filter(item => {
if (
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.rightActive
) {
right = item;
}
return (
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
this.rightActive
);
});
this.$router.push(right);
sessionStorage.setItem("historys", JSON.stringify(this.historys));
},
isSame(route1, route2) {
if (route1.name != route2.name) {
return false;
}
for (let key in route1.query) {
if (route1.query[key] != route2.query[key]) {
return false;
}
}
for (let key in route1.params) {
if (route1.params[key] != route2.params[key]) {
return false;
} }
return item.name == this.rightActive
} }
)
this.$router.push(right)
sessionStorage.setItem('historys', JSON.stringify(this.historys))
return true;
}, },
setTab(route) { setTab(route) {
if (!this.historys.some(item => item.name == route.name)) {
const obj = {}
obj.name = route.name
obj.meta = route.meta
obj.query = route.query
obj.params = route.params
this.historys.push(obj)
if (!this.historys.some(item => this.isSame(item, route))) {
const obj = {};
obj.name = route.name;
obj.meta = route.meta;
obj.query = route.query;
obj.params = route.params;
this.historys.push(obj);
} }
this.activeValue = this.$route.name
window.sessionStorage.setItem(
"activeValue",
this.$route.name +
JSON.stringify(this.$route.query) +
JSON.stringify(this.$route.params)
);
}, },
changeTab(component) { changeTab(component) {
const tab = component.$attrs.tab
this.$router.push({ name: tab.name,query:tab.query,params:tab.params })
const tab = component.$attrs.tab;
this.$router.push({
name: tab.name,
query: tab.query,
params: tab.params
});
}, },
removeTab(tab) { removeTab(tab) {
const index = this.historys.findIndex(item => item.name == tab)
if (this.$route.name == tab) {
const index = this.historys.findIndex(
item =>
item.name +
JSON.stringify(item.query) +
JSON.stringify(item.params) ==
tab
);
if (
this.$route.name +
JSON.stringify(this.$route.query) +
JSON.stringify(this.$route.params) ==
tab
) {
if (this.historys.length == 1) { if (this.historys.length == 1) {
this.$router.push({ name: this.defaultRouter })
this.$router.push({ name: this.defaultRouter });
} else { } else {
if (index < this.historys.length - 1) { if (index < this.historys.length - 1) {
this.$router.push({ name: this.historys[index + 1].name,query:this.historys[index + 1].query,params:this.historys[index + 1].params })
this.$router.push({
name: this.historys[index + 1].name,
query: this.historys[index + 1].query,
params: this.historys[index + 1].params
});
} else { } else {
this.$router.push({ name: this.historys[index - 1].name,query:this.historys[index - 1].query,params:this.historys[index - 1].params })
this.$router.push({
name: this.historys[index - 1].name,
query: this.historys[index - 1].query,
params: this.historys[index - 1].params
});
} }
} }
} }
this.historys.splice(index, 1)
this.historys.splice(index, 1);
} }
}, },
watch: { watch: {
contextMenuVisible() { contextMenuVisible() {
if (this.contextMenuVisible) { if (this.contextMenuVisible) {
document.body.addEventListener('click', () => {
this.contextMenuVisible = false
})
document.body.addEventListener("click", () => {
this.contextMenuVisible = false;
});
} else { } else {
document.body.removeEventListener('click', () => {
this.contextMenuVisible = false
})
document.body.removeEventListener("click", () => {
this.contextMenuVisible = false;
});
} }
}, },
$route(to) {
this.historys = this.historys.filter(item => !item.meta.hidden)
this.setTab(to)
sessionStorage.setItem('historys', JSON.stringify(this.historys))
$route(to, now) {
this.historys = this.historys.filter(item => !item.meta.closeTab);
this.setTab(to);
sessionStorage.setItem("historys", JSON.stringify(this.historys));
this.activeValue = window.sessionStorage.getItem("activeValue");
if (now && to && now.name == to.name) {
this.$bus.$emit("reload");
} }
} }
}
}
};
</script> </script>
<style lang="scss"> <style lang="scss">
.contextmenu { .contextmenu {
@ -234,6 +318,4 @@ export default {
background: #f2f2f2; background: #f2f2f2;
cursor: pointer; cursor: pointer;
} }
</style> </style>

15
web/src/view/layout/index.vue

@ -36,7 +36,7 @@
<el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9"> <el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
<div class="fl-right right-box"> <div class="fl-right right-box">
<Search /> <Search />
<Screenfull class="screenfull"></Screenfull>
<Screenfull class="screenfull" :style="{cursor:'pointer'}"></Screenfull>
<el-dropdown> <el-dropdown>
<span class="header-avatar"> <span class="header-avatar">
<CustomPic/> <CustomPic/>
@ -67,11 +67,11 @@
</transition> </transition>
<transition mode="out-in" name="el-fade-in-linear"> <transition mode="out-in" name="el-fade-in-linear">
<keep-alive> <keep-alive>
<router-view v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" v-if="$route.meta.keepAlive"></router-view>
<router-view v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" v-if="$route.meta.keepAlive && reloadFlag"></router-view>
</keep-alive> </keep-alive>
</transition> </transition>
<transition mode="out-in" name="el-fade-in-linear"> <transition mode="out-in" name="el-fade-in-linear">
<router-view v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" v-if="!$route.meta.keepAlive"></router-view>
<router-view v-loading="loadingFlag" element-loading-text="正在加载中" class="admin-box" v-if="!$route.meta.keepAlive && reloadFlag"></router-view>
</transition> </transition>
<BottomInfo /> <BottomInfo />
</el-main> </el-main>
@ -98,7 +98,7 @@ export default {
isMobile: false, isMobile: false,
isShadowBg: false, isShadowBg: false,
loadingFlag:false, loadingFlag:false,
reloadFlag:true,
value: '' value: ''
} }
}, },
@ -112,6 +112,12 @@ export default {
}, },
methods: { methods: {
...mapActions('user', ['LoginOut']), ...mapActions('user', ['LoginOut']),
reload(){
this.reloadFlag = false
this.$nextTick(()=>{
this.reloadFlag = true
})
},
totalCollapse() { totalCollapse() {
this.isCollapse = !this.isCollapse this.isCollapse = !this.isCollapse
this.isSider = !this.isCollapse this.isSider = !this.isCollapse
@ -153,6 +159,7 @@ export default {
} }
this.$bus.emit('collapse', this.isCollapse) this.$bus.emit('collapse', this.isCollapse)
this.$bus.emit('mobile', this.isMobile) this.$bus.emit('mobile', this.isMobile)
this.$bus.on("reload",this.reload)
this.$bus.on("showLoading",()=>{ this.$bus.on("showLoading",()=>{
this.loadingFlag = true this.loadingFlag = true
}) })

14
web/src/view/layout/search/search.vue

@ -19,8 +19,14 @@
</el-select> </el-select>
</div> </div>
</transition> </transition>
<div
:style="{display:'inline-block',float:'right',width:'31px',textAlign:'left',fontSize:'16px',paddingTop:'2px'}"
class="user-box"
>
<i @click="$bus.$emit('reload')" :style="{cursor:'pointer'}" class="el-icon-refresh" />
</div>
<div :style="{display:'inline-block',float:'right'}" class="user-box"> <div :style="{display:'inline-block',float:'right'}" class="user-box">
<i @click="showSearch()" class="el-icon-search search-icon"></i>
<i :style="{cursor:'pointer'}" @click="showSearch()" class="el-icon-search search-icon"></i>
</div> </div>
</div> </div>
</template> </template>
@ -48,9 +54,9 @@ export default {
}, },
showSearch() { showSearch() {
this.show = true; this.show = true;
this.$nextTick(()=>{
this.$refs['search-input'].focus()
})
this.$nextTick(() => {
this.$refs["search-input"].focus();
});
} }
} }
}; };

7
web/src/view/superAdmin/menu/menu.vue

@ -117,6 +117,12 @@
<el-option :value="true" label="是"></el-option> <el-option :value="true" label="是"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="closeTab" prop="meta.closeTab" style="width:30%">
<el-select placeholder="是否自动关闭tab" v-model="form.meta.closeTab">
<el-option :value="false" label="否"></el-option>
<el-option :value="true" label="是"></el-option>
</el-select>
</el-form-item>
</el-form> </el-form>
<div class="warning">新增菜单需要在角色管理内配置权限才可使用</div> <div class="warning">新增菜单需要在角色管理内配置权限才可使用</div>
<div> <div>
@ -209,6 +215,7 @@ export default {
title: "", title: "",
icon: "", icon: "",
defaultMenu: false, defaultMenu: false,
closeTab: false,
keepAlive: false keepAlive: false
}, },
parameters: [] parameters: []

Loading…
Cancel
Save