删除上个版本的代码

Former-commit-id: 6bda49593a2b4816ad2b4b947fa353c6240b2a06
This commit is contained in:
liyang
2018-08-22 15:12:03 +08:00
parent 73b26812ef
commit e4a16cf07e
125 changed files with 0 additions and 7539 deletions
-15
View File
@@ -1,15 +0,0 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style lang="scss">
@import '~@/assets/style/public-class.scss';
</style>
@@ -1,13 +0,0 @@
// 过渡动画 横向渐变
.fade-transverse-leave-active,
.fade-transverse-enter-active {
transition: all .5s;
}
.fade-transverse-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transverse-leave-to {
opacity: 0;
transform: translateX(30px);
}
-13
View File
@@ -1,13 +0,0 @@
// 优化显示
html, body {
margin: 0px;
height: 100%;
font-family: "Arial", "Microsoft YaHei", "黑体", "宋体", sans-serif;
#app {
@extend %full;
a {
text-decoration: none;
}
}
}
-20
View File
@@ -1,20 +0,0 @@
// element 样式补丁
.el-card {
&.is-always-shadow {
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
}
&.is-hover-shadow {
&:hover {
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
}
}
}
.el-menu--horizontal {
border-bottom: none !important;
}
.el-tabs__item:focus.is-active.is-focus:not(:active) {
box-shadow: none !important;
}
-65
View File
@@ -1,65 +0,0 @@
@import 'public';
// 补丁 base
@import '~@/assets/style/fixed/base.scss';
// 补丁 element
@import '~@/assets/style/fixed/element.scss';
// 动画
@import '~@/assets/style/animate/vue-transition.scss';
// 在这里写公用的class
// 注意 这个文件里只写class
// mixin等内容请在 public.scss 里书写
// 文字相关
.#{$prefix}-text-center {
text-align: center;
}
// 浮动相关
.#{$prefix}-fl {
float: left;
}
.#{$prefix}-fr {
float: right;
}
.#{$prefix}-clearfix:before,
.#{$prefix}-clearfix:after {
display: table;
content: "";
}
.#{$prefix}-clearfix:after {
clear: both
}
// 边距相关
$sizes: (0, 5, 10, 15, 20);
@for $index from 1 to 6 {
.#{$prefix}-m-#{nth($sizes, $index)} { margin: #{nth($sizes, $index)}px !important; }
.#{$prefix}-mt-#{nth($sizes, $index)} { margin-top: #{nth($sizes, $index)}px !important; }
.#{$prefix}-mr-#{nth($sizes, $index)} { margin-right: #{nth($sizes, $index)}px !important; }
.#{$prefix}-mb-#{nth($sizes, $index)} { margin-bottom: #{nth($sizes, $index)}px !important; }
.#{$prefix}-ml-#{nth($sizes, $index)} { margin-left: #{nth($sizes, $index)}px !important; }
.#{$prefix}-p-#{nth($sizes, $index)} { padding: #{nth($sizes, $index)}px !important; }
.#{$prefix}-pt-#{nth($sizes, $index)} { padding-top: #{nth($sizes, $index)}px !important; }
.#{$prefix}-pr-#{nth($sizes, $index)} { padding-right: #{nth($sizes, $index)}px !important; }
.#{$prefix}-pb-#{nth($sizes, $index)} { padding-bottom: #{nth($sizes, $index)}px !important; }
.#{$prefix}-pl-#{nth($sizes, $index)} { padding-left: #{nth($sizes, $index)}px !important; }
}
// 快速使用
.#{$prefix}-m { margin: 20px !important; }
.#{$prefix}-mt { margin-top: 20px !important; }
.#{$prefix}-mr { margin-right: 20px !important; }
.#{$prefix}-mb { margin-bottom: 20px !important; }
.#{$prefix}-ml { margin-left: 20px !important; }
.#{$prefix}-p { padding: 20px !important; }
.#{$prefix}-pt { padding-top: 20px !important; }
.#{$prefix}-pr { padding-right: 20px !important; }
.#{$prefix}-pb { padding-bottom: 20px !important; }
.#{$prefix}-pl { padding-left: 20px !important; }
-44
View File
@@ -1,44 +0,0 @@
@import '~@/assets/style/unit/color.scss';
// 工具类名统一前缀
$prefix: d2;
// 禁止用户选中 鼠标变为手形
%unable-select {
user-select: none;
cursor: pointer;
}
// 填满父元素
// 组要父元素 position: relative | absolute;
%full {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
// flex 垂直水平居中
%flex-center-row {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
}
%flex-center-col {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
// 将元素模拟成卡片外观
%card {
border: 1px solid #dddee1;
border-color: #e9eaec;
background: #fff;
border-radius: 4px;
font-size: 14px;
position: relative;
}
-2
View File
@@ -1,2 +0,0 @@
@import './setting.scss';
@import '../theme.scss';
-59
View File
@@ -1,59 +0,0 @@
// 主题名称
$theme-name: 'd2';
// 主题背景颜色
$theme-bg-color: #ebf1f6;
// 主题背景图片遮罩
$theme-bg-mask: rgba(#000, 0);
// container组件
$theme-container-background-color: rgba(#FFF, 1);
$theme-container-header-footer-background-color: #FFF;
$theme-container-border-inner: 1px solid #cfd7e5;
$theme-container-border-outer: 1px solid #cfd7e5;
$theme-multiple-page-control-color: $color-text-normal;
$theme-multiple-page-control-color-active: #2f74ff;
$theme-multiple-page-control-nav-prev-color: #cfd7e5;
$theme-multiple-page-control-nav-next-color: #cfd7e5;
$theme-multiple-page-control-border-color: #cfd7e5;
$theme-multiple-page-control-border-color-active: #FFF;
$theme-multiple-page-control-background-color: rgba(#000, .03);
$theme-multiple-page-control-background-color-active: #FFF;
// 顶栏和侧边栏中展开的菜单 hover 状态下
$theme-menu-item-color-hover: #293849;
$theme-menu-item-background-color-hover: #ecf5ff;
// 顶栏上的文字颜色
$theme-header-item-color: $color-text-normal;
$theme-header-item-background-color: transparent;
// 顶栏上的项目在 hover 时
$theme-header-item-color-hover: #2f74ff;
$theme-header-item-background-color-hover: rgba(#FFF, .5);
// 顶栏上的项目在 focus 时
$theme-header-item-color-focus: #2f74ff;
$theme-header-item-background-color-focus: rgba(#FFF, .5);
// 顶栏上的项目在 active 时
$theme-header-item-color-active: #2f74ff;
$theme-header-item-background-color-active: rgba(#FFF, .5);
// 侧边栏上的文字颜色
$theme-aside-item-color: $color-text-normal;
$theme-aside-item-background-color: transparent;
// 侧边栏上的项目在 hover 时
$theme-aside-item-color-hover: #2f74ff;
$theme-aside-item-background-color-hover: rgba(#FFF, .5);
// 侧边栏上的项目在 focus 时
$theme-aside-item-color-focus: #2f74ff;
$theme-aside-item-background-color-focus: rgba(#FFF, .5);
// 侧边栏上的项目在 active 时
$theme-aside-item-color-active: #2f74ff;
$theme-aside-item-background-color-active: rgba(#FFF, .5);
// 侧边栏菜单为空的时候显示的元素
$theme-aside-menu-empty-icon-color: $color-text-normal;
$theme-aside-menu-empty-text-color: $color-text-normal;
$theme-aside-menu-empty-background-color: rgba(#000, .03);
$theme-aside-menu-empty-icon-color-hover: $color-text-main;
$theme-aside-menu-empty-text-color-hover: $color-text-main;
$theme-aside-menu-empty-background-color-hover: rgba(#000, .05);
-2
View File
@@ -1,2 +0,0 @@
@import './setting.scss';
@import '../theme.scss';
-59
View File
@@ -1,59 +0,0 @@
// 主题名称
$theme-name: 'line';
// 主题背景颜色
$theme-bg-color: #f8f8f9;
// 主题背景图片遮罩
$theme-bg-mask: rgba(#000, 0);
// container组件
$theme-container-background-color: rgba(#FFF, .8);
$theme-container-header-footer-background-color: #FFF;
$theme-container-border-inner: 1px solid $color-border-2;
$theme-container-border-outer: 1px solid #cfd7e5;
$theme-multiple-page-control-color: #FFF;
$theme-multiple-page-control-color-active: $color-text-normal;
$theme-multiple-page-control-nav-prev-color: #cfd7e5;
$theme-multiple-page-control-nav-next-color: #cfd7e5;
$theme-multiple-page-control-border-color: #cfd7e5;
$theme-multiple-page-control-border-color-active: #FFF;
$theme-multiple-page-control-background-color: #cfd7e5;
$theme-multiple-page-control-background-color-active: #FFF;
// 顶栏和侧边栏中展开的菜单 hover 状态下
$theme-menu-item-color-hover: #293849;
$theme-menu-item-background-color-hover: #EFEFEF;
// 顶栏上的文字颜色
$theme-header-item-color: $color-text-normal;
$theme-header-item-background-color: transparent;
// 顶栏上的项目在 hover 时
$theme-header-item-color-hover: $color-text-main;
$theme-header-item-background-color-hover: rgba(#000, .02);
// 顶栏上的项目在 focus 时
$theme-header-item-color-focus: $color-text-main;
$theme-header-item-background-color-focus: rgba(#000, .02);
// 顶栏上的项目在 active 时
$theme-header-item-color-active: $color-text-main;
$theme-header-item-background-color-active: rgba(#000, .03);
// 侧边栏上的文字颜色
$theme-aside-item-color: $color-text-normal;
$theme-aside-item-background-color: transparent;
// 侧边栏上的项目在 hover 时
$theme-aside-item-color-hover: $color-text-main;
$theme-aside-item-background-color-hover: rgba(#000, .02);
// 侧边栏上的项目在 focus 时
$theme-aside-item-color-focus: $color-text-main;
$theme-aside-item-background-color-focus: rgba(#000, .02);
// 侧边栏上的项目在 active 时
$theme-aside-item-color-active: $color-text-main;
$theme-aside-item-background-color-active: rgba(#000, .03);
// 侧边栏菜单为空的时候显示的元素
$theme-aside-menu-empty-icon-color: $color-text-normal;
$theme-aside-menu-empty-text-color: $color-text-normal;
$theme-aside-menu-empty-background-color: rgba(#000, .03);
$theme-aside-menu-empty-icon-color-hover: $color-text-main;
$theme-aside-menu-empty-text-color-hover: $color-text-main;
$theme-aside-menu-empty-background-color-hover: rgba(#000, .05);
-29
View File
@@ -1,29 +0,0 @@
export default [
{
title: 'd2admin 经典',
name: 'd2',
preview: 'image/theme/d2/preview@2x.png'
},
{
title: '紫罗兰',
name: 'violet',
preview: 'image/theme/violet/preview@2x.png'
},
{
title: '简约线条',
name: 'line',
backgroundImage: 'image/theme/line/bg.jpg',
preview: 'image/theme/line/preview@2x.png'
},
{
title: '流星',
name: 'star',
backgroundImage: 'image/theme/star/bg.jpg',
preview: 'image/theme/star/preview@2x.png'
},
{
title: 'Tomorrow Night Blue (vsCode)',
name: 'tomorrow-night-blue',
preview: 'image/theme/tomorrow-night-blue/preview@2x.png'
}
]
-8
View File
@@ -1,8 +0,0 @@
@import '~@/assets/style/public.scss';
@import '~@/assets/style/theme/theme-base.scss';
@import '~@/assets/style/theme/d2/index.scss';
@import '~@/assets/style/theme/line/index.scss';
@import '~@/assets/style/theme/star/index.scss';
@import '~@/assets/style/theme/tomorrow-night-blue/index.scss';
@import '~@/assets/style/theme/violet/index.scss';
-2
View File
@@ -1,2 +0,0 @@
@import './setting.scss';
@import '../theme.scss';
-59
View File
@@ -1,59 +0,0 @@
// 主题名称
$theme-name: 'star';
// 主题背景颜色
$theme-bg-color: #EFF4F8;
// 主题背景图片遮罩
$theme-bg-mask: rgba(#000, .3);
// container组件
$theme-container-background-color: rgba(#FFF, .9);
$theme-container-header-footer-background-color: #FFF;
$theme-container-border-inner: 1px solid $color-border-1;
$theme-container-border-outer: 1px solid #114450;
$theme-multiple-page-control-color: #FFF;
$theme-multiple-page-control-color-active: $color-text-normal;
$theme-multiple-page-control-nav-prev-color: #FFF;
$theme-multiple-page-control-nav-next-color: #FFF;
$theme-multiple-page-control-border-color: #114450;
$theme-multiple-page-control-border-color-active: #FFF;
$theme-multiple-page-control-background-color: rgba(#FFF, .5);
$theme-multiple-page-control-background-color-active: #FFF;
// 顶栏和侧边栏中展开的菜单 hover 状态下
$theme-menu-item-color-hover: #293849;
$theme-menu-item-background-color-hover: #ecf5ff;
// 顶栏上的文字颜色
$theme-header-item-color: #FFF;
$theme-header-item-background-color: transparent;
// 顶栏上的项目在 hover 时
$theme-header-item-color-hover: #FFF;
$theme-header-item-background-color-hover: rgba(#000, .2);
// 顶栏上的项目在 focus 时
$theme-header-item-color-focus: #FFF;
$theme-header-item-background-color-focus: rgba(#000, .2);
// 顶栏上的项目在 active 时
$theme-header-item-color-active: #FFF;
$theme-header-item-background-color-active: rgba(#000, .3);
// 侧边栏上的文字颜色
$theme-aside-item-color: #FFF;
$theme-aside-item-background-color: transparent;
// 侧边栏上的项目在 hover 时
$theme-aside-item-color-hover: #FFF;
$theme-aside-item-background-color-hover: rgba(#000, .2);
// 侧边栏上的项目在 focus 时
$theme-aside-item-color-focus: #FFF;
$theme-aside-item-background-color-focus: rgba(#000, .2);
// 侧边栏上的项目在 active 时
$theme-aside-item-color-active: #FFF;
$theme-aside-item-background-color-active: rgba(#000, .3);
// 侧边栏菜单为空的时候显示的元素
$theme-aside-menu-empty-icon-color: #FFF;
$theme-aside-menu-empty-text-color: #FFF;
$theme-aside-menu-empty-background-color: rgba(#FFF, .2);
$theme-aside-menu-empty-icon-color-hover: #FFF;
$theme-aside-menu-empty-text-color-hover: #FFF;
$theme-aside-menu-empty-background-color-hover: rgba(#FFF, .3);
-405
View File
@@ -1,405 +0,0 @@
// 减小弹出菜单的项目高度
.el-menu--popup {
.el-menu-item {
height: 36px;
line-height: 36px;
}
.el-submenu__title {
height: 36px;
line-height: 36px;
}
}
// 整体框架结构
.d2-layout-header-aside-group {
height: 100%;
width: 100%;
min-width: 900px;
background-size: cover;
background-position: center;
overflow: hidden;
position: relative;
// 背景上面的半透明遮罩
.d2-layout-header-aside-mask {
@extend %full;
}
// 内容层
.d2-layout-header-aside-content {
@extend %full;
$d2-theme-header-height: 60px;
.d2-theme-header {
height: $d2-theme-header-height;
}
.d2-theme-container {
.d2-theme-container-aside {
transition: width .3s;
position: relative;
.d2-layout-header-aside-menu-side {
@extend %full;
overflow: hidden;
}
}
.d2-theme-container-main {
padding: 0px;
position: relative;
overflow: hidden;
.d2-theme-container-main-body {
flex-grow: 1;
position: relative;
}
}
}
}
}
// 主题公用
.d2-layout-header-aside-group {
&.grayMode {
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter: gray;
}
// 主体
.d2-layout-header-aside-content {
// [布局] 顶栏
.d2-theme-header {
// logo区域
.logo-group {
transition: width .3s;
float: left;
text-align: center;
img {
height: 60px;
}
}
// 折叠侧边栏切换按钮
.toggle-aside-btn {
float: left;
height: 60px;
width: 60px;
display: flex;
justify-content: center;
align-items: center;
@extend %unable-select;
i {
font-size: 20px;
margin-top: 4px;
}
}
// [菜单] 顶栏
.el-menu {
float: left;
border-bottom: none;
background-color: transparent;
%header-menu-item {
@extend %unable-select;
i.fa {
font-size: 16px;
margin-right: 4px;
}
}
.el-menu-item {
@extend %header-menu-item;
border-bottom: none;
}
.el-submenu {
@extend %header-menu-item;
.el-submenu__title {
border-bottom: none;
}
}
}
// 顶栏右侧的按钮
.d2-header-right {
float: right;
height: 60px;
display: flex;
align-items: center;
.btn-text {
padding: 14px 12px;
border-radius: 4px;
margin: 0px !important;
margin-left: 10px !important;
}
.el-dropdown {
@extend %unable-select;
}
}
}
// [布局] 顶栏下面
.d2-theme-container {
// 侧边栏
.d2-theme-container-aside {
%d2-theme-container-aside-menu-icon {
width: 20px;
text-align: center;
font-size: 16px;
}
// [菜单] 正常状态
.el-menu {
@extend %unable-select;
background-color: transparent;
border-right: none;
.el-menu-item {
i {
@extend %d2-theme-container-aside-menu-icon;
}
}
}
.el-submenu {
@extend %unable-select;
.el-submenu__title {
i {
@extend %d2-theme-container-aside-menu-icon;
}
.el-submenu__icon-arrow {
margin-top: -10px;
}
}
}
// 菜单为空的时候显示的信息
.d2-layout-header-aside-menu-empty {
height: 160px;
margin: 10px;
margin-top: 0px;
border-radius: 4px;
@extend %unable-select;
i {
font-size: 30px;
margin-bottom: 10px;
}
span {
font-size: 14px;
}
}
// [菜单] 折叠状态
.el-menu--collapse {
background-color: transparent;
.el-submenu__title {
text-align: center;
}
}
}
// 右下 主体
.d2-theme-container-main {
// 主体部分分为多页面控制器 和主体
.d2-theme-container-main-header {
// 多页面控制器
.d2-multiple-page-control-group {
padding-right: 20px;
.d2-multiple-page-control-content {
overflow: auto;
position: relative;
.d2-multiple-page-control-content-inner {
.d2-multiple-page-control {
.el-tabs__header.is-top {
margin: 0px;
}
.el-tabs__nav {
overflow: hidden;
}
}
}
}
.d2-multiple-page-control-btn {
position: relative;
bottom: -1px;
.el-dropdown {
.el-button-group {
.el-button:first-child {
border-bottom-left-radius: 0px;
}
.el-button:last-child {
border-bottom-right-radius: 0px;
}
}
}
}
}
}
// 主体
.d2-theme-container-main-body {
// 布局组件
.container-component {
@extend %full;
overflow: hidden;
// 填充式布局组件
.d2-container-full {
position: absolute;
top: 0px;
right: 20px;
bottom: 0px;
left: 0px;
display: flex;
flex-direction: column;
overflow: hidden;
.d2-container-full__header {
padding: 20px;
}
.d2-container-full__body {
flex-grow: 1;
padding: 20px 20px;
overflow: auto;
position: relative;
}
.d2-container-full__footer {
padding: 20px;
}
}
// 填充式布局组件 - 滚动优化
.d2-container-full-bs {
position: absolute;
top: 0px;
right: 20px;
bottom: 0px;
left: 0px;
display: flex;
flex-direction: column;
overflow: hidden;
.d2-container-full-bs__header {
padding: 20px;
}
.d2-container-full-bs__body {
flex-grow: 1;
overflow: hidden;
position: relative;
.d2-container-full-bs__body-wrapper-inner {
padding: 20px;
position: relative;
}
}
.d2-container-full-bs__footer {
padding: 20px;
}
}
// 隐形布局组件
.d2-container-ghost {
position: absolute;
top: 0px;
right: 20px;
bottom: 0px;
left: 0px;
display: flex;
flex-direction: column;
overflow: hidden;
.d2-container-ghost__header {
padding: 20px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.d2-container-ghost__body {
flex-grow: 1;
overflow: auto;
position: relative;
}
.d2-container-ghost__footer {
padding: 20px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
}
// 隐形布局组件 - 滚动优化
.d2-container-ghost-bs {
position: absolute;
top: 0px;
right: 20px;
bottom: 0px;
left: 0px;
display: flex;
flex-direction: column;
overflow: hidden;
.d2-container-ghost-bs__header {
padding: 20px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.d2-container-ghost-bs__body {
flex-grow: 1;
overflow: hidden;
position: relative;
}
.d2-container-ghost-bs__footer {
padding: 20px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
}
// 卡片式布局组件
.d2-container-card {
position: absolute;
top: 0px;
right: 20px;
bottom: 0px;
left: 0px;
display: flex;
flex-direction: column;
overflow: hidden;
.d2-container-card__header {
padding: 20px;
}
.d2-container-card__body {
flex-grow: 1;
overflow: auto;
.d2-container-card__body-card {
position: relative;
margin-bottom: 20px;
padding: 20px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
}
.d2-container-card__footer {
padding: 20px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
}
// 卡片式布局组件 - 滚动优化
.d2-container-card-bs {
position: absolute;
top: 0px;
right: 20px;
bottom: 0px;
left: 0px;
display: flex;
flex-direction: column;
overflow: hidden;
.d2-container-card-bs__header {
padding: 20px;
}
.d2-container-card-bs__body {
position: relative;
flex-grow: 1;
overflow: hidden;
.d2-container-card-bs__body-wrapper-inner {
padding-bottom: 20px;
}
.d2-container-card-bs__body-card {
position: relative;
padding: 20px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
}
.d2-container-card-bs__footer {
padding: 20px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
}
}
}
}
}
}
}
-389
View File
@@ -1,389 +0,0 @@
// 每个主题特有的设置
.theme-#{$theme-name} {
.el-card {
&.d2-card {
border: $theme-container-border-outer;
.el-card__header {
border-bottom: $theme-container-border-outer;
}
}
}
// 背景图片和遮罩
.d2-layout-header-aside-group {
background-color: $theme-bg-color;
.d2-layout-header-aside-mask {
background: $theme-bg-mask;
}
}
// 菜单项目
@mixin theme-menu-hover-style {
color: $theme-menu-item-color-hover;
i.fa {
color: $theme-menu-item-color-hover;
}
background: $theme-menu-item-background-color-hover;
}
%el-menu-icon {
i.fa {
display: inline-block;
width: 15px;
text-align: center;
margin-right: 5px;
}
}
.el-submenu__title {
@extend %unable-select;
@extend %el-menu-icon;
}
.el-menu-item {
@extend %unable-select;
@extend %el-menu-icon;
}
.el-submenu__title:hover {
@include theme-menu-hover-style;
}
.el-menu-item:hover {
@include theme-menu-hover-style;
}
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
@include theme-menu-hover-style;
}
.el-menu--horizontal .el-menu .el-submenu__title:hover {
@include theme-menu-hover-style;
}
// 顶栏
.d2-theme-header {
// 切换按钮
.toggle-aside-btn {
i {
color: $theme-header-item-color;
background: $theme-header-item-background-color;
&:hover {
color: $theme-header-item-color-hover;
}
}
}
// 顶栏菜单
.el-menu {
.el-menu-item {
transition: border-top-color 0s;
color: $theme-header-item-color;
background: $theme-header-item-background-color;
i.fa { color: inherit; }
&:hover {
color: $theme-header-item-color-hover;
background: $theme-header-item-background-color-hover;
i.fa { color: inherit; }
}
&:focus {
color: $theme-header-item-color-focus;
background: $theme-header-item-background-color-focus;
i.fa { color: inherit; }
}
&.is-active {
color: $theme-header-item-color-active;
background: $theme-header-item-background-color-active;
i.fa { color: inherit; }
}
}
.el-submenu {
.el-submenu__title {
transition: border-top-color 0s;
color: $theme-header-item-color;
background: $theme-header-item-background-color;
i.fa { color: inherit; }
.el-submenu__icon-arrow {
color: $theme-header-item-color;
}
&:hover {
color: $theme-header-item-color-hover;
background: $theme-header-item-background-color-hover;
i.fa { color: inherit; }
.el-submenu__icon-arrow {
color: $theme-header-item-color-hover;
}
}
&:focus {
color: $theme-header-item-color-focus;
background: $theme-header-item-background-color-focus;
i.fa { color: inherit; }
.el-submenu__icon-arrow {
color: $theme-header-item-color-focus;
}
}
}
}
}
// 顶栏右侧
.d2-header-right {
.btn-text {
color: $theme-header-item-color;
&.can-hover {
&:hover {
color: $theme-header-item-color-hover;
background: $theme-header-item-background-color-hover;
}
}
}
}
}
// [布局] 顶栏下面
.d2-theme-container {
// 侧边栏
.d2-theme-container-aside {
// 菜单为空的时候显示的信息
.d2-layout-header-aside-menu-empty {
background: $theme-aside-menu-empty-background-color;
i {
color: $theme-aside-menu-empty-icon-color;
}
span {
color: $theme-aside-menu-empty-text-color;
}
&:hover {
background: $theme-aside-menu-empty-background-color-hover;
i {
color: $theme-aside-menu-empty-icon-color-hover;
}
span {
color: $theme-aside-menu-empty-text-color-hover;
}
}
}
// [菜单] 正常状态
.el-menu {
.el-menu-item {
color: $theme-aside-item-color;
background: $theme-aside-item-background-color;
i {
color: $theme-aside-item-color;
}
&:hover {
color: $theme-aside-item-color-hover;
background: $theme-aside-item-background-color-hover;
i {
color: $theme-aside-item-color-hover;
}
}
&:focus {
color: $theme-aside-item-color-focus;
background: $theme-aside-item-background-color-focus;
i {
color: $theme-aside-item-color-focus;
}
}
&.is-active {
color: $theme-aside-item-color-active;
background: $theme-aside-item-background-color-active;
i {
color: $theme-aside-item-color-active;
}
}
}
}
.el-submenu {
.el-submenu__title {
color: $theme-aside-item-color;
background: $theme-aside-item-background-color;
i {
color: $theme-aside-item-color;
}
.el-submenu__icon-arrow {
color: $theme-aside-item-color;
}
&:hover {
color: $theme-aside-item-color-hover;
background: $theme-aside-item-background-color-hover;
i {
color: $theme-aside-item-color-hover;
}
.el-submenu__icon-arrow {
color: $theme-aside-item-color-hover;
}
}
}
}
}
.d2-theme-container-main {
// 主体部分分为多页面控制器 和主体
.d2-theme-container-main-header {
// 多页面控制器
.d2-multiple-page-control {
.el-tabs__header.is-top {
border-bottom-color: $theme-multiple-page-control-border-color;
}
.el-tabs__nav {
border-color: $theme-multiple-page-control-border-color;
.el-tabs__item {
@extend %unable-select;
color: $theme-multiple-page-control-color;
background-color: $theme-multiple-page-control-background-color;
border-left-color: $theme-multiple-page-control-border-color;
&:first-child {
border-left: none;
&:hover {
padding: 0px 20px;
}
.el-icon-close {
display: none;
}
}
}
.el-tabs__item.is-active {
color: $theme-multiple-page-control-color-active;
background-color: $theme-multiple-page-control-background-color-active;
border-bottom-color: $theme-multiple-page-control-border-color-active;
}
}
%el-tabs__nav {
font-size: 20px;
}
.el-tabs__nav-prev {
@extend %el-tabs__nav;
color: $theme-multiple-page-control-nav-prev-color;
}
.el-tabs__nav-next {
@extend %el-tabs__nav;
color: $theme-multiple-page-control-nav-next-color;
}
}
// 多页控制器的关闭控制
.d2-multiple-page-control-btn {
.el-dropdown {
.el-button-group {
.el-button {
border-color: $theme-multiple-page-control-border-color;
}
}
}
}
}
// 主体
.d2-theme-container-main-body {
// 布局组件
.container-component {
// [组件]
// d2-container-full 填充型
.d2-container-full {
border: $theme-container-border-outer;
border-top: none;
border-bottom: none;
.d2-container-full__header {
border-bottom: $theme-container-border-inner;
background: $theme-container-header-footer-background-color;
}
.d2-container-full__body {
background: $theme-container-background-color;
}
.d2-container-full__footer {
border-top: $theme-container-border-inner;
background: $theme-container-header-footer-background-color;
}
}
// [组件]
// d2-container-full-bs 填充型 滚动优化
.d2-container-full-bs {
border: $theme-container-border-outer;
border-top: none;
border-bottom: none;
.d2-container-full-bs__header {
border-bottom: $theme-container-border-inner;
background: $theme-container-header-footer-background-color;
}
.d2-container-full-bs__body {
background: $theme-container-background-color;
}
.d2-container-full-bs__footer {
border-top: $theme-container-border-inner;
background: $theme-container-header-footer-background-color;
}
}
// [组件]
// d2-container-ghost 隐形布局组件
.d2-container-ghost {
.d2-container-ghost__header {
border-bottom: $theme-container-border-outer;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
.d2-container-ghost__footer {
border-top: $theme-container-border-outer;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
}
// [组件]
// d2-container-ghost-bs 隐形布局组件 滚动优化
.d2-container-ghost-bs {
.d2-container-ghost-bs__header {
border-bottom: $theme-container-border-outer;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
.d2-container-ghost-bs__footer {
border-top: $theme-container-border-outer;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
}
// [组件]
// d2-container-card 卡片型
.d2-container-card {
.d2-container-card__header {
border-bottom: $theme-container-border-inner;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
.d2-container-card__body {
.d2-container-card__body-card {
background: $theme-container-background-color;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
border-bottom: $theme-container-border-outer;
}
}
.d2-container-card__footer {
border-top: $theme-container-border-outer;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
}
// [组件]
// d2-container-card-bs 卡片型 滚动优化
.d2-container-card-bs {
.d2-container-card-bs__header {
border-bottom: $theme-container-border-inner;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
.d2-container-card-bs__body {
.d2-container-card-bs__body-card {
background: $theme-container-background-color;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
border-bottom: $theme-container-border-outer;
}
}
.d2-container-card-bs__footer {
border-top: $theme-container-border-outer;
border-left: $theme-container-border-outer;
border-right: $theme-container-border-outer;
background: $theme-container-header-footer-background-color;
}
}
}
}
}
}
}
@@ -1,2 +0,0 @@
@import './setting.scss';
@import '../theme.scss';
@@ -1,59 +0,0 @@
// 主题名称
$theme-name: 'tomorrow-night-blue';
// 主题背景颜色
$theme-bg-color: #002253;
// 主题背景图片遮罩
$theme-bg-mask: rgba(#000, 0);
// container组件
$theme-container-background-color: rgba(#FFF, 1);
$theme-container-header-footer-background-color: #FFF;
$theme-container-border-inner: 1px solid $color-border-1;
$theme-container-border-outer: 1px solid #002253;
$theme-multiple-page-control-color: #FFF;
$theme-multiple-page-control-color-active: $color-text-normal;
$theme-multiple-page-control-nav-prev-color: #FFF;
$theme-multiple-page-control-nav-next-color: #FFF;
$theme-multiple-page-control-border-color: #002253;
$theme-multiple-page-control-border-color-active: #FFF;
$theme-multiple-page-control-background-color: rgba(#FFF, .2);
$theme-multiple-page-control-background-color-active: #FFF;
// 顶栏和侧边栏中展开的菜单 hover 状态下
$theme-menu-item-color-hover: #293849;
$theme-menu-item-background-color-hover: #ecf5ff;
// 顶栏上的文字颜色
$theme-header-item-color: #FF929A;
$theme-header-item-background-color: transparent;
// 顶栏上的项目在 hover 时
$theme-header-item-color-hover: #FFEBA4;
$theme-header-item-background-color-hover: rgba(#FFF, .05);
// 顶栏上的项目在 focus 时
$theme-header-item-color-focus: #FFB870;
$theme-header-item-background-color-focus: rgba(#FFF, .05);
// 顶栏上的项目在 active 时
$theme-header-item-color-active: #FFB870;
$theme-header-item-background-color-active: rgba(#FFF, .05);
// 侧边栏上的文字颜色
$theme-aside-item-color: #FF929A;
$theme-aside-item-background-color: transparent;
// 侧边栏上的项目在 hover 时
$theme-aside-item-color-hover: #FFEBA4;
$theme-aside-item-background-color-hover: rgba(#FFF, .05);
// 侧边栏上的项目在 focus 时
$theme-aside-item-color-focus: #FFB870;
$theme-aside-item-background-color-focus: rgba(#FFF, .05);
// 侧边栏上的项目在 active 时
$theme-aside-item-color-active: #FFB870;
$theme-aside-item-background-color-active: rgba(#FFF, .05);
// 侧边栏菜单为空的时候显示的元素
$theme-aside-menu-empty-icon-color: #FFB870;
$theme-aside-menu-empty-text-color: #FFB870;
$theme-aside-menu-empty-background-color: rgba(#FFF, .1);
$theme-aside-menu-empty-icon-color-hover: #FFEBA4;
$theme-aside-menu-empty-text-color-hover: #FFEBA4;
$theme-aside-menu-empty-background-color-hover: rgba(#FFF, .2);
-9
View File
@@ -1,9 +0,0 @@
@import './setting.scss';
@import '../theme.scss';
.theme-#{$theme-name} {
.d2-layout-header-aside-group {
background: #bc00e3;
background: linear-gradient(120deg, #bc00e3 0%, #4EFFFB 100%);
}
}
@@ -1,59 +0,0 @@
// 主题名称
$theme-name: 'violet';
// 主题背景颜色
$theme-bg-color: #000;
// 主题背景图片遮罩
$theme-bg-mask: rgba(#000, 0);
// container组件
$theme-container-background-color: #FFF;
$theme-container-header-footer-background-color: #FFF;
$theme-container-border-inner: 1px solid $color-border-2;
$theme-container-border-outer: 1px solid #8C40E2;
$theme-multiple-page-control-color: #FFF;
$theme-multiple-page-control-color-active: $color-text-normal;
$theme-multiple-page-control-nav-prev-color: #FFF;
$theme-multiple-page-control-nav-next-color: #FFF;
$theme-multiple-page-control-border-color: #8C40E2;
$theme-multiple-page-control-border-color-active: #FFF;
$theme-multiple-page-control-background-color: rgba(#FFF, .3);
$theme-multiple-page-control-background-color-active: #FFF;
// 顶栏和侧边栏中展开的菜单 hover 状态下
$theme-menu-item-color-hover: #293849;
$theme-menu-item-background-color-hover: #ecf5ff;
// 顶栏上的文字颜色
$theme-header-item-color: #FFF;
$theme-header-item-background-color: transparent;
// 顶栏上的项目在 hover 时
$theme-header-item-color-hover: #FFF;
$theme-header-item-background-color-hover: linear-gradient(-180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.12) 100%);
// 顶栏上的项目在 focus 时
$theme-header-item-color-focus: #FFF;
$theme-header-item-background-color-focus: linear-gradient(-180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.12) 100%);
// 顶栏上的项目在 active 时
$theme-header-item-color-active: #FFF;
$theme-header-item-background-color-active: linear-gradient(-180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.12) 100%);
// 侧边栏上的文字颜色
$theme-aside-item-color: #FFF;
$theme-aside-item-background-color: transparent;
// 侧边栏上的项目在 hover 时
$theme-aside-item-color-hover: #FFF;
$theme-aside-item-background-color-hover: linear-gradient(90deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.00) 100%);
// 侧边栏上的项目在 focus 时
$theme-aside-item-color-focus: #FFF;
$theme-aside-item-background-color-focus: linear-gradient(90deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.00) 100%);
// 侧边栏上的项目在 active 时
$theme-aside-item-color-active: #FFF;
$theme-aside-item-background-color-active: linear-gradient(90deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.00) 100%);
// 侧边栏菜单为空的时候显示的元素
$theme-aside-menu-empty-icon-color: #FFF;
$theme-aside-menu-empty-text-color: #FFF;
$theme-aside-menu-empty-background-color: rgba(#000, .1);
$theme-aside-menu-empty-icon-color-hover: #FFF;
$theme-aside-menu-empty-text-color-hover: #FFF;
$theme-aside-menu-empty-background-color-hover: rgba(#000, .15);
-23
View File
@@ -1,23 +0,0 @@
// 主色
$color-primary: #409EFF;
// 辅助色
$color-info: #909399;
$color-success: #67C23A;
$color-warning: #E6A23C;
$color-danger: #F56C6C;
// 文字
$color-text-main: #303133;
$color-text-normal: #606266;
$color-text-sub: #909399;
$color-text-placehoder: #C0C4CC;
// 边框
$color-border-1: #DCDFE6;
$color-border-2: #E4E7ED;
$color-border-3: #EBEEF5;
$color-border-4: #F2F6FC;
// 背景
$color-bg: #f8f8f9;
-13
View File
@@ -1,13 +0,0 @@
<svg width="60px" height="54px" viewBox="0 0 60 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>D2Admin</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="logo-no-shadow" transform="translate(-3.000000, -3.000000)">
<path d="M44.2833805,33.4299717 L6.05798302,56.3652102 C4.16366196,57.5018028 1.70662094,56.8875426 0.570028297,54.9932215 C0.197031333,54.3715599 8.87839274e-17,53.6602143 0,52.9352385 L-4.4408921e-16,7.06476152 C-7.1463071e-16,4.85562252 1.790861,3.06476152 4,3.06476152 C4.72497578,3.06476152 5.43632142,3.26179285 6.05798302,3.63478981 L44.2833805,26.5700283 C46.1777016,27.7066209 46.7919618,30.163662 45.6553692,32.057983 C45.3175701,32.6209814 44.8463789,33.0921727 44.2833805,33.4299717 Z" id="Triangle-Copy" fill="#35495E" transform="translate(25.000000, 30.000000) rotate(-180.000000) translate(-25.000000, -30.000000) "></path>
<path d="M60.2833805,33.4299717 L22.057983,56.3652102 C20.163662,57.5018028 17.7066209,56.8875426 16.5700283,54.9932215 C16.1970313,54.3715599 16,53.6602143 16,52.9352385 L16,7.06476152 C16,4.85562252 17.790861,3.06476152 20,3.06476152 C20.7249758,3.06476152 21.4363214,3.26179285 22.057983,3.63478981 L60.2833805,26.5700283 C62.1777016,27.7066209 62.7919618,30.163662 61.6553692,32.057983 C61.3175701,32.6209814 60.8463789,33.0921727 60.2833805,33.4299717 Z" id="Triangle" fill="#409EFF"></path>
<path d="M42.4688663,31.7973091 L24.0289915,42.8612339 C23.081831,43.4295303 21.8533105,43.1224001 21.2850141,42.1752396 C21.0985157,41.8644088 21,41.508736 21,41.1462481 L21,19.0183984 C21,17.9138289 21.8954305,17.0183984 23,17.0183984 C23.3624879,17.0183984 23.7181607,17.116914 24.0289915,17.3034125 L42.4688663,28.3673374 C43.4160268,28.9356337 43.7231569,30.1641542 43.1548606,31.1113147 C42.9859611,31.3928139 42.7503655,31.6284096 42.4688663,31.7973091 Z" id="Triangle-Copy" fill="#FFFFFF" transform="translate(31.000000, 30.082670) rotate(-180.000000) translate(-31.000000, -30.082670) "></path>
<path d="M37.5708451,30.8574929 L30.5144958,35.0913025 C30.0409155,35.3754507 29.4266552,35.2218856 29.1425071,34.7483054 C29.0492578,34.59289 29,34.4150536 29,34.2338096 L29,25.7661904 C29,25.2139056 29.4477153,24.7661904 30,24.7661904 C30.1812439,24.7661904 30.3590804,24.8154482 30.5144958,24.9086975 L37.5708451,29.1425071 C38.0444254,29.4266552 38.1979905,30.0409155 37.9138423,30.5144958 C37.8293925,30.6552454 37.7115947,30.7730432 37.5708451,30.8574929 Z" id="Triangle" fill="#409EFF"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

-7
View File
@@ -1,7 +0,0 @@
import Vue from 'vue'
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./icons', false, /\.svg$/)
const iconMap = requireAll(req)
Vue.prototype.$IconSvg = iconMap.map(e => e.default.id.slice(3))
@@ -1,27 +0,0 @@
<template>
<div class="d2-container-card-bs">
<div v-if="$slots.header" class="d2-container-card-bs__header" ref="header">
<slot name="header"/>
</div>
<div class="d2-container-card-bs__body" ref="wrapper">
<div class="d2-container-card-bs__body-wrapper-inner">
<div class="d2-container-card-bs__body-card">
<slot/>
</div>
</div>
</div>
<div v-if="$slots.footer" class="d2-container-card-bs__footer" ref="footer">
<slot name="footer"/>
</div>
</div>
</template>
<script>
import bs from './mixins/bs'
export default {
name: 'd2-container-card-bs',
mixins: [
bs
]
}
</script>
@@ -1,21 +0,0 @@
<template>
<div class="d2-container-card">
<div v-if="$slots.header" class="d2-container-card__header" ref="header">
<slot name="header"/>
</div>
<div class="d2-container-card__body">
<div class="d2-container-card__body-card">
<slot/>
</div>
</div>
<div v-if="$slots.footer" class="d2-container-card__footer" ref="footer">
<slot name="footer"/>
</div>
</div>
</template>
<script>
export default {
name: 'd2-container-card'
}
</script>
@@ -1,25 +0,0 @@
<template>
<div class="d2-container-full-bs">
<div v-if="$slots.header" class="d2-container-full-bs__header" ref="header">
<slot name="header"/>
</div>
<div class="d2-container-full-bs__body" ref="wrapper">
<div class="d2-container-full-bs__body-wrapper-inner">
<slot/>
</div>
</div>
<div v-if="$slots.footer" class="d2-container-full-bs__footer" ref="footer">
<slot name="footer"/>
</div>
</div>
</template>
<script>
import bs from './mixins/bs'
export default {
name: 'd2-container-card-bs',
mixins: [
bs
]
}
</script>
@@ -1,19 +0,0 @@
<template>
<div class="d2-container-full">
<div v-if="$slots.header" class="d2-container-full__header" ref="header">
<slot name="header"/>
</div>
<div class="d2-container-full__body">
<slot/>
</div>
<div v-if="$slots.footer" class="d2-container-full__footer" ref="footer">
<slot name="footer"/>
</div>
</div>
</template>
<script>
export default {
name: 'd2-container-full'
}
</script>
@@ -1,23 +0,0 @@
<template>
<div class="d2-container-ghost-bs">
<div v-if="$slots.header" class="d2-container-ghost-bs__header" ref="header">
<slot name="header"/>
</div>
<div class="d2-container-ghost-bs__body" ref="wrapper">
<slot/>
</div>
<div v-if="$slots.footer" class="d2-container-ghost-bs__footer" ref="footer">
<slot name="footer"/>
</div>
</div>
</template>
<script>
import bs from './mixins/bs'
export default {
name: 'd2-container-card-bs',
mixins: [
bs
]
}
</script>
@@ -1,13 +0,0 @@
<template>
<div class="d2-container-ghost">
<div v-if="$slots.header" class="d2-container-ghost__header" ref="header">
<slot name="header"/>
</div>
<div class="d2-container-ghost__body">
<slot/>
</div>
<div v-if="$slots.footer" class="d2-container-ghost__footer" ref="footer">
<slot name="footer"/>
</div>
</div>
</template>
@@ -1,37 +0,0 @@
import BScroll from 'better-scroll'
export default {
props: {
betterScrollOptions: {
type: Object,
required: false,
default: () => ({})
}
},
data () {
return {
BS: null
}
},
mounted () {
this.scrollInit()
},
beforeDestroy () {
this.scrollDestroy()
},
methods: {
scrollInit () {
this.BS = new BScroll(this.$refs.wrapper, Object.assign({
mouseWheel: true,
scrollbar: {
fade: true,
interactive: false
}
}, this.betterScrollOptions))
},
scrollDestroy () {
if (this.BS) {
this.BS.destroy()
}
}
}
}
-75
View File
@@ -1,75 +0,0 @@
<template>
<div class="container-component" ref="container">
<!-- [card] 卡片容器 -->
<d2-container-card v-if="type === 'card' && !betterScroll">
<slot v-if="$slots.header" name="header" slot="header"/>
<slot/>
<slot v-if="$slots.footer" name="footer" slot="footer"/>
</d2-container-card>
<!-- [card] 卡片容器 滚动优化 -->
<d2-container-card-bs v-bind="$attrs" v-if="type === 'card' && betterScroll">
<slot v-if="$slots.header" name="header" slot="header"/>
<slot/>
<slot v-if="$slots.footer" name="footer" slot="footer"/>
</d2-container-card-bs>
<!-- [ghost] 隐形容器 -->
<d2-container-ghost v-if="type === 'ghost' && !betterScroll">
<slot v-if="$slots.header" name="header" slot="header"/>
<slot/>
<slot v-if="$slots.footer" name="footer" slot="footer"/>
</d2-container-ghost>
<!-- [ghost] 隐形容器 滚动优化 -->
<d2-container-ghost-bs v-bind="$attrs" v-if="type === 'ghost' && betterScroll">
<slot v-if="$slots.header" name="header" slot="header"/>
<slot/>
<slot v-if="$slots.footer" name="footer" slot="footer"/>
</d2-container-ghost-bs>
<!-- [container-full] 填充 -->
<d2-container-full v-if="type === 'full' && !betterScroll">
<slot v-if="$slots.header" name="header" slot="header"/>
<slot/>
<slot v-if="$slots.footer" name="footer" slot="footer"/>
</d2-container-full>
<!-- [container-full-bs] 填充 滚动优化 -->
<d2-container-full-bs v-bind="$attrs" v-if="type === 'full' && betterScroll">
<slot v-if="$slots.header" name="header" slot="header"/>
<slot/>
<slot v-if="$slots.footer" name="footer" slot="footer"/>
</d2-container-full-bs>
</div>
</template>
<script>
// 组件
import d2ContainerFull from './components/d2-container-full.vue'
import d2ContainerFullBs from './components/d2-container-full-bs.vue'
import d2ContainerGhost from './components/d2-container-ghost.vue'
import d2ContainerGhostBs from './components/d2-container-ghost-bs.vue'
import d2ContainerCard from './components/d2-container-card.vue'
import d2ContainerCardBs from './components/d2-container-card-bs.vue'
export default {
name: 'd2-container',
components: {
'd2-container-full': d2ContainerFull,
'd2-container-full-bs': d2ContainerFullBs,
'd2-container-ghost': d2ContainerGhost,
'd2-container-ghost-bs': d2ContainerGhostBs,
'd2-container-card': d2ContainerCard,
'd2-container-card-bs': d2ContainerCardBs
},
props: {
// 容器样式
type: {
type: String,
required: false,
default: 'full'
},
// 滚动优化
betterScroll: {
type: Boolean,
required: false,
default: false
}
}
}
</script>
-22
View File
@@ -1,22 +0,0 @@
<template>
<svg aria-hidden="true">
<use :xlink:href="icon"></use>
</svg>
</template>
<script>
export default {
name: 'd2-icon-svg',
props: {
name: {
type: String,
required: true
}
},
computed: {
icon () {
return `#d2-${this.name}`
}
}
}
</script>
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 434 KiB

-17
View File
@@ -1,17 +0,0 @@
<template>
<i class="fa" :class="`fa-${name}`" aria-hidden="true"></i>
</template>
<script>
import './font-awesome-4.7.0/css/font-awesome.min.css'
export default {
name: 'd2-icon',
props: {
name: {
type: String,
required: false,
default: 'font-awesome'
}
}
}
</script>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

-63
View File
@@ -1,63 +0,0 @@
<template>
<div class="page-cover">
<div class="page-cover__logo">
<slot/>
</div>
<p class="page-cover__title">{{title}}</p>
<p class="page-cover__sub-title d2-mt-0">{{subTitle}}</p>
<slot name="footer"/>
<a target="blank" href="https://github.com/d2-projects/d2-admin">
<img
style="position: absolute; top: 0; right: 0; border: 0; width: 150px;"
src="./image/darkblue@2x.png"
alt="Fork me on GitHub">
</a>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
required: false,
default: 'Title'
},
subTitle: {
type: String,
required: false,
default: 'subTitle'
}
}
}
</script>
<style lang="scss" scoped>
@import '~@/assets/style/public.scss';
.page-index-article-header {
overflow: hidden;
.page-index-article-header__title {
display: inline-block;
padding: 12px 20px;
}
}
.page-cover {
@extend %full;
@extend %unable-select;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
.page-cover__logo {
img {
width: 200px;
}
}
.page-cover__title {
color: $color-text-main;
}
.page-cover__sub-title {
color: $color-text-sub;
}
}
</style>
-10
View File
@@ -1,10 +0,0 @@
import Vue from 'vue'
import d2Container from './d2-container'
// 注意 有些组件使用异步加载会有影响
Vue.component('d2-container', d2Container)
Vue.component('d2-page-cover', () => import('./d2-page-cover'))
Vue.component('d2-icon', () => import('./d2-icon'))
Vue.component('d2-icon-svg', () => import('./d2-icon-svg/index.vue'))
@@ -1,25 +0,0 @@
<template>
<el-menu-item :index="menu.path || uniqueid">
<i :class="`fa fa-${menu.icon || 'file-o'}`"></i>
<span slot="title">{{menu.title || '未命名菜单'}}</span>
</el-menu-item>
</template>
<script>
import uniqueid from 'lodash.uniqueid'
export default {
name: 'd2-layout-header-aside-menu-item',
props: {
menu: {
type: Object,
required: false,
default: () => {}
}
},
data () {
return {
uniqueid: uniqueid('d2-menu-empty-')
}
}
}
</script>
@@ -1,37 +0,0 @@
<template>
<el-submenu :index="menu.path || uniqueid">
<template slot="title">
<i :class="`fa fa-${menu.icon || 'folder-o'}`"></i>
<span slot="title">{{menu.title}}</span>
</template>
<template v-for="(child, childIndex) in menu.children">
<d2-layout-header-aside-menu-item v-if="child.children === undefined" :menu="child" :key="childIndex"/>
<d2-layout-header-aside-menu-sub v-else :menu="child" :key="childIndex"/>
</template>
</el-submenu>
</template>
<script>
import uniqueid from 'lodash.uniqueid'
// 组件
import d2LayoutMainMenuItem from '../menu-item'
export default {
name: 'd2-layout-header-aside-menu-sub',
components: {
'd2-layout-header-aside-menu-item': d2LayoutMainMenuItem
},
props: {
menu: {
type: Object,
required: false,
default: () => {}
}
},
data () {
return {
uniqueid: uniqueid('d2-menu-empty-')
}
}
}
</script>
@@ -1,61 +0,0 @@
<template>
<div
class="d2-contentmenu-list"
@click="rowClick">
<div
v-for="item in menulist"
:key="item.value"
:data-value="item.value"
class="d2-contentmenu-item"
flex="cross:center main:center">
<d2-icon
v-if="item.icon"
:name="item.icon"/>
<div
class="d2-contentmenu-item-title"
flex-box="1">
{{item.title}}
</div>
</div>
</div>
</template>
<script>
export default {
name: 'd2-contextmenu-list',
props: {
menulist: {
type: Array,
default: () => []
}
},
methods: {
rowClick (event) {
let target = event.target
while (!target.dataset.value) {
target = target.parentNode
}
this.$emit('rowClick', target.dataset.value)
}
}
}
</script>
<style lang="scss">
.d2-contentmenu-list {
.d2-contentmenu-item {
padding: 8px 20px 8px 15px;
margin: 0;
font-size: 14px;
color: #606266;
cursor: pointer;
&:hover {
background: #ecf5ff;
color: #66b1ff;
}
.d2-contentmenu-item-title {
margin-left: 10px;
}
}
}
</style>
@@ -1,71 +0,0 @@
<template>
<div
class="d2-contextmenu"
v-show="flag"
:style="style">
<slot/>
</div>
</template>
<script>
export default {
name: 'd2-contextmenu',
props: {
visible: {
type: Boolean,
default: false
},
x: {
type: Number,
default: 0
},
y: {
type: Number,
default: 0
}
},
computed: {
flag: {
get () {
if (this.visible) {
// 注册全局监听事件 [ 目前只考虑鼠标解除触发 ]
window.addEventListener('mousedown', this.watchContextmenu)
}
return this.visible
},
set (newVal) {
this.$emit('update:visible', newVal)
}
},
style () {
return {
left: this.x + 'px',
top: this.y + 'px',
display: this.visible ? 'block' : 'none '
}
}
},
methods: {
watchContextmenu (event) {
if (!this.$el.contains(event.target) || event.button !== 0) this.flag = false
window.removeEventListener('mousedown', this.watchContextmenu)
}
},
mounted () {
// 将菜单放置到body下
document.querySelector('body').appendChild(this.$el)
}
}
</script>
<style>
.d2-contextmenu {
position: absolute;
padding: 5px 0;
z-index: 2018;
background: #FFF;
border: 1px solid #cfd7e5;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
}
</style>
@@ -1,27 +0,0 @@
<template>
<el-tooltip
effect="dark"
:content="isFullScreen ? '退出全屏' : '全屏'"
placement="bottom">
<el-button class="d2-mr btn-text can-hover" type="text" @click="d2adminFullScreenToggle">
<d2-icon v-if="isFullScreen" name="compress"/>
<d2-icon v-else name="arrows-alt" style="font-size: 16px"/>
</el-button>
</el-tooltip>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState({
isFullScreen: state => state.d2admin.isFullScreen
})
},
methods: {
...mapMutations([
'd2adminFullScreenToggle'
])
}
}
</script>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

@@ -1,51 +0,0 @@
<template>
<div>
<el-tooltip effect="dark" content="疑问" placement="bottom">
<el-button class="d2-ml-0 d2-mr btn-text can-hover" type="text" @click="dialogVisible = true">
<d2-icon name="question-circle" style="font-size: 20px"/>
</el-button>
</el-tooltip>
<el-dialog title="帮助" width="600px" :visible.sync="dialogVisible">
<div style="margin-top: -25px; margin-bottom: -25px;">
<el-button-group class="d2-mb">
<el-button @click="$open('https://github.com/d2-projects/d2-admin')">
<d2-icon name="github" class="d2-mr-5"/>
主页
</el-button>
<el-button @click="$open('http://d2admin.fairyever.com/zh/')">
<d2-icon name="book" class="d2-mr-5"/>
中文文档
</el-button>
<el-button @click="$open('https://github.com/d2-projects/d2-admin/issues')">
<d2-icon name="question" class="d2-mr-5"/>
issues
</el-button>
<el-button @click="$open('https://github.com/d2-projects/d2-admin/issues/new')">
<d2-icon name="plus" class="d2-mr-5"/>
new issues
</el-button>
</el-button-group>
<el-row :gutter="20">
<el-col :span="12">
<el-alert :closable="false" type="info" title="扫码进 QQ 群" class="d2-mb"/>
<img src="./image/qq.jpg" style="width: 100%;">
</el-col>
<el-col :span="12">
<el-alert :closable="false" type="info" title="作者微信 加好友拉进微信群" class="d2-mb"/>
<img src="./image/we.jpg" style="width: 100%;">
</el-col>
</el-row>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data () {
return {
dialogVisible: false
}
}
}
</script>
@@ -1,58 +0,0 @@
<template>
<el-table :data="themeList" v-bind="table">
<el-table-column prop="title" align="center" width="160"/>
<el-table-column label="预览" width="120">
<div
slot-scope="scope"
class="theme-preview"
:style="{'backgroundImage': `url(${$baseUrl}${scope.row.preview})`}">
</div>
</el-table-column>
<el-table-column prop="address" align="center">
<template slot-scope="scope">
<el-button v-if="themeActiveName === scope.row.name" type="success" icon="el-icon-check" round>已激活</el-button>
<el-button v-else round @click="handleSelectTheme(scope.row.name)">使用</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'd2-theme-list',
data () {
return {
table: {
showHeader: false,
border: true
}
}
},
computed: {
...mapState({
themeList: state => state.d2admin.themeList,
themeActiveName: state => state.d2admin.themeActiveName
})
},
methods: {
...mapMutations([
'd2adminThemeSet'
]),
handleSelectTheme (name) {
this.d2adminThemeSet(name)
}
}
}
</script>
<style lang="scss" scoped>
@import '~@/assets/style/public.scss';
.theme-preview {
height: 50px;
width: 100px;
border-radius: 4px;
background-size: cover;
border: 1px solid $color-border-1;
}
</style>
@@ -1,26 +0,0 @@
<template>
<div>
<el-tooltip effect="dark" content="主题" placement="bottom">
<el-button class="d2-ml-0 d2-mr btn-text can-hover" type="text" @click="dialogVisible = true">
<d2-icon name="diamond" style="font-size: 16px"/>
</el-button>
</el-tooltip>
<el-dialog title="主题" width="600px" :visible.sync="dialogVisible">
<d2-theme-list style="margin-top: -25px;"/>
</el-dialog>
</div>
</template>
<script>
import themeList from './components/d2-theme-list'
export default {
components: {
'd2-theme-list': themeList
},
data () {
return {
dialogVisible: false
}
}
}
</script>
@@ -1,36 +0,0 @@
<template>
<el-dropdown class="d2-mr">
<span class="btn-text">你好 {{userInfo.name}}</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="logOff">
<d2-icon name="power-off" class="d2-mr-5"/>
注销
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState({
userInfo: state => state.d2admin.userInfo
})
},
methods: {
...mapActions([
'd2adminLogout'
]),
/**
* @description 登出
*/
logOff () {
this.d2adminLogout({
vm: this,
confirm: true
})
}
}
}
</script>
@@ -1,30 +0,0 @@
<template>
<el-menu mode="horizontal" @select="handleMenuSelect">
<template v-for="(menu, menuIndex) in menuHeader">
<d2-layout-header-aside-menu-item v-if="menu.children === undefined" :menu="menu" :key="menuIndex"/>
<d2-layout-header-aside-menu-sub v-else :menu="menu" :key="menuIndex"/>
</template>
</el-menu>
</template>
<script>
import { mapState } from 'vuex'
import menuMixin from '../mixin/menu'
import d2LayoutMainMenuItem from '../components/menu-item/index.vue'
import d2LayoutMainMenuSub from '../components/menu-sub/index.vue'
export default {
name: 'd2-layout-header-aside-menu-header',
mixins: [
menuMixin
],
components: {
'd2-layout-header-aside-menu-item': d2LayoutMainMenuItem,
'd2-layout-header-aside-menu-sub': d2LayoutMainMenuSub
},
computed: {
...mapState({
menuHeader: state => state.d2admin.menuHeader
})
}
}
</script>
@@ -1,94 +0,0 @@
<template>
<div class="d2-layout-header-aside-menu-side">
<el-menu
:collapse="isMenuAsideCollapse"
:unique-opened="true"
:default-active="active"
ref="menu"
@select="handleMenuSelect">
<template v-for="(menu, menuIndex) in menuAside">
<d2-layout-header-aside-menu-item v-if="menu.children === undefined" :menu="menu" :key="menuIndex"/>
<d2-layout-header-aside-menu-sub v-else :menu="menu" :key="menuIndex"/>
</template>
</el-menu>
<div v-if="menuAside.length === 0 && !isMenuAsideCollapse" class="d2-layout-header-aside-menu-empty" flex="dir:top main:center cross:center">
<d2-icon name="inbox"/>
<span>没有侧栏菜单</span>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import menuMixin from '../mixin/menu'
import d2LayoutMainMenuItem from '../components/menu-item/index.vue'
import d2LayoutMainMenuSub from '../components/menu-sub/index.vue'
import BScroll from 'better-scroll'
export default {
name: 'd2-layout-header-aside-menu-side',
mixins: [
menuMixin
],
components: {
'd2-layout-header-aside-menu-item': d2LayoutMainMenuItem,
'd2-layout-header-aside-menu-sub': d2LayoutMainMenuSub
},
data () {
return {
active: '',
asideHeight: 300,
BS: null
}
},
computed: {
...mapState({
menuAside: state => state.d2admin.menuAside,
isMenuAsideCollapse: state => state.d2admin.isMenuAsideCollapse
})
},
watch: {
// 折叠和展开菜单的时候销毁 better scroll
isMenuAsideCollapse (val) {
this.scrollDestroy()
setTimeout(() => {
this.scrollInit()
}, 500)
},
// 监听路由 控制侧边栏激活状态
'$route.matched': {
handler (val) {
this.active = val[val.length - 1].path
this.$nextTick(() => {
if (this.menuAside.length > 0) {
this.$refs.menu.activeIndex = this.active
}
})
},
immediate: true
}
},
mounted () {
this.scrollInit()
},
beforeDestroy () {
this.scrollDestroy()
},
methods: {
scrollInit () {
this.BS = new BScroll(this.$el, {
mouseWheel: true
// 如果你愿意可以打开显示滚动条
// scrollbar: {
// fade: true,
// interactive: false
// }
})
},
scrollDestroy () {
if (this.BS) {
this.BS.destroy()
}
}
}
}
</script>
@@ -1,13 +0,0 @@
export default {
methods: {
handleMenuSelect (index, indexPath) {
if (/^d2-menu-empty-\d+$/.test(index)) {
this.$message.warning('临时菜单')
} else {
this.$router.push({
path: index
})
}
}
}
}
@@ -1,185 +0,0 @@
<template>
<div class="d2-multiple-page-control-group" flex>
<div class="d2-multiple-page-control-content" flex-box="1">
<div class="d2-multiple-page-control-content-inner">
<d2-contextmenu
:visible.sync="contextmenuFlag"
:x="contentmenuX"
:y="contentmenuY">
<d2-contextmenu-list
:menulist="tagName === 'index' ? contextmenuListIndex : contextmenuList"
@rowClick="contextmenuClick"/>
</d2-contextmenu>
<el-tabs
class="d2-multiple-page-control"
:value="pageCurrent"
type="card"
:closable="true"
@tab-click="handleClick"
@edit="handleTabsEdit"
@contextmenu.native="handleContextmenu">
<el-tab-pane
v-for="(page, index) in pageOpenedList"
:key="index"
:label="page.meta.title || '未命名'"
:name="page.name"/>
</el-tabs>
</div>
</div>
<div
class="d2-multiple-page-control-btn"
flex-box="0">
<el-dropdown
split-button
@click="handleControlBtnClick"
@command="command => handleControlItemClick(command)">
<d2-icon name="times-circle"/>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="left">
<d2-icon name="arrow-left" class="d2-mr-10"/>
关闭左侧
</el-dropdown-item>
<el-dropdown-item command="right">
<d2-icon name="arrow-right" class="d2-mr-10"/>
关闭右侧
</el-dropdown-item>
<el-dropdown-item command="other">
<d2-icon name="times" class="d2-mr-10"/>
关闭其它
</el-dropdown-item>
<el-dropdown-item command="all">
<d2-icon name="times-circle" class="d2-mr-10"/>
全部关闭
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
components: {
D2Contextmenu: () => import('../contextmenu'),
D2ContextmenuList: () => import('../contextmenu/components/contentmenuList')
},
data () {
return {
contextmenuFlag: false,
contentmenuX: 0,
contentmenuY: 0,
contextmenuListIndex: [
{ icon: 'times-circle', title: '关闭全部', value: 'all' }
],
contextmenuList: [
{ icon: 'arrow-left', title: '关闭左侧', value: 'left' },
{ icon: 'arrow-right', title: '关闭右侧', value: 'right' },
{ icon: 'times', title: '关闭其它', value: 'other' },
{ icon: 'times-circle', title: '关闭全部', value: 'all' }
],
tagName: 'index'
}
},
computed: {
...mapState({
pageOpenedList: state => state.d2admin.pageOpenedList,
pageCurrent: state => state.d2admin.pageCurrent
})
},
methods: {
...mapMutations([
'd2adminTagCloseLeft',
'd2adminTagCloseRight',
'd2adminTagCloseOther',
'd2adminTagCloseAll'
]),
/**
* @description 右键菜单功能点击
*/
handleContextmenu (event) {
let target = event.target
// 解决 https://github.com/d2-projects/d2-admin/issues/54
let flag = false
if (target.className.indexOf('el-tabs__item') > -1) flag = true
else if (target.parentNode.className.indexOf('el-tabs__item') > -1) {
target = target.parentNode
flag = true
}
if (flag) {
event.preventDefault()
event.stopPropagation()
this.contentmenuX = event.clientX
this.contentmenuY = event.clientY
this.tagName = target.getAttribute('aria-controls').slice(5)
this.contextmenuFlag = true
}
},
/**
* @description 右键菜单的row-click事件
*/
contextmenuClick (command) {
this.handleControlItemClick(command, this.tagName)
},
/**
* @description 接收点击关闭控制上选项的事件
*/
handleControlItemClick (command, tagName = null) {
if (tagName) {
this.contextmenuFlag = false
}
const params = {
pageSelect: tagName,
vm: this
}
switch (command) {
case 'left':
this.d2adminTagCloseLeft(params)
break
case 'right':
this.d2adminTagCloseRight(params)
break
case 'other':
this.d2adminTagCloseOther(params)
break
case 'all':
this.d2adminTagCloseAll(this)
break
default:
this.$message.error('无效的操作')
break
}
},
/**
* @description 接收点击关闭控制上按钮的事件
*/
handleControlBtnClick () {
this.d2adminTagCloseAll(this)
},
/**
* @description 接收点击 tab 标签的事件
*/
handleClick (tab, event) {
// 找到点击的页面在 tag 列表里是哪个
const page = this.pageOpenedList.find(page => page.name === tab.name)
const { name, params, query } = page
if (page) {
this.$router.push({ name, params, query })
}
},
/**
* @description 点击 tab 上的删除按钮触发这里 首页的删除按钮已经隐藏 因此这里不用判断是 index
*/
handleTabsEdit (tagName, action) {
if (action === 'remove') {
this.$store.commit('d2adminTagClose', {
tagName,
vm: this
})
}
}
}
}
</script>
-3
View File
@@ -1,3 +0,0 @@
import layout from './layout'
export default layout
-122
View File
@@ -1,122 +0,0 @@
<template>
<div
class="d2-layout-header-aside-group"
:style="styleLayoutMainGroup"
:class="{grayMode: isGrayMode}">
<!-- 半透明遮罩 -->
<div class="d2-layout-header-aside-mask"></div>
<!-- 主体内容 -->
<div class="d2-layout-header-aside-content" flex="dir:top">
<!-- 顶栏 -->
<div class="d2-theme-header" flex-box="0">
<div class="logo-group" :style="{width: isMenuAsideCollapse ? asideWidthCollapse : asideWidth}">
<img v-if="isMenuAsideCollapse" :src="`${$baseUrl}image/theme/${d2adminThemeActiveSetting.name}/logo/icon-only.png`">
<img v-else :src="`${$baseUrl}image/theme/${d2adminThemeActiveSetting.name}/logo/all.png`">
</div>
<div class="toggle-aside-btn" @click="handleToggleAside">
<d2-icon name="bars"/>
</div>
<d2-menu-header/>
<!-- 顶栏右侧 -->
<div class="d2-header-right">
<d2-header-help/>
<d2-header-fullscreen/>
<d2-header-theme/>
<d2-header-user/>
</div>
</div>
<!-- 下面 主体 -->
<div class="d2-theme-container" flex-box="1" flex>
<!-- 主体 侧边栏 -->
<div
flex-box="0"
ref="aside"
class="d2-theme-container-aside"
:style="{width: isMenuAsideCollapse ? asideWidthCollapse : asideWidth}">
<d2-menu-side/>
</div>
<!-- 主体 -->
<div class="d2-theme-container-main" flex-box="1" flex="dir:top">
<div class="d2-theme-container-main-header" flex-box="0">
<d2-tabs/>
</div>
<div class="d2-theme-container-main-body" flex-box="1">
<transition name="fade-transverse">
<keep-alive :include="d2adminKeepAliveInclude">
<router-view/>
</keep-alive>
</transition>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
import menuSide from './components/menu-side'
import menuHeader from './components/menu-header'
import tabs from './components/tabs'
import headerFullscreen from './components/header-fullscreen'
import headerTheme from './components/header-theme'
import headerUser from './components/header-user'
import headerHelp from './components/header-help'
export default {
name: 'd2-layout-header-aside',
components: {
'd2-menu-side': menuSide,
'd2-menu-header': menuHeader,
'd2-tabs': tabs,
'd2-header-fullscreen': headerFullscreen,
'd2-header-theme': headerTheme,
'd2-header-user': headerUser,
'd2-header-help': headerHelp
},
data () {
return {
// [侧边栏宽度] 正常状态
asideWidth: '200px',
// [侧边栏宽度] 折叠状态
asideWidthCollapse: '65px'
}
},
computed: {
...mapState({
isGrayMode: state => state.d2admin.isGrayMode,
pageOpenedList: state => state.d2admin.pageOpenedList,
isMenuAsideCollapse: state => state.d2admin.isMenuAsideCollapse
}),
...mapGetters([
'd2adminThemeActiveSetting',
'd2adminKeepAliveInclude'
]),
/**
* @description 最外层容器的背景图片样式
*/
styleLayoutMainGroup () {
return {
...this.d2adminThemeActiveSetting.backgroundImage ? {
backgroundImage: `url('${this.$baseUrl}${this.d2adminThemeActiveSetting.backgroundImage}')`
} : {}
}
}
},
methods: {
...mapMutations([
'd2adminMenuAsideCollapseToggle'
]),
/**
* 接收点击切换侧边栏的按钮
*/
handleToggleAside () {
this.d2adminMenuAsideCollapseToggle()
}
}
}
</script>
<style lang="scss">
// 注册主题
@import '~@/assets/style/theme/register.scss';
</style>
-18
View File
@@ -1,18 +0,0 @@
import low from 'lowdb'
import LocalStorage from 'lowdb/adapters/LocalStorage'
import { version } from '../../package'
const adapter = new LocalStorage(`d2admin-${version}`)
const db = low(adapter)
// 初始化数据库
db.defaults({
themeActiveName: [],
pageOpenedList: [],
userInfo: [],
isMenuAsideCollapse: [],
database: [],
databasePublic: {}
}).write()
export default db
-97
View File
@@ -1,97 +0,0 @@
import Cookies from 'js-cookie'
import UaParser from 'ua-parser-js'
import { version } from '../../package.json'
let util = {
cookies: {}
}
/**
* @description 存储 cookie 值
* @param {String} name cookie name
* @param {String} value cookie value
* @param {Object} setting cookie setting
*/
util.cookies.set = function (name = 'default', value = '', setting = {}) {
let cookieSetting = {
expires: 1
}
Object.assign(cookieSetting, setting)
Cookies.set(`d2admin-${version}-${name}`, value, cookieSetting)
}
/**
* @description 拿到 cookie 值
* @param {String} name cookie name
*/
util.cookies.get = function (name = 'default') {
return Cookies.get(`d2admin-${version}-${name}`)
}
/**
* @description 拿到 cookie 全部的值
*/
util.cookies.getAll = function () {
return Cookies.get()
}
/**
* @description 删除 cookie
* @param {String} name cookie name
*/
util.cookies.remove = function (name = 'default') {
return Cookies.remove(`d2admin-${version}-${name}`)
}
/**
* @description 更新标题
* @param {String} title 标题
*/
util.title = function (titleText) {
window.document.title = `${process.env.VUE_APP_TITLE}${titleText ? ` | ${titleText}` : ''}`
}
/**
* @description 获取所有的 UA 信息
*/
util.ua = function () {
return new UaParser().getResult()
}
/**
* @description 判断是否在其内
* @param {*} ele element
* @param {Array} targetArr array
*/
util.isOneOf = function (ele, targetArr) {
if (targetArr.indexOf(ele) >= 0) {
return true
} else {
return false
}
}
/**
* @description 打印一个 “胶囊” 样式的信息
* @param {String} title title text
* @param {String} info info text
*/
util.logCapsule = function (title, info) {
console.log(
`%c ${title} %c ${info} %c`,
'background:#29384b; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
'background:#3488ff; padding: 1px; border-radius: 0 3px 3px 0; color: #fff',
'background:transparent'
)
}
/**
* @description 显示版本信息
*/
util.showInfo = function showInfo () {
util.logCapsule('D2Admin Start Kit', `v${version}`)
console.log('Github https://github.com/d2-projects/d2-admin')
console.log('Doc http://d2admin.fairyever.com/zh/')
}
export default util
-85
View File
@@ -1,85 +0,0 @@
import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
// flex.css
import 'flex.css'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import screenfull from 'screenfull'
import '@/assets/svg-icons'
import '@/components'
import '@/plugin/axios'
import '@/mock/register'
import util from '@/libs/util.js'
import store from '@/store/index'
import pluginOpen from '@/plugin/open'
// 菜单和路由设置
import router from './router'
import menuHeader from '@/menu/header'
import menuAside from '@/menu/aside'
import { frameInRoutes } from '@/router/routes'
Vue.use(ElementUI)
Vue.use(pluginOpen)
Vue.config.productionTip = false
Vue.prototype.$env = process.env.NODE_ENV
Vue.prototype.$baseUrl = process.env.BASE_URL
new Vue({
router,
store,
render: h => h(App),
created () {
// 处理路由 得到每一级的路由设置
this.getAllPageFromRoutes()
// 设置顶栏菜单
this.$store.commit('d2adminMenuHeaderSet', menuHeader)
// 设置侧边栏菜单
this.$store.commit('d2adminMenuAsideSet', menuAside)
},
mounted () {
// 获取并记录用户 UA
this.$store.commit('d2adminUaGet')
// 展示系统信息
util.showInfo()
// 用户登陆后从数据库加载一系列的设置
this.$store.commit('d2adminLoginSuccessLoad')
// 初始化全屏监听
this.fullscreenListenerInit()
},
methods: {
/**
* 初始化全屏监听
*/
fullscreenListenerInit () {
if (screenfull.enabled) {
screenfull.on('change', () => {
if (!screenfull.isFullscreen) {
this.$store.commit('d2adminFullScreenSet', false)
}
})
}
},
/**
* 处理路由 得到所有的页面
*/
getAllPageFromRoutes () {
const pool = []
const push = function (routes) {
routes.forEach(route => {
if (route.children) {
push(route.children)
} else {
const { meta, name, path } = route
pool.push({ meta, name, path })
}
})
}
push(frameInRoutes)
this.$store.commit('d2adminPagePoolSet', pool)
}
}
}).$mount('#app')
-13
View File
@@ -1,13 +0,0 @@
// 菜单 侧边栏
export default [
{ path: '/index', title: '首页', icon: 'home' },
{
title: '页面',
icon: 'folder-o',
children: [
{ path: '/page1', title: '页面 1' },
{ path: '/page2', title: '页面 2' },
{ path: '/page3', title: '页面 3' }
]
}
]
-13
View File
@@ -1,13 +0,0 @@
// 菜单 顶栏
export default [
{ path: '/index', title: '首页', icon: 'home' },
{
title: '页面',
icon: 'folder-o',
children: [
{ path: '/page1', title: '页面 1' },
{ path: '/page2', title: '页面 2' },
{ path: '/page3', title: '页面 3' }
]
}
]
-42
View File
@@ -1,42 +0,0 @@
import Mock from 'mockjs'
const userDB = [
{
username: 'admin',
password: 'admin',
uuid: 'admin-uuid',
name: '管理员'
},
{
username: 'editor',
password: 'editor',
uuid: 'editor-uuid',
name: '编辑'
},
{
username: 'user1',
password: 'user1',
uuid: 'user1-uuid',
name: '用户1'
}
]
Mock.mock('/login', 'post', ({url, type, body}) => {
const bodyObj = JSON.parse(body)
const user = userDB.find(e => e.username === bodyObj.username && e.password === bodyObj.password)
if (user) {
return {
code: 0,
msg: '登陆成功',
data: {
...user,
token: 'd787syv8dys8cas80d9s0a0d8f79ads56f7s4d56f879a8as89fd980s7dg'
}
}
} else {
return {
code: 401,
msg: '用户名或密码错误'
}
}
})
-8
View File
@@ -1,8 +0,0 @@
import Mock from 'mockjs'
import '@/mock/login'
// 设置全局延时 没有延时的话有时候会检测不到数据变化 建议保留
Mock.setup({
timeout: '300-600'
})
-3
View File
@@ -1,3 +0,0 @@
import page from './page'
export default page
-25
View File
@@ -1,25 +0,0 @@
<template>
<div class="page-404">
<p class="page-404_title">page not found</p>
<el-button class="d2-mt" @click="$router.replace({ path: '/' })">
返回首页
</el-button>
</div>
</template>
<style lang="scss" scoped>
@import '~@/assets/style/public.scss';
.page-404 {
background: linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
background-blend-mode: multiply,multiply;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.page-404_title {
font-size: 20px;
color: #FFF;
}
}
</style>
-3
View File
@@ -1,3 +0,0 @@
import page from './page'
export default page
-28
View File
@@ -1,28 +0,0 @@
<template>
<d2-container>
<d2-page-cover
title="I AM D2ADMIN"
sub-title="追求简约美感的后台管理系统集成方案">
<d2-icon-svg style="width: 120px;" name="d2admin"/>
<div slot="footer" class="index-btn-group">
<span @click="$open('https://github.com/d2-projects/d2-admin')">主页</span> |
<span @click="$open('http://d2admin.fairyever.com/zh/')">文档</span> |
<span @click="$open('https://github.com/d2-projects/d2-admin/issues')">issue</span> |
<span @click="$open('https://github.com/d2-projects/d2-admin/issues/new')">提问</span>
</div>
</d2-page-cover>
</d2-container>
</template>
<style lang="scss" scoped>
@import '~@/assets/style/public.scss';
.index-btn-group {
color: $color-text-placehoder;
span {
color: $color-text-sub;
&:hover {
color: $color-text-main;
}
}
}
</style>
-2
View File
@@ -1,2 +0,0 @@
// 例子插件配置地址
// https://vincentgarreau.com/particles.js/#default
-112
View File
@@ -1,112 +0,0 @@
/* eslint-disable */
export default {
"particles": {
"number": {
"value": 6,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#444"
},
"shape": {
"type": "polygon",
"stroke": {
"width": 0,
"color": "#000"
},
"polygon": {
"nb_sides": 6
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.3,
"random": true,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 160,
"random": false,
"anim": {
"enable": true,
"speed": 10,
"size_min": 40,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 200,
"color": "#ffffff",
"opacity": 1,
"width": 2
},
"move": {
"enable": true,
"speed": 8,
"direction": "none",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": false,
"mode": "grab"
},
"onclick": {
"enable": false,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 400,
"size": 40,
"duration": 2,
"opacity": 8,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
-112
View File
@@ -1,112 +0,0 @@
/* eslint-disable */
export default {
"particles": {
"number": {
"value": 80,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#DCDFE6"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 1,
"random": false,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 4,
"random": true,
"anim": {
"enable": false,
"speed": 40,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": true,
"distance": 150,
"color": "#DCDFE6",
"opacity": 0.4,
"width": 2
},
"move": {
"enable": true,
"speed": 6,
"direction": "none",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "repulse"
},
"onclick": {
"enable": true,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 400,
"size": 40,
"duration": 2,
"opacity": 8,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
-112
View File
@@ -1,112 +0,0 @@
/* eslint-disable */
export default {
"particles": {
"number": {
"value": 160,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#ffffff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 1,
"random": true,
"anim": {
"enable": true,
"speed": 1,
"opacity_min": 0,
"sync": false
}
},
"size": {
"value": 3,
"random": true,
"anim": {
"enable": false,
"speed": 4,
"size_min": 0.3,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 150,
"color": "#ffffff",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 1,
"direction": "none",
"random": true,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 600
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 250,
"size": 0,
"duration": 2,
"opacity": 0,
"speed": 3
},
"repulse": {
"distance": 400,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
-112
View File
@@ -1,112 +0,0 @@
/* eslint-disable */
export default {
"particles": {
"number": {
"value": 400,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#fff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.5,
"random": true,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 10,
"random": true,
"anim": {
"enable": false,
"speed": 40,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 500,
"color": "#ffffff",
"opacity": 0.4,
"width": 2
},
"move": {
"enable": true,
"speed": 6,
"direction": "bottom",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 0.5
}
},
"bubble": {
"distance": 400,
"size": 4,
"duration": 0.3,
"opacity": 1,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

-3
View File
@@ -1,3 +0,0 @@
import page from './page'
export default page
-147
View File
@@ -1,147 +0,0 @@
<template>
<div class="login-page">
<div class="layer bg" id="login"></div>
<div class="layer flex-center">
<!-- logo部分 -->
<div class="logo-group">
<img src="./image/logo.png" alt="logo">
</div>
<!-- 表单部分 -->
<div class="form-group">
<el-card>
<el-form ref="loginForm" label-position="top" :rules="rules" :model="formLogin">
<el-form-item prop="username">
<el-input type="text" v-model="formLogin.username" placeholder="用户名">
<i slot="prepend" class="fa fa-user-circle-o"></i>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" v-model="formLogin.password" placeholder="密码">
<i slot="prepend" class="fa fa-keyboard-o"></i>
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input type="text" v-model="formLogin.code" placeholder="- - - -">
<template slot="prepend">验证码</template>
<template slot="append">
<img class="login-code" src="./image/login-code.png">
</template>
</el-input>
</el-form-item>
<el-button @click="submit" type="primary" class="button-login">登录</el-button>
</el-form>
</el-card>
</div>
<!-- 快速登陆按钮 -->
<el-button type="info" class="button-help" @click="dialogVisible = true">
快速选择用户(测试功能)
</el-button>
</div>
<el-dialog
title="快速选择用户"
:visible.sync="dialogVisible"
width="400px">
<el-row :gutter="10" style="margin: -20px 0px -10px 0px;">
<el-col v-for="(user, index) in users" :key="index" :span="8">
<div class="user-btn" @click="handleUserBtnClick(user)">
<d2-icon name="user-circle-o"/>
<span>{{user.name}}</span>
</div>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
/* eslint-disable */
require('particles.js')
import config from './config/default'
import { mapActions } from 'vuex'
export default {
data () {
return {
// 快速选择用户
dialogVisible: false,
users: [
{
name: '管理员',
username: 'admin',
password: 'admin'
},
{
name: '编辑',
username: 'editor',
password: 'editor'
},
{
name: '用户1',
username: 'user1',
password: 'user1'
}
],
// 表单
formLogin: {
username: 'admin',
password: 'admin',
code: 'v9am'
},
// 校验
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' }
]
}
}
},
mounted () {
// 初始化例子插件
particlesJS('login', config)
},
methods: {
...mapActions([
'd2adminLogin'
]),
/**
* @description 接收选择一个用户快速登陆的事件
* @param {Object} user 用户信息
*/
handleUserBtnClick (user) {
this.formLogin.username = user.username
this.formLogin.password = user.password
this.submit()
},
/**
* @description 提交表单
*/
// 提交登陆信息
submit () {
this.$refs.loginForm.validate((valid) => {
if (valid) {
// 登陆
// 注意 这里的演示没有传验证码
// 具体需要传递的数据请自行修改代码
this.d2adminLogin({
vm: this,
username: this.formLogin.username,
password: this.formLogin.password
})
} else {
// 登陆表单校验失败
this.$message.error('表单校验失败')
}
})
}
}
}
</script>
<style lang="scss">
@import './style.scss';
</style>
-90
View File
@@ -1,90 +0,0 @@
@import '~@/assets/style/public.scss';
.login-page {
background-color: #EDF4FA;
height: 100%;
position: relative;
// 层
.layer {
position: absolute;
height: 100%;
width: 100%;
&.flex-center {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
}
// 背景
.bg {
canvas {
display: block;
margin: 0px;
padding: 0px;
}
}
// logo
.logo-group {
margin-top: -75px - 70px;
position: relative;
top: 75px;
img {
height: 140px;
}
}
// 登陆表单
.form-group {
width: 300px;
// 重新设置卡片阴影
.el-card {
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
.el-card__body {
padding-top: 70px;
}
}
// 登陆按钮
.button-login {
width: 100%;
}
// 输入框左边的图表区域缩窄
.el-input-group__prepend {
padding: 0px 14px;
}
.login-code {
height: 40px - 2px;
display: block;
margin: 0px -20px;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
}
// 帮助按钮
.button-help {
width: 300px;
margin-top: 20px;
}
.user-btn {
@extend %flex-center-col;
@extend %unable-select;
padding: 10px 0px;
border-radius: 4px;
&:hover {
background-color: $color-bg;
i {
color: $color-text-normal;
}
span {
color: $color-text-normal;
}
}
i {
font-size: 36px;
color: $color-text-sub;
}
span {
font-size: 12px;
margin-top: 10px;
color: $color-text-sub;
}
}
}
-13
View File
@@ -1,13 +0,0 @@
<template>
<d2-container>
<template slot="header">Page 1 header</template>
Hello World
<template slot="footer">footer</template>
</d2-container>
</template>
<script>
export default {
name: 'page1'
}
</script>
-13
View File
@@ -1,13 +0,0 @@
<template>
<d2-container>
<template slot="header">Page 2 header</template>
Hello World
<template slot="footer">footer</template>
</d2-container>
</template>
<script>
export default {
name: 'page2'
}
</script>
-13
View File
@@ -1,13 +0,0 @@
<template>
<d2-container>
<template slot="header">Page 3 header</template>
Hello World
<template slot="footer">footer</template>
</d2-container>
</template>
<script>
export default {
name: 'page3'
}
</script>
-10
View File
@@ -1,10 +0,0 @@
import Vue from 'vue'
import axios from 'axios'
axios.interceptors.response.use(res => {
return res.data
}, err => {
return Promise.reject(err)
})
Vue.prototype.$axios = axios
-8
View File
@@ -1,8 +0,0 @@
export default {
install (Vue, options) {
// 打开一个url
Vue.prototype.$open = (url = 'https://github.com/d2-projects') => {
window.open(url)
}
}
}
-50
View File
@@ -1,50 +0,0 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import util from '@/libs/util.js'
// 路由数据
import routes from './routes'
Vue.use(VueRouter)
// 导出路由 在 main.js 里使用
const router = new VueRouter({
routes
})
/**
* 路由拦截
* 权限验证
*/
router.beforeEach((to, from, next) => {
// 验证当前路由所有的匹配中是否需要有登陆验证的
if (to.matched.some(r => r.meta.requiresAuth)) {
// 这里暂时将cookie里是否存有token作为验证是否登陆的条件
// 请根据自身业务需要修改
const token = util.cookies.get('token')
if (token && token !== 'undefined') {
next()
} else {
// 没有登陆的时候跳转到登陆界面
next({
name: 'login'
})
}
} else {
// 不需要身份校验 直接通过
next()
}
})
router.afterEach(to => {
// 需要的信息
const app = router.app
const { name, params, query } = to
// 多页控制 打开新的页面
app.$store.commit('d2adminPageOpenNew', { name, params, query })
// 更改标题
util.title(to.meta.title)
})
export default router
-75
View File
@@ -1,75 +0,0 @@
// layout
import layoutHeaderAside from '@/layout/header-aside'
const meta = { requiresAuth: true }
/**
* 在主框架内显示
*/
const frameIn = [
{
path: '/',
redirect: { name: 'index' },
component: layoutHeaderAside,
children: [
{
path: 'index',
name: 'index',
meta,
component: () => import('@/pages/index')
},
{
path: '/page1',
name: 'page1',
component: () => import('@/pages/page1'),
meta: { meta, title: '页面 1' }
},
{
path: '/page2',
name: 'page2',
component: () => import('@/pages/page2'),
meta: { meta, title: '页面 2' }
},
{
path: '/page3',
name: 'page3',
component: () => import('@/pages/page3'),
meta: { meta, title: '页面 3' }
}
]
}
]
/**
* 在主框架之外显示
*/
const frameOut = [
// 登陆
{
path: '/login',
name: 'login',
component: () => import('@/pages/login')
}
]
/**
* 错误页面
*/
const errorPage = [
// 404
{
path: '*',
name: '404',
component: () => import('@/pages/error-page-404')
}
]
// 导出需要显示菜单的
export const frameInRoutes = frameIn
// 重新组织后导出
export default [
...frameIn,
...frameOut,
...errorPage
]
-12
View File
@@ -1,12 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
import d2admin from './modules/d2admin'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
d2admin
}
})
-659
View File
@@ -1,659 +0,0 @@
import screenfull from 'screenfull'
import util from '@/libs/util.js'
import db from '@/libs/db.js'
import themeList from '@/assets/style/theme/list.js'
const pageOpenedDefult = {
name: 'index',
meta: {
title: '首页',
requiresAuth: false
}
}
export default {
state: {
// 用户信息
userInfo: {
name: ''
},
// 顶栏菜单
menuHeader: [],
// 侧栏菜单
menuAside: [],
// 全屏
isFullScreen: false,
// 灰度
isGrayMode: false,
// 侧边栏收缩
isMenuAsideCollapse: false,
// 主题
themeList,
// 现在激活的主题
themeActiveName: themeList[0].name, // 这应该是一个名字 不是对象
// 可以在多页 tab 模式下显示的页面
pagePool: [],
// 当前显示的多页面列表
pageOpenedList: [
pageOpenedDefult
],
// 当前页面
pageCurrent: '',
// 用户 UA
ua: {}
},
getters: {
/**
* @description 返回当前的主题信息 不是一个名字 而是当前激活主题的所有数据
* @param {vuex state} state vuex state
*/
d2adminThemeActiveSetting (state) {
return state.themeList.find(theme => theme.name === state.themeActiveName)
},
/**
* @description 从当前所有打开的多标签页里返回需要缓存的页面 name
* @param {*} state vuex state
*/
d2adminKeepAliveInclude (state) {
return state.pageOpenedList.filter(item => {
if (item.meta) {
if (item.meta.notCache) {
return false
}
}
return true
}).map(e => e.name)
}
},
actions: {
/**
* 登陆
* @param {Object} param0 context
* @param {Object} param1 { vue, username, password }
*/
d2adminLogin ({ state, commit, rootState }, { vm, username, password }) {
// 开始请求登录接口
vm.$axios({
method: 'post',
url: '/login',
data: {
username,
password
}
})
.then(res => {
// 设置 cookie 一定要存 uuid 和 token 两个 cookie
// 整个系统依赖这两个数据进行校验和存储
// uuid 是用户身份唯一标识 用户注册的时候确定 并且不可改变 不可重复
// token 代表用户当前登录状态 建议在网络请求中携带 token,如有必要 token 需要定时更新,默认保存一天
util.cookies.set('uuid', res.data.uuid)
util.cookies.set('token', res.data.token)
// 设置 vuex 用户信息
commit('d2adminUserInfoSet', {
name: res.data.name
})
// 用户登陆后从数据库加载一系列的设置
commit('d2adminLoginSuccessLoad')
// 跳转路由
vm.$router.push({
name: 'index'
})
})
.catch(err => {
console.group('登陆结果')
console.log('err: ', err)
console.groupEnd()
})
},
/**
* 注销用户并返回登陆页面
* @param {Object} param0 context
* @param {Object} confirm need confirm ?
*/
d2adminLogout ({ state, commit, rootState }, { vm, confirm }) {
/**
* @description 注销
*/
function logout () {
// 删除cookie
util.cookies.remove('token')
util.cookies.remove('uuid')
// 跳转路由
vm.$router.push({
name: 'login'
})
}
// 判断是否需要确认
if (confirm) {
commit('d2adminGrayModeSet', true)
vm.$confirm('注销当前账户吗? 打开的标签页和用户设置将会被保存。', '确认操作', {
confirmButtonText: '确定注销',
cancelButtonText: '放弃',
type: 'warning'
})
.then(() => {
commit('d2adminGrayModeSet', false)
logout()
})
.catch(() => {
commit('d2adminGrayModeSet', false)
vm.$message('放弃注销用户')
})
} else {
logout()
}
}
},
mutations: {
/**
* @class 通用工具
* @description 将 state 中某一项存储到数据库 如果已经有的话就更新数据 需要 uuid
* @param {vuex state} state vuex state
* @param {String} key key name
*/
d2adminUtilVuex2DbByUuid (state, key) {
const row = db.get(key).find({uuid: util.cookies.get('uuid')})
if (row.value()) {
row.assign({value: state[key]}).write()
} else {
db.get(key).push({
uuid: util.cookies.get('uuid'),
value: state[key]
}).write()
}
},
/**
* @class 通用工具
* @description 从数据库取值到 vuex 需要 uuid
* @param {vuex state} state vuex state
* @param {Object} param1 key and default value
*/
d2adminUtilDb2VuexByUuid (state, { key, defaultValue }) {
const row = db.get(key).find({uuid: util.cookies.get('uuid')}).value()
state[key] = row ? row.value : defaultValue
},
/**
* @class 通用工具
* @description 将 state 中某一项存储到数据库 如果已经有的话就更新数据 不需要 uuid 所有用户共享
* @param {vuex state} state vuex state
* @param {String} key key name
*/
d2adminUtilVuex2Db (state, key) {
const row = db.get(key).find({pub: 'pub'})
if (row.value()) {
row.assign({value: state[key]}).write()
} else {
db.get(key).push({
pub: 'pub',
value: state[key]
}).write()
}
},
/**
* @class 通用工具
* @description 从数据库取值到 vuex 不需要 uuid 所有用户共享
* @param {vuex state} state vuex state
* @param {Object} param1 key and default value
*/
d2adminUtilDb2Vuex (state, { key, defaultValue }) {
const row = db.get(key).find({pub: 'pub'}).value()
state[key] = row ? row.value : defaultValue
},
/**
* @class 通用工具
* @description 访问本地数据库 用户单独空间 没有初始化会自动初始化
* @param {vuex state} state vuex state
* @param {Function} fn function
*/
d2adminUtilDatabaseUser (state, fn) {
const uuid = util.cookies.get('uuid')
const database = db.get('database').find({ uuid })
if (database.value() === undefined) {
db.get('database').push({
uuid,
value: {}
}).write()
if (fn) {
fn(db.get('database').find({ uuid }).get('value'))
}
} else {
if (fn) {
fn(database.get('value'))
}
}
},
/**
* @class 通用工具
* @description 访问本地数据库 清空用户单独空间 只负责删除 d2adminUtilDatabaseUser 会初始化
* @param {vuex state} state vuex state
*/
d2adminUtilDatabaseUserClear (state) {
db.get('database')
.remove({ uuid: util.cookies.get('uuid') })
.write()
},
/**
* @class 通用工具
* @description 访问本地数据库 这份数据是每个用户都可以访问的
* @param {vuex state} state vuex state
* @param {Function} fn function
*/
d2adminUtilDatabase (state, fn) {
if (fn) {
fn(db.get('databasePublic'))
}
},
/**
* @class 通用工具
* @description 访问本地数据库 清空公用空间
* @param {vuex state} state vuex state
*/
d2adminUtilDatabaseClear (state) {
db.set('databasePublic', {})
.write()
},
/**
* @class UA
* @description 记录 UA
* @param {vuex state} state vuex state
*/
d2adminUaGet (state) {
state.ua = util.ua()
},
/**
* @class menuHeader
* @description 设置顶栏菜单
* @param {vuex state} state vuex state
* @param {Array} menu menu setting
*/
d2adminMenuHeaderSet (state, menu) {
state.menuHeader = menu
},
/**
* @class menuAside
* @description 设置侧边栏菜单
* @param {vuex state} state vuex state
* @param {Array} menu menu setting
*/
d2adminMenuAsideSet (state, menu) {
state.menuAside = menu
},
/**
* @class ...
* @description 用户登陆后从数据库加载一系列的设置
* @param {vuex state} state vuex state
*/
d2adminLoginSuccessLoad (state) {
// DB -> store 加载用户名
this.commit('d2adminUserInfoLoad')
// DB -> store 加载主题
this.commit('d2adminThemeLoad')
// DB -> store 数据库加载上次退出时的多页列表
this.commit('d2adminPageOpenedListLoad')
// DB -> store 数据库加载这个用户之前设置的侧边栏折叠状态
this.commit('d2adminMenuAsideCollapseLoad')
},
/**
* @description 设置用户名
* @class userInfo
* @param {vuex state} state vuex state
* @param {String} userInfo userInfo
*/
d2adminUserInfoSet (state, userInfo) {
state.userInfo = userInfo
this.commit('d2adminUtilVuex2DbByUuid', 'userInfo')
},
/**
* @description 从数据库取用户名
* @class userInfo
* @param {vuex state} state vuex state
*/
d2adminUserInfoLoad (state) {
this.commit('d2adminUtilDb2VuexByUuid', {
key: 'userInfo',
defaultValue: {
name: '请重新登陆'
}
})
},
/**
* @class pagePool
* @description 保存 pagePool (候选池)
* @param {vuex state} state vuex state
* @param {Array} pagePool tags
*/
d2adminPagePoolSet (state, pagePool) {
state.pagePool = pagePool
},
/**
* @class pageCurrent
* @description 打开一个新的页面
* @param {vuex state} state vuex state
* @param {Object} param1 { name, params, query } 路由信息
*/
d2adminPageOpenNew (state, { name, params, query }) {
// 已经打开的页面
let pageOpenedList = state.pageOpenedList
// 判断此页面是否已经打开 并且记录位置
let pageOpendIndex = 0
const pageOpend = pageOpenedList.find((page, index) => {
const same = page.name === name
pageOpendIndex = same ? index : pageOpendIndex
return same
})
if (pageOpend) {
// 页面以前打开过 但是新的页面可能 name 一样,参数不一样
this.commit('d2adminPageOpenedListUpdateItem', { index: pageOpendIndex, params, query })
} else {
// 页面以前没有打开过
let tag = state.pagePool.find(t => t.name === name)
if (tag) {
this.commit('d2adminTagIncreate', { tag, params, query })
}
}
this.commit('d2adminPageCurrentSet', name)
},
/**
* @class pageCurrent
* @description 设置当前激活的页面 name
* @param {vuex state} state vuex state
* @param {String} name new name
*/
d2adminPageCurrentSet (state, name) {
state.pageCurrent = name
},
/**
* @class pageOpenedList
* @description 更新页面列表上的某一项
* @param {vuex state} state vuex state
* @param {Object} param1 { index, params, query } 路由信息
*/
d2adminPageOpenedListUpdateItem (state, { index, params, query }) {
// 更新页面列表某一项
let page = state.pageOpenedList[index]
page.params = params || page.params
page.query = query || page.query
state.pageOpenedList.splice(index, 1, page)
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
},
/**
* @class pageOpenedList
* @description 从数据库载入分页列表
* @param {vuex state} state vuex state
*/
d2adminPageOpenedListLoad (state) {
this.commit('d2adminUtilDb2VuexByUuid', {
key: 'pageOpenedList',
defaultValue: [
pageOpenedDefult
]
})
},
/**
* @class pageOpenedList
* @description 新增一个 tag (打开一个页面)
* @param {vuex state} state vuex state
* @param {Object} param1 new tag info
*/
d2adminTagIncreate (state, { tag, params, query }) {
// 设置新的 tag 在新打开一个以前没打开过的页面时使用
let newPage = tag
newPage.params = params || newPage.params
newPage.query = query || newPage.query
// 添加进当前显示的页面数组
state.pageOpenedList.push(newPage)
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
},
/**
* @class pageOpenedList
* @description 关闭一个 tag (关闭一个页面)
* @param {vuex state} state vuex state
* @param {Object} param1 { tagName: 要关闭的标签名字, vm: vue }
*/
d2adminTagClose (state, { tagName, vm }) {
// 下个新的页面
let newPage = state.pageOpenedList[0]
const isCurrent = state.pageCurrent === tagName
// 如果关闭的页面就是当前显示的页面
if (isCurrent) {
// 去找一个新的页面
let len = state.pageOpenedList.length
for (let i = 1; i < len; i++) {
if (state.pageOpenedList[i].name === tagName) {
if (i < len - 1) {
newPage = state.pageOpenedList[i + 1]
} else {
newPage = state.pageOpenedList[i - 1]
}
break
}
}
}
// 找到这个页面在已经打开的数据里是第几个
const index = state.pageOpenedList.findIndex(page => page.name === tagName)
if (index >= 0) {
state.pageOpenedList.splice(index, 1)
}
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
// 最后需要判断是否需要跳到首页
if (isCurrent) {
const { name = '', params = {}, query = {} } = newPage
let routerObj = {
name,
params,
query
}
vm.$router.push(routerObj)
}
},
/**
* @class pageOpenedList
* @description 关闭当前标签左边的标签
* @param {vuex state} state vuex state
* @param {Object} param1 { pageSelect: 当前选中的tagName, vm: vue }
*/
d2adminTagCloseLeft (state, { pageSelect, vm } = {}) {
const pageAim = pageSelect || state.pageCurrent
let currentIndex = 0
state.pageOpenedList.forEach((page, index) => {
if (page.name === pageAim) {
currentIndex = index
}
})
if (currentIndex > 0) {
state.pageOpenedList.splice(1, currentIndex - 1)
}
state.pageCurrent = pageAim
if (vm && vm.$route.name !== pageAim) {
vm.$router.push({
name: pageAim
})
}
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
},
/**
* @class pageOpenedList
* @description 关闭当前标签右边的标签
* @param {vuex state} state vuex state
* @param {Object} param1 { pageSelect: 当前选中的tagName, vm: vue }
*/
d2adminTagCloseRight (state, { pageSelect, vm } = {}) {
const pageAim = pageSelect || state.pageCurrent
let currentIndex = 0
state.pageOpenedList.forEach((page, index) => {
if (page.name === pageAim) {
currentIndex = index
}
})
state.pageOpenedList.splice(currentIndex + 1)
state.pageCurrent = pageAim
if (vm && vm.$route.name !== pageAim) {
vm.$router.push({
name: pageAim
})
}
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
},
/**
* @class pageOpenedList
* @description 关闭当前激活之外的 tag
* @param {vuex state} state vuex state
* @param {Object} param1 { pageSelect: 当前选中的tagName, vm: vue }
*/
d2adminTagCloseOther (state, { pageSelect, vm } = {}) {
const pageAim = pageSelect || state.pageCurrent
let currentIndex = 0
state.pageOpenedList.forEach((page, index) => {
if (page.name === pageAim) {
currentIndex = index
}
})
if (currentIndex === 0) {
state.pageOpenedList.splice(1)
} else {
state.pageOpenedList.splice(currentIndex + 1)
state.pageOpenedList.splice(1, currentIndex - 1)
}
state.pageCurrent = pageAim
if (vm && vm.$route.name !== pageAim) {
vm.$router.push({
name: pageAim
})
}
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
},
/**
* @class pageOpenedList
* @description 关闭所有 tag
* @param {vuex state} state vuex state
* @param {Object} vm vue
*/
d2adminTagCloseAll (state, vm) {
state.pageOpenedList.splice(1)
// 更新设置到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'pageOpenedList')
// 关闭所有的标签页后需要判断一次现在是不是在首页
if (vm.$route.name !== 'index') {
vm.$router.push({
name: 'index'
})
}
},
/**
* 设置侧边栏展开或者收缩
* @class isMenuAsideCollapse
* @param {vuex state} state vuex state
* @param {Boolean} collapse is collapse
*/
d2adminMenuAsideCollapseSet (state, collapse) {
state.isMenuAsideCollapse = collapse
this.commit('d2adminUtilVuex2DbByUuid', 'isMenuAsideCollapse')
},
/**
* 切换侧边栏展开和收缩
* @class isMenuAsideCollapse
* @param {vuex state} state vuex state
*/
d2adminMenuAsideCollapseToggle (state) {
state.isMenuAsideCollapse = !state.isMenuAsideCollapse
this.commit('d2adminUtilVuex2DbByUuid', 'isMenuAsideCollapse')
},
/**
* 从数据库读取侧边栏展开或者收缩
* @class isMenuAsideCollapse
* @param {vuex state} state vuex state
*/
d2adminMenuAsideCollapseLoad (state) {
this.commit('d2adminUtilDb2VuexByUuid', {
key: 'isMenuAsideCollapse',
defaultValue: false
})
},
/**
* @class isFullScreen
* @description 切换全屏
* @param {vuex state} state vuex state
*/
d2adminFullScreenToggle () {
if (screenfull.isFullscreen) {
screenfull.exit()
this.commit('d2adminFullScreenSet', false)
} else {
screenfull.request()
this.commit('d2adminFullScreenSet', true)
}
},
/**
* @class isFullScreen
* @description 设置 store 里的全屏状态
* @param {vuex state} state vuex state
*/
d2adminFullScreenSet (state, isFullScreen) {
state.isFullScreen = isFullScreen
},
/**
* @class isGrayMode
* @description 切换灰度状态
* @param {vuex state} state vuex state
*/
d2adminGrayModeToggle (state) {
state.isGrayMode = !state.isGrayMode
},
/**
* @class isGrayMode
* @description 设置灰度模式
* @param {vuex state} state vuex state
* @param {Boolean} value new value
*/
d2adminGrayModeSet (state, value) {
state.isGrayMode = value
},
/**
* @class themeActiveName
* @description 激活一个主题(应用到dom上)
* @param {vuex state} state vuex state
* @param {String} themeValue 需要激活的主题名称
*/
d2adminThemeSet (state, themeName) {
// 检查这个主题在主题列表里是否存在
const theme = state.themeList.find(e => e.name === themeName)
if (theme) {
// 设置 state
state.themeActiveName = themeName
} else {
// 设置为列表第一个主题
state.themeActiveName = state.themeList[0].name
}
// 将 vuex 中的主题应用到 dom
this.commit('d2adminTheme2dom')
// 保存到数据库
this.commit('d2adminUtilVuex2DbByUuid', 'themeActiveName')
},
/**
* @class themeActiveName
* @description 从数据库加载主题设置
* @param {vuex state} state vuex state
*/
d2adminThemeLoad (state) {
this.commit('d2adminUtilDb2VuexByUuid', {
key: 'themeActiveName',
defaultValue: state.themeList[0].name
})
this.commit('d2adminTheme2dom')
},
/**
* @class themeActiveName
* @description 将 vuex 中的主题应用到 dom
* @param {vuex state} state vuex state
*/
d2adminTheme2dom (state) {
document.body.className = `theme-${state.themeActiveName}`
}
}
}