This commit is contained in:
sc 2021-04-22 14:12:22 +08:00
parent 2deb78a613
commit b651e9055d
18 changed files with 275 additions and 72 deletions

BIN
public/images/avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/images/avatar2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
public/images/avatar3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

View File

@ -1,34 +1,35 @@
{
"code": 200,
"data": {
"userInfo" : {
"userName":"Admin"
"userInfo": {
"userId": "1",
"userName": "Administrator"
},
"menuList" : [
{
"menuList": [{
"name": "组件",
"path": "/vab",
"meta": {
"icon":"el-icon-takeaway-box"
"icon": "el-icon-takeaway-box"
},
"children": []
},
"children": [
{
"path": "/vab/list",
"name": "布局",
"path": "/layout",
"meta": {
"icon": "el-icon-files"
},
"children": [{
"path": "/layout/list",
"name": "列表",
"meta": {},
"component": "list"
},
{
"path": "/vab/show",
"path": "/layout/show",
"name": "详情",
"meta": {},
"component": "show"
},
{
"path": "/vab/lala",
"name": "404",
"meta": {},
"component": "lala"
}
]
},
@ -36,14 +37,54 @@
"name": "其他",
"path": "/other",
"meta": {
"icon":"el-icon-more"
"icon": "el-icon-more"
},
"children": [
{
"path": "/other/1",
"name": "other1",
"path": "/link",
"name": "外部链接",
"meta": {
"icon": "el-icon-link"
},
"children": [
{
"path": "https://baidu.com",
"name": "百度",
"meta": {
"target": "_blank"
}
},
{
"path": "https://www.google.cn",
"name": "谷歌",
"meta": {
"target": "_blank"
}
}
]
},
{
"path": "/iframe",
"name": "Iframe",
"meta": {
"icon": "el-icon-position"
},
"children": [
{
"path": "https://vue3js.cn/docs/zh/",
"name": "VUE 3"
},
{
"path": "https://element-plus.org?id=1",
"name": "Element Plus"
}
]
},
{
"path": "/other/lala",
"name": "404",
"meta": {},
"component": "list"
"component": "lala"
}
]
},
@ -51,16 +92,14 @@
"name": "配置",
"path": "/setting",
"meta": {
"icon":"el-icon-setting"
"icon": "el-icon-setting"
},
"children": [
{
"children": [{
"path": "/setting/1",
"name": "setting1",
"meta": {},
"component": "lala"
}
]
}]
}
]
},

View File

@ -1,10 +1,13 @@
<template>
<label v-for="navMenu in navMenus" v-bind:key="navMenu">
<div v-if="navMenus.length<=0" style="padding:20px;">
<el-alert title="无子集菜单" center type="info" :closable="false"></el-alert>
</div>
<template v-for="navMenu in navMenus" v-bind:key="navMenu">
<el-menu-item v-if="!navMenu.children" :index="navMenu.path">
<a v-if="navMenu.meta&&navMenu.meta.target" :href="navMenu.path" :target="navMenu.meta.target" @click.stop='a'></a>
<i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i>
<span>{{navMenu.name}}</span>
</el-menu-item>
<el-submenu v-if="navMenu.children" :index="navMenu.path">
<template #title>
<i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i>
@ -12,7 +15,7 @@
</template>
<NavMenu :navMenus="navMenu.children"></NavMenu>
</el-submenu>
</label>
</template>
</template>
<script>
@ -22,6 +25,8 @@
data() {
return {}
},
methods: {}
methods: {
a(){}
}
}
</script>

View File

@ -1,14 +1,77 @@
<template>
<div class="adminui-header">
header
<div class="left-panel">
<el-breadcrumb separator-class="el-icon-arrow-right">
<template v-for="(item) in breadList" v-bind:key="item" >
<el-breadcrumb-item v-if="item.path !='/'"><i v-if="item.meta&&item.meta.icon" :class="item.meta.icon || 'el-icon-menu'"></i>{{item.name}}</el-breadcrumb-item>
</template>
</el-breadcrumb>
</div>
<div class="center-panel">
</div>
<div class="right-panel">
<div class="setting panel-item">
<i class="el-icon-setting"></i>
</div>
<el-popover placement="bottom" :width="300" trigger="click">
<template #reference>
<div class="msg panel-item">
<el-badge :value="1" class="badge" type="danger">
<i class="el-icon-bell"></i>
</el-badge>
</div>
</template>
<div>
<el-empty description="暂无消息"></el-empty>
</div>
</el-popover>
<el-dropdown trigger="click" @command="handleUser">
<div class="user panel-item">
<el-avatar :size="30">{{ userNameF }}</el-avatar>
<label>{{ userName }}<i class="el-icon-arrow-down el-icon--right"></i></label>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="userInfo">个人设置</el-dropdown-item>
<el-dropdown-item divided command="outLogin">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script>
export default {
props: {},
setup() {
data() {
return {
breadList: [],
userName: "",
userNameF: ""
}
},
created() {
var userInfo = this.$TOOL.data.get("user").userInfo;
this.userName = userInfo.userName;
this.userNameF = this.userName.substring(0,1);
this.getBreadcrumb();
},
watch: {
$route() {
this.getBreadcrumb();
}
},
methods: {
handleUser(command) {
if(command == "outLogin"){
this.$router.replace({path: '/login'});
}
},
getBreadcrumb(){
let matched = this.$route.matched;
this.breadList = matched;
}
}
}
</script>

View File

@ -11,7 +11,7 @@
<div class="aminui-side">
<div class="adminui-side-scroll">
<el-menu :default-active="$route.path" router>
<el-menu :default-active="$route.fullPath" router>
<NavMenu :navMenus="nextMenu"></NavMenu>
</el-menu>
</div>
@ -37,7 +37,7 @@
var menu = this.$TOOL.data.get("user").menuList;
var home = this.$router.options.routes[0].children[0];
menu.unshift(home);
this.menu = menu;
this.menu = this.filterUrl(menu);
this.showThis()
},
setup() {
@ -51,13 +51,9 @@
methods: {
//
showThis(){
var menu = this.$TOOL.data.get("user").menuList;
var home = this.$router.options.routes[0].children[0];
menu.unshift(home);
var pl = this.$route.path.split("/");
var p = pl.length<=2?home.path:"/" + pl[1];
this.pmenu = p==home.path ? home:this.getRoute(p, menu);
this.nextMenu = this.pmenu.children;
this.pmenu = this.$route.matched[1] || home;
this.nextMenu = this.filterUrl(this.pmenu.children);
},
//
showMenu(route) {
@ -74,6 +70,21 @@
this.getRoute(path, item.children);
}
}
},
//
filterUrl(map){
var newMap = []
map.forEach(item => {
item.meta = item.meta?item.meta:{};
if(item.path.startsWith('http') && item.meta.target!='_blank'){
item.path = `/${encodeURIComponent(item.path)}`;
}
if(item.children&&item.children.length > 0){
this.filterUrl(item.children);
}
newMap.push(item)
})
return newMap;
}
}
}

