util user menu releases

Former-commit-id: 236acdba4bc6cbd5921647fd5c1ee0258f43c143 [formerly 236acdba4bc6cbd5921647fd5c1ee0258f43c143 [formerly 236acdba4bc6cbd5921647fd5c1ee0258f43c143 [formerly 236acdba4bc6cbd5921647fd5c1ee0258f43c143 [formerly cd607a12b20a3d53a1967ee6012a35e03e3d31fe [formerly 645a010d0d8f84a370c509c39c560d93eaa8ae4f]]]]]
Former-commit-id: fd4e72b6a4dc7cb2731c0b5fbf343dab6c251d3f
Former-commit-id: 68305cd58cbd1927373a79c1b507de3c4f3d9924
Former-commit-id: 48312890868f48d5524b0de0dda489f2b2c57b0a [formerly fec91cd8f508ffe42c5e254dcee018c879f3d51e]
Former-commit-id: 9e300a2baafd1eae86bb69a052f15b904724856e
Former-commit-id: eaafbb0a410a49a286eb8e666b6784b96c9df371
Former-commit-id: ccef5438dddbe9762bd3574b33aab49bc1edee58
Former-commit-id: d2ca5c406860c43079d78a80d18ca2b1ed87f776
Former-commit-id: d4648c6865bff45b24aea999b60381b78417b802
This commit is contained in:
liyang
2018-08-08 16:04:10 +08:00
parent 8ef8ae0ca4
commit 5a91ab709f
15 changed files with 317 additions and 85 deletions

View File

@@ -28,6 +28,7 @@
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.set": "^4.3.2",
"lodash.sortby": "^4.7.0", "lodash.sortby": "^4.7.0",
"lodash.uniqueid": "^4.0.1", "lodash.uniqueid": "^4.0.1",
"lowdb": "^1.0.0", "lowdb": "^1.0.0",

View File