View File

@ -5,7 +5,7 @@
<Head></Head>
<Tags></Tags>
<div class="adminui-main">
<router-view></router-view>
<router-view :key="$route.fullPath"></router-view>
</div>
</div>

View File

@ -60,6 +60,7 @@ router.beforeEach(async (to, from, next) => {
let userInfo = tool.data.get("user");
if(to.path === "/login"){
isGetApiRouter = false;
next();
return false;
}
@ -79,7 +80,7 @@ router.beforeEach(async (to, from, next) => {
})
router.addRoute(routes_404)
if (to.matched.length == 0) {
router.push(to.path);
router.push(to.fullPath);
}
isGetApiRouter = true;
}
@ -94,7 +95,7 @@ router.onError((error) => {
NProgress.done();
ElNotification.error({
title: '路由错误',
message: error
message: error.message
});
});
@ -102,14 +103,22 @@ router.onError((error) => {
//转换
function filterAsyncRouter(routerMap) {
const accessedRouters = []
routerMap.filter(itemRouter => {
accessedRouters.push({
path: itemRouter.path,
name: itemRouter.name,
meta: itemRouter.meta,
children: filterAsyncRouter(itemRouter.children || []),
component: loadComponent(itemRouter.component)
})
routerMap.forEach(item => {
item.meta = item.meta?item.meta:{};
//处理外部链接特殊路由
if(item.path.startsWith('http') && item.meta.target!='_blank'){
item.path = `/${encodeURIComponent(item.path)}`;
item.component = 'other/iframe';
}
//MAP转路由对象
var route = {
path: item.path,
name: item.name,
meta: item.meta,
children: item.children ? filterAsyncRouter(item.children) : null,
component: loadComponent(item.component)
}
accessedRouters.push(route)
})
return accessedRouters
}

View File

@ -1,4 +1,4 @@
#app, body, html {width: 100%;height: 100%;background-color: #f8f8f8;font-size: 12px;}
#app, body, html {width: 100%;height: 100%;background-color: #f6f8f9;font-size: 12px;}
* {margin: 0;padding: 0;box-sizing: border-box;outline: none;}
/* 全局滚动条样式 */
@ -29,7 +29,23 @@
.aminui-body {position: absolute;z-index: 70;top:0px;left:275px;bottom:0px;right:0px;}
.adminui-header {height: 50px;border-bottom: 1px solid #ebeef5;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);}
.adminui-header {height: 50px;border-bottom: 1px solid #ebeef5;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);display: flex;justify-content:space-between;}
.adminui-header .left-panel {display: flex;align-items: center;padding-left:20px;}
.adminui-header .right-panel {display: flex;align-items: center;}
.adminui-header .panel-item {height:50px;line-height: 50px;padding:0 20px;cursor: pointer;}
.adminui-header .panel-item i {font-size: 16px;}
.adminui-header .panel-item .badge .el-badge__content {top:15px}
.adminui-header .panel-item:hover {background: #eee;}
.adminui-header .el-breadcrumb .el-breadcrumb__inner i {margin-right:5px;}
.adminui-header .user {display: flex;align-items: center;}
.adminui-header .user label {display: inline-block;margin-left:5px;font-size: 12px;cursor:pointer;}
.adminui-tags {height:35px;background: #fff;border-bottom: 1px solid #e6e6e6;box-shadow: 0 1px 4px rgba(0,21,41,.08);}
.adminui-tags li {cursor: pointer;display: inline-block;float: left;height:34px;line-height: 34px;}
.adminui-tags li a {display: inline-block;padding:0 10px;width:100%;height:100%;color: #999;text-decoration:none;}
@ -40,8 +56,9 @@
.adminui-tags li.active a {color: #fff;}
.adminui-main {position: absolute;top:85px;left:0px;right:0px;bottom:0px;overflow: auto;}
.adminui-main {position: absolute;top:85px;left:0px;right:0px;bottom:0px;overflow: auto;padding: 20px;}
.el-menu {border: none!important;}
.el-menu-item.is-active {background: #ecf5ff;}
.el-menu .el-menu-item a {color: inherit;text-decoration: none;display: block;width:100%;height:100%;position: absolute;top:0px;left:0px;}

View File

@ -1,9 +1,44 @@
<template>
<div>HOME</div>
<el-row>
<el-col :span="24">
<el-card shadow="never">
<div class="welTop">
<div class="icon">
<el-avatar :size="60" src="images/avatar.jpg"></el-avatar>
</div>
<div class="main">
<h2>~ admin忙碌了一上午记得吃午饭哦</h2>
<p>最近更新动态面包屑外部链接Iframe链接等</p>
</div>
<div class="icons">
<div class="avatar-list">
<el-tooltip content="Sakuya" placement="top">
<el-avatar class="avatar" :size="30" src="images/avatar.jpg"></el-avatar>
</el-tooltip>
<el-tooltip content="Lolowan" placement="top">
<el-avatar class="avatar" :size="30" src="images/avatar2.gif"></el-avatar>
</el-tooltip>
<el-tooltip content="Ali" placement="top">
<el-avatar class="avatar" :size="30" src="images/avatar3.gif"></el-avatar>
</el-tooltip>
</div>
<p>Participants</p>
</div>
</div>
</el-card>
</el-col>
</el-row>
</template>
<script>
</script>
<style>
<style scoped>
.welTop {display: flex;}
.welTop .main {margin-left:20px;}
.welTop .main h2 {font-size: 20px;color: #3c4a54;}
.welTop .main p {color: #999;margin-top:10px;line-height: 1.8;}
.welTop .icons {margin-left:auto;text-align: center;}
.welTop .icons p {font-size: 12px;}
.avatar-list .avatar {margin-left: -10px;border: 3px solid #fff;cursor: pointer;}
</style>

View File

@ -1,6 +1,7 @@
<template>
<div>LIST</div>
<div style="height:1800px"></div>
<div>
<el-empty description="LIST"></el-empty>
</div>
</template>
<script>

View File

@ -17,7 +17,12 @@
login: async function() {
var userInfo = await this.$API.user.info();
this.$TOOL.data.set("user", userInfo.data);
this.$router.push({path: '/'});
this.$router.replace({path: '/'});
//
this.$notify.success({
title: '登录成功',
message: '欢迎登录'
})
}
}
}

View File

@ -1,5 +1,7 @@
<template>
<div>404</div>
<div>
<el-empty description="404"></el-empty>
</div>
</template>
<script>

View File

@ -0,0 +1,17 @@
<template>
<iframe :src="src" frameborder='0'></iframe>
</template>
<script>
export default {
data() {
return {
src: decodeURIComponent(this.$route.fullPath.substr(1))
}
}
}
</script>
<style scoped>
iframe {border:0;position: absolute;top:0px;left:0px;right:0px;bottom:0px;width:100%;height:100%;}
</style>

View File

@ -1,7 +1,6 @@
<template>
<div>SHOW</div>
<div class="main">
<el-input v-model="input" placeholder="请输入内容" clearable></el-input>
<div>
<el-empty description="SHOW"></el-empty>
</div>
</template>
@ -15,6 +14,6 @@
}
</script>
<style>
<style scoped>
.main {width:200px;}
</style>