@@ -14,9 +14,9 @@
import { mapState, mapActions } from 'vuex' import { mapState, mapActions } from 'vuex'
export default { export default {
computed: { computed: {
...mapState('d2admin', [ ...mapState('d2admin', {
'userInfo' userInfo: state => state.user.userInfo
]) })
}, },
methods: { methods: {
...mapActions('d2admin', [ ...mapActions('d2admin', [

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-menu mode="horizontal" @select="handleMenuSelect"> <el-menu mode="horizontal" @select="handleMenuSelect">
<template v-for="(menu, menuIndex) in menuHeader"> <template v-for="(menu, menuIndex) in header">
<d2-layout-header-aside-menu-item v-if="menu.children === undefined" :menu="menu" :key="menuIndex"/> <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"/> <d2-layout-header-aside-menu-sub v-else :menu="menu" :key="menuIndex"/>
</template> </template>
@@ -22,8 +22,8 @@ export default {
'd2-layout-header-aside-menu-sub': d2LayoutMainMenuSub 'd2-layout-header-aside-menu-sub': d2LayoutMainMenuSub
}, },
computed: { computed: {
...mapState('d2admin', [ ...mapState('d2admin/menu', [
'menuHeader' 'header'
]) ])
} }
} }

View File

@@ -1,17 +1,17 @@
<template> <template>
<div class="d2-layout-header-aside-menu-side"> <div class="d2-layout-header-aside-menu-side">
<el-menu <el-menu
:collapse="isMenuAsideCollapse" :collapse="asideCollapse"
:unique-opened="true" :unique-opened="true"
:default-active="active" :default-active="active"
ref="menu" ref="menu"
@select="handleMenuSelect"> @select="handleMenuSelect">
<template v-for="(menu, menuIndex) in menuAside"> <template v-for="(menu, menuIndex) in aside">
<d2-layout-header-aside-menu-item v-if="menu.children === undefined" :menu="menu" :key="menuIndex"/> <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"/> <d2-layout-header-aside-menu-sub v-else :menu="menu" :key="menuIndex"/>
</template> </template>
</el-menu> </el-menu>
<div v-if="menuAside.length === 0 && !isMenuAsideCollapse" class="d2-layout-header-aside-menu-empty" flex="dir:top main:center cross:center"> <div v-if="aside.length === 0 && !asideCollapse" class="d2-layout-header-aside-menu-empty" flex="dir:top main:center cross:center">
<d2-icon name="inbox"/> <d2-icon name="inbox"/>
<span>没有侧栏菜单</span> <span>没有侧栏菜单</span>
</div> </div>
@@ -41,14 +41,14 @@ export default {
} }
}, },
computed: { computed: {
...mapState('d2admin', [ ...mapState('d2admin/menu', [
'menuAside', 'aside',
'isMenuAsideCollapse' 'asideCollapse'
]) ])
}, },
watch: { watch: {
// 折叠和展开菜单的时候销毁 better scroll // 折叠和展开菜单的时候销毁 better scroll
isMenuAsideCollapse (val) { asideCollapse (val) {
this.scrollDestroy() this.scrollDestroy()
setTimeout(() => { setTimeout(() => {
this.scrollInit() this.scrollInit()
@@ -59,7 +59,7 @@ export default {
handler (val) { handler (val) {
this.active = val[val.length - 1].path this.active = val[val.length - 1].path
this.$nextTick(() => { this.$nextTick(() => {
if (this.menuAside.length > 0) { if (this.aside.length > 0) {
this.$refs.menu.activeIndex = this.active this.$refs.menu.activeIndex = this.active
} }
}) })

View File

@@ -9,8 +9,8 @@
<div class="d2-layout-header-aside-content" flex="dir:top"> <div class="d2-layout-header-aside-content" flex="dir:top">
<!-- 顶栏 --> <!-- 顶栏 -->
<div class="d2-theme-header" flex-box="0"> <div class="d2-theme-header" flex-box="0">
<div class="logo-group" :style="{width: isMenuAsideCollapse ? asideWidthCollapse : asideWidth}"> <div class="logo-group" :style="{width: asideCollapse ? asideWidthCollapse : asideWidth}">
<img v-if="isMenuAsideCollapse" :src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/icon-only.png`"> <img v-if="asideCollapse" :src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/icon-only.png`">
<img v-else :src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/all.png`"> <img v-else :src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/all.png`">
</div> </div>
<div class="toggle-aside-btn" @click="handleToggleAside"> <div class="toggle-aside-btn" @click="handleToggleAside">
@@ -34,7 +34,7 @@
flex-box="0" flex-box="0"
ref="aside" ref="aside"
class="d2-theme-container-aside" class="d2-theme-container-aside"
:style="{width: isMenuAsideCollapse ? asideWidthCollapse : asideWidth}"> :style="{width: asideCollapse ? asideWidthCollapse : asideWidth}">
<d2-menu-side/> <d2-menu-side/>
</div> </div>
<!-- 主体 --> <!-- 主体 -->
@@ -80,8 +80,10 @@ export default {
computed: { computed: {
...mapState('d2admin', [ ...mapState('d2admin', [
'isGrayMode', 'isGrayMode',
'pageOpenedList', 'pageOpenedList'
'isMenuAsideCollapse' ]),
...mapState('d2admin/menu', [
'asideCollapse'
]), ]),
...mapGetters('d2admin', [ ...mapGetters('d2admin', [
'themeActiveSetting', 'themeActiveSetting',
@@ -99,14 +101,14 @@ export default {
} }
}, },
methods: { methods: {
...mapMutations('d2admin', [ ...mapMutations('d2admin/menu', [
'menuAsideCollapseToggle' 'asideCollapseToggle'
]), ]),
/** /**
* 接收点击切换侧边栏的按钮 * 接收点击切换侧边栏的按钮
*/ */
handleToggleAside () { handleToggleAside () {
this.menuAsideCollapseToggle() this.asideCollapseToggle()
} }
} }
} }

View File

@@ -7,6 +7,9 @@ const db = low(adapter)
// 初始化数据库 // 初始化数据库
db.defaults({ db.defaults({
// 新
sys: {},
// 旧
themeActiveName: [], themeActiveName: [],
pageOpenedList: [], pageOpenedList: [],
userInfo: [], userInfo: [],

View File

@@ -159,9 +159,9 @@ util.checkUpdate = function (vm) {
if (update) { if (update) {
util.log.capsule('D2Admin', `New version ${res.name}`) util.log.capsule('D2Admin', `New version ${res.name}`)
console.log(`版本号: ${res.tag_name} | 详情${res.html_url}`) console.log(`版本号: ${res.tag_name} | 详情${res.html_url}`)
vm.$store.commit('d2admin/releasesUpdateSet', true) vm.$store.commit('d2admin/releases/updateSet', true)
} }
vm.$store.commit('d2admin/releasesLatestSet', res) vm.$store.commit('d2admin/releases/latestSet', res)
}) })
.catch(err => { .catch(err => {
console.log('checkUpdate error', err) console.log('checkUpdate error', err)

View File

@@ -52,7 +52,7 @@ new Vue({
// 处理路由 得到每一级的路由设置 // 处理路由 得到每一级的路由设置
this.getAllPageFromRoutes() this.getAllPageFromRoutes()
// 设置顶栏菜单 // 设置顶栏菜单
this.$store.commit('d2admin/menuHeaderSet', menuHeader) this.$store.commit('d2admin/menu/headerSet', menuHeader)
}, },
mounted () { mounted () {
// D2Admin 开发环境检查更新 // D2Admin 开发环境检查更新
@@ -70,7 +70,7 @@ new Vue({
// 监听路由 控制侧边栏显示 // 监听路由 控制侧边栏显示
'$route.matched' (val) { '$route.matched' (val) {
const _side = menuAside.filter(menu => menu.path === val[0].path) const _side = menuAside.filter(menu => menu.path === val[0].path)
this.$store.commit('d2admin/menuAsideSet', _side.length > 0 ? _side[0].children : []) this.$store.commit('d2admin/menu/asideSet', _side.length > 0 ? _side[0].children : [])
} }
}, },
methods: { methods: {

View File

@@ -6,18 +6,11 @@
<el-card shadow="never" class="d2-card"> <el-card shadow="never" class="d2-card">
<template slot="header">顶栏菜单</template> <template slot="header">顶栏菜单</template>
<el-button-group class="d2-mb"> <el-button-group class="d2-mb">
<el-button @click="handleMenuHeaderSet">设置空菜单</el-button> <el-button @click="handleHeaderSet">设置空菜单</el-button>
<el-button @click="menuHeaderReset">恢复</el-button> <el-button @click="headerReset">恢复</el-button>
</el-button-group> </el-button-group>
<div style="height: 400px; overflow: auto;"> <div style="height: 400px; overflow: auto;">
<d2-highlight :code="JSON.stringify(menuHeader, null, 2)"/> <d2-highlight :code="JSON.stringify(header, null, 2)"/>
<!-- <tree-view
class="tree-view-small"
:data="menuHeader"
:options="{
rootObjectKey: 'menuHeader',
maxDepth: 1
}"/> -->
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
@@ -25,18 +18,11 @@
<el-card shadow="never" class="d2-card"> <el-card shadow="never" class="d2-card">
<template slot="header">侧栏菜单</template> <template slot="header">侧栏菜单</template>
<el-button-group class="d2-mb"> <el-button-group class="d2-mb">
<el-button @click="handleMenuAsideSet">设置空菜单</el-button> <el-button @click="handleAsideSet">设置空菜单</el-button>
<el-button @click="menuAsideReset">恢复</el-button> <el-button @click="asideReset">恢复</el-button>
</el-button-group> </el-button-group>
<div style="height: 400px; overflow: auto;"> <div style="height: 400px; overflow: auto;">
<d2-highlight :code="JSON.stringify(menuAside, null, 2)"/> <d2-highlight :code="JSON.stringify(aside, null, 2)"/>
<!-- <tree-view
class="tree-view-small"
:data="menuAside"
:options="{
rootObjectKey: 'menuAside',
maxDepth: 1
}"/> -->
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
@@ -67,26 +53,26 @@ export default {
] ]
} }
], ],
menuHeaderChanged: false, headerChanged: false,
menuAsideChanged: false, asideChanged: false,
menuHeaderBak: [], headerBak: [],
menuAsideBak: [] asideBak: []
} }
}, },
computed: { computed: {
...mapState('d2admin', [ ...mapState('d2admin/menu', [
'menuHeader', 'header',
'menuAside' 'aside'
]) ])
}, },
created () { created () {
this.menuHeaderBak = clonedeep(this.menuHeader) this.headerBak = clonedeep(this.header)
this.menuAsideBak = clonedeep(this.menuAside) this.asideBak = clonedeep(this.aside)
}, },
beforeDestroy () { beforeDestroy () {
if (this.menuHeaderChanged && this.menuAsideChanged) { if (this.headerChanged && this.asideChanged) {
this.menuHeaderSet(this.menuHeaderBak) this.headerSet(this.headerBak)
this.menuAsideSet(this.menuAsideBak) this.asideSet(this.asideBak)
this.$notify({ this.$notify({
title: '菜单恢复', title: '菜单恢复',
message: '对侧边栏和顶栏菜单的修改已经复原', message: '对侧边栏和顶栏菜单的修改已经复原',
@@ -94,8 +80,8 @@ export default {
}) })
return return
} }
if (this.menuHeaderChanged) { if (this.headerChanged) {
this.menuHeaderSet(this.menuHeaderBak) this.headerSet(this.headerBak)
this.$notify({ this.$notify({
title: '菜单恢复', title: '菜单恢复',
message: '对顶栏菜单的修改已经复原', message: '对顶栏菜单的修改已经复原',
@@ -103,8 +89,8 @@ export default {
}) })
return return
} }
if (this.menuAsideChanged) { if (this.asideChanged) {
this.menuAsideSet(this.menuAsideBak) this.asideSet(this.asideBak)
this.$notify({ this.$notify({
title: '菜单恢复', title: '菜单恢复',
message: '对侧边栏菜单的修改已经复原', message: '对侧边栏菜单的修改已经复原',
@@ -113,16 +99,16 @@ export default {
} }
}, },
methods: { methods: {
...mapMutations('d2admin', [ ...mapMutations('d2admin/menu', [
'menuHeaderSet', 'headerSet',
'menuAsideSet' 'asideSet'
]), ]),
/** /**
* 修改顶栏菜单 * 修改顶栏菜单
*/ */
handleMenuHeaderSet () { handleHeaderSet () {
this.menuHeaderChanged = true this.headerChanged = true
this.menuHeaderSet(this.menuEmpty) this.headerSet(this.menuEmpty)
this.$notify({ this.$notify({
title: '菜单修改', title: '菜单修改',
message: '对顶栏菜单的修改已经生效', message: '对顶栏菜单的修改已经生效',
@@ -132,9 +118,9 @@ export default {
/** /**
* 修改侧边栏菜单 * 修改侧边栏菜单
*/ */
handleMenuAsideSet () { handleAsideSet () {
this.menuAsideChanged = true this.asideChanged = true
this.menuAsideSet(this.menuEmpty) this.asideSet(this.menuEmpty)
this.$notify({ this.$notify({
title: '菜单修改', title: '菜单修改',
message: '对侧边栏菜单的修改已经生效', message: '对侧边栏菜单的修改已经生效',
@@ -144,8 +130,8 @@ export default {
/** /**
* 恢复顶栏菜单 * 恢复顶栏菜单
*/ */
menuHeaderReset () { headerReset () {
this.menuHeaderSet(this.menuHeaderBak) this.headerSet(this.headerBak)
this.$notify({ this.$notify({
title: '菜单恢复', title: '菜单恢复',
message: '对顶栏菜单的修改已经复原', message: '对顶栏菜单的修改已经复原',
@@ -155,8 +141,8 @@ export default {
/** /**
* 恢复侧边栏菜单 * 恢复侧边栏菜单
*/ */
menuAsideReset () { asideReset () {
this.menuAsideSet(this.menuAsideBak) this.asideSet(this.asideBak)
this.$notify({ this.$notify({
title: '菜单恢复', title: '菜单恢复',
message: '对侧边栏菜单的修改已经复原', message: '对侧边栏菜单的修改已经复原',

View File

@@ -1,6 +1,6 @@
<template> <template>
<d2-container type="ghost"> <d2-container type="ghost">
<template slot="header">version {{version}} [ {{releasesUpdate ? '有新版本' : '已经是最新版本'}} ]</template> <template slot="header">version {{releasesVersion}} [ {{releasesUpdate ? '有新版本' : '已经是最新版本'}} ]</template>
<div class="d2-mt d2-mr"> <div class="d2-mt d2-mr">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
@@ -36,7 +36,7 @@
<el-col :span="8"> <el-col :span="8">
<el-card shadow="never" class="d2-card d2-mb"> <el-card shadow="never" class="d2-card d2-mb">
<template slot="header">侧边栏折叠</template> <template slot="header">侧边栏折叠</template>
<el-switch v-model="isMenuAsideCollapse" active-text="收缩" inactive-text="展开" disabled/> <el-switch v-model="menuAsideCollapse" active-text="收缩" inactive-text="展开" disabled/>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
@@ -108,16 +108,21 @@
import { mapState, mapGetters } from 'vuex' import { mapState, mapGetters } from 'vuex'
export default { export default {
computed: { computed: {
...mapState('d2admin', {
// 用户信息
userInfo: state => state.user.userInfo,
// 版本
releasesVersion: state => state.releases.version,
releasesLatest: state => state.releases.latest,
releasesUpdate: state => state.releases.update,
// 菜单
menuHeader: state => state.menu.header,
menuAside: state => state.menu.aside,
menuAsideCollapse: state => state.menu.asideCollapse
}),
...mapState('d2admin', [ ...mapState('d2admin', [
'userInfo',
'version',
'releasesLatest',
'releasesUpdate',
'menuHeader',
'menuAside',
'isFullScreen', 'isFullScreen',
'isGrayMode', 'isGrayMode',
'isMenuAsideCollapse',
'themeList', 'themeList',
'themeActiveName', 'themeActiveName',
'pagePool', 'pagePool',

View File

@@ -1 +1 @@
523f1a7e36f1281a070291d62241d6cdc675d19e a1c3d72ea5edb20e160908b56adff479dbc3446c

View File

@@ -0,0 +1,67 @@
export default {
namespaced: true,
state: {
// 顶栏菜单
header: [],
// 侧栏菜单
aside: [],
// 侧边栏收缩
asideCollapse: false
},
mutations: {
/**
* @param {Object} state vuex state
* @param {Array} menu menu setting
*/
headerSet (state, menu) {
state.header = menu
},
/**
* @param {Object} state vuex state
* @param {Array} menu menu setting
*/
asideSet (state, menu) {
state.aside = menu
},
/**
* 设置侧边栏展开或者收缩
* @param {Object} state vuex state
* @param {Boolean} collapse is collapse
*/
asideCollapseSet (state, collapse) {
// store 赋值
state.asideCollapse = collapse
// 持久化
this.commit('d2admin/util/dbValueSetByUser', {
dbName: 'sys',
path: 'menu.asideCollapse',
value: collapse
})
},
/**
* 切换侧边栏展开和收缩
* @param {Object} state vuex state
*/
asideCollapseToggle (state) {
state.asideCollapse = !state.asideCollapse
// 持久化
this.commit('d2admin/util/dbValueSetByUser', {
dbName: 'sys',
path: 'menu.asideCollapse',
value: state.asideCollapse
})
},
/**
* 从数据库读取侧边栏展开或者收缩
* @param {Object} state vuex state
*/
async asideCollapseLoad (state) {
// store 赋值
state.asideCollapse = await this.dispatch('d2admin/util/dbValueGetByUser', {
dbName: 'sys',
path: 'menu.asideCollapse',
defaultValue: false
})
}
}
}

View File

@@ -0,0 +1,31 @@
import { version } from '../../../../../package'
export default {
namespaced: true,
state: {
// D2Admin 版本
version,
// 最新版本的信息
latest: {},
// 有新版本
update: false
},
mutations: {
/**
* @description 设置是否有新的 D2Admin 版本
* @param {Object} state vuex state
* @param {Boolean} update can update
*/
updateSet (state, update) {
state.update = update
},
/**
* @description 设置最新版本的信息
* @param {Object} state vuex state
* @param {Object}} latest releases value
*/
latestSet (state, latest) {
state.latest = latest
}
}
}

View File

@@ -0,0 +1,36 @@
export default {
state: {
userInfo: {
name: ''
}
},
mutations: {
/**
* @description 设置用户数据
* @param {Object} state vuex state
* @param {*} userInfo userInfo
*/
userInfoSet (state, userInfo) {
// store 赋值
state.userInfo = userInfo
// 持久化
this.commit('d2admin/util/dbValueSetByUser', {
dbName: 'sys',
path: 'user.userInfo',
value: userInfo
})
},
/**
* @description 从数据库取用户数据
* @param {Object} state vuex state
*/
async userInfoLoad (state) {
// store 赋值
state.userInfo = await this.dispatch('d2admin/util/dbValueGetByUser', {
dbName: 'sys',
path: 'user.userInfo',
defaultValue: '请重新登陆'
})
}
}
}

View File

@@ -0,0 +1,101 @@
import db from '@/libs/db.js'
import util from '@/libs/util.js'
/**
* @description 检查路径是否存在 不存在的话初始化
* @param {Object} param dbName {String}: 数据库名称
* @param {Object} param path {String}: 路径
* @param {Object} param defaultValue {*}: 初始化默认值
*/
function pathInit ({
dbName = 'sys',
path = '',
defaultValue = []
}) {
const sys = db.get(dbName)
if (!sys.get(path).value()) {
sys
.set(path, defaultValue)
.write()
}
return sys.get(path)
}
/**
* @description 检查路径下是否有当前用户的档案
* @param {Object} param dbName {String}: 数据库名称
* @param {Object} param path {String}: 路径
*/
function isRowExistByUser ({
dbName = 'sys',
path = ''
}) {
const sys = db.get(dbName)
const row = sys
.get(path)
.find({
uuid: util.cookies.get('uuid')
})
// 返回可以操作的 row 或者布尔值 false
// 外部判断返回值的时候建议使用 if (!isRowExistByUser({}))
if (row.value()) {
return row
} else {
return false
}
}
export default {
namespaced: true,
mutations: {
/**
* @description 将数据存储到指定位置 [用户存储区域]
* @param {Object} state vuex state
* @param {Object} param dbName {String}: 数据库名称
* @param {Object} param path {String}: 存储路径
* @param {Object} param value {*}: 需要存储的值
*/
dbValueSetByUser (state, {
dbName = 'sys',
path = '',
value = ''
}) {
// 得到路径在数据库中的对象 没有初始化会自动初始化
// ByUser 类型的默认值设置为数组
// 以后数组的每一项是一个用户的存档
const currentPath = pathInit({ dbName, path, defaultValue: [] })
// 得到当前用户在数据库此路径下的存档
const row = isRowExistByUser({ dbName, path })
// 合并 or 追加
if (!row) {
currentPath.push({
uuid: util.cookies.get('uuid'),
value
}).write()
} else {
row.assign({ value }).write()
}
}
},
actions: {
/**
* @description 从系统存储中获取数据 [用户存储区域]
* @param {Object} state vuex state
* @param {Object} param dbName {String}: 数据库名称
* @param {Object} param path {String}: 存储路径
* @param {Object} param defaultValue {*}: 取值失败的默认值
*/
dbValueGetByUser (context, {
dbName = 'sys',
path = '',
defaultValue = ''
}) {
return new Promise((resolve, reject) => {
// 得到当前用户在数据库此路径下的存档
const row = isRowExistByUser({ path })
// 返回存档或者默认值
resolve(!row ? defaultValue : row.value().value)
})
}
}
}