Main #1
+2
-11
@@ -1,20 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<router-view />
|
<router-view />
|
||||||
<theme-picker />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ThemePicker from "@/components/ThemePicker"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App"
|
||||||
components: { ThemePicker }
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
|
||||||
#app .theme-picker {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -92,9 +92,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
routes() {
|
routes() {
|
||||||
return this.$store.getters.defaultRoutes
|
return this.$store.getters.defaultRoutes
|
||||||
}
|
}
|
||||||
@@ -213,7 +210,7 @@ export default {
|
|||||||
activeStyle(index) {
|
activeStyle(index) {
|
||||||
if (index !== this.activeIndex) return {}
|
if (index !== this.activeIndex) return {}
|
||||||
return {
|
return {
|
||||||
'background-color': this.theme,
|
'background-color': '#00875A',
|
||||||
'color': '#fff'
|
'color': '#fff'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-color-picker
|
|
||||||
v-model="theme"
|
|
||||||
:predefine="['#00875A', '#006B47', '#007F4F', '#11a983', '#13c2c2', '#6959CD', '#f5222d', '#212121', ]"
|
|
||||||
class="theme-picker"
|
|
||||||
popper-class="theme-picker-dropdown"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const ORIGINAL_THEME = '#00875A' // default color
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chalk: '', // content of theme-chalk css
|
|
||||||
theme: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
defaultTheme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
defaultTheme: {
|
|
||||||
handler: function(val, oldVal) {
|
|
||||||
this.theme = val
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
},
|
|
||||||
async theme(val) {
|
|
||||||
await this.setTheme(val)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (this.defaultTheme !== ORIGINAL_THEME) {
|
|
||||||
this.setTheme(this.defaultTheme)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async setTheme(val) {
|
|
||||||
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
|
|
||||||
if (typeof val !== 'string') return
|
|
||||||
const themeCluster = this.getThemeCluster(val.replace('#', ''))
|
|
||||||
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
|
|
||||||
|
|
||||||
const getHandler = (variable, id) => {
|
|
||||||
return () => {
|
|
||||||
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
|
|
||||||
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
|
|
||||||
|
|
||||||
let styleTag = document.getElementById(id)
|
|
||||||
if (!styleTag) {
|
|
||||||
styleTag = document.createElement('style')
|
|
||||||
styleTag.setAttribute('id', id)
|
|
||||||
document.head.appendChild(styleTag)
|
|
||||||
}
|
|
||||||
styleTag.innerText = newStyle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.chalk) {
|
|
||||||
const url = `/styles/theme-chalk/index.css`
|
|
||||||
await this.getCSSString(url, 'chalk')
|
|
||||||
}
|
|
||||||
|
|
||||||
const chalkHandler = getHandler('chalk', 'chalk-style')
|
|
||||||
chalkHandler()
|
|
||||||
|
|
||||||
const styles = [].slice.call(document.querySelectorAll('style'))
|
|
||||||
.filter(style => {
|
|
||||||
const text = style.innerText
|
|
||||||
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
|
|
||||||
})
|
|
||||||
styles.forEach(style => {
|
|
||||||
const { innerText } = style
|
|
||||||
if (typeof innerText !== 'string') return
|
|
||||||
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$emit('change', val)
|
|
||||||
},
|
|
||||||
|
|
||||||
updateStyle(style, oldCluster, newCluster) {
|
|
||||||
let newStyle = style
|
|
||||||
oldCluster.forEach((color, index) => {
|
|
||||||
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
|
|
||||||
})
|
|
||||||
return newStyle
|
|
||||||
},
|
|
||||||
|
|
||||||
getCSSString(url, variable) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const xhr = new XMLHttpRequest()
|
|
||||||
xhr.onreadystatechange = () => {
|
|
||||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
||||||
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xhr.open('GET', url)
|
|
||||||
xhr.send()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
getThemeCluster(theme) {
|
|
||||||
const tintColor = (color, tint) => {
|
|
||||||
let red = parseInt(color.slice(0, 2), 16)
|
|
||||||
let green = parseInt(color.slice(2, 4), 16)
|
|
||||||
let blue = parseInt(color.slice(4, 6), 16)
|
|
||||||
|
|
||||||
if (tint === 0) { // when primary color is in its rgb space
|
|
||||||
return [red, green, blue].join(',')
|
|
||||||
} else {
|
|
||||||
red += Math.round(tint * (255 - red))
|
|
||||||
green += Math.round(tint * (255 - green))
|
|
||||||
blue += Math.round(tint * (255 - blue))
|
|
||||||
|
|
||||||
red = red.toString(16)
|
|
||||||
green = green.toString(16)
|
|
||||||
blue = blue.toString(16)
|
|
||||||
|
|
||||||
return `#${red}${green}${blue}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const shadeColor = (color, shade) => {
|
|
||||||
let red = parseInt(color.slice(0, 2), 16)
|
|
||||||
let green = parseInt(color.slice(2, 4), 16)
|
|
||||||
let blue = parseInt(color.slice(4, 6), 16)
|
|
||||||
|
|
||||||
red = Math.round((1 - shade) * red)
|
|
||||||
green = Math.round((1 - shade) * green)
|
|
||||||
blue = Math.round((1 - shade) * blue)
|
|
||||||
|
|
||||||
red = red.toString(16)
|
|
||||||
green = green.toString(16)
|
|
||||||
blue = blue.toString(16)
|
|
||||||
|
|
||||||
return `#${red}${green}${blue}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const clusters = [theme]
|
|
||||||
for (let i = 0; i <= 9; i++) {
|
|
||||||
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
|
|
||||||
}
|
|
||||||
clusters.push(shadeColor(theme, 0.1))
|
|
||||||
return clusters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.theme-message,
|
|
||||||
.theme-picker-dropdown {
|
|
||||||
z-index: 99999 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-picker .el-color-picker__trigger {
|
|
||||||
height: 26px !important;
|
|
||||||
width: 26px !important;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-picker-dropdown .el-color-dropdown__link-btn {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<template>
|
|
||||||
<footer v-if="visible" class="copyright">
|
|
||||||
<span>{{ content }}</span>
|
|
||||||
</footer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
computed: {
|
|
||||||
visible() {
|
|
||||||
return this.$store.state.settings.footerVisible
|
|
||||||
},
|
|
||||||
content() {
|
|
||||||
return this.$store.state.settings.footerContent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.copyright {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 36px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
text-align: right;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
color: #666;
|
|
||||||
font-size: 14px;
|
|
||||||
border-top: 1px solid #e7e7e7;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="navbar" :class="['nav' + navType, { 'header-mode': headerMode }]">
|
<div class="navbar" :class="[{ 'header-mode': headerMode }]">
|
||||||
<hamburger v-if="!headerMode" id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
<hamburger v-if="!headerMode" id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||||
|
|
||||||
<breadcrumb v-if="!headerMode && navType == 1" id="breadcrumb-container" class="breadcrumb-container" />
|
<breadcrumb v-if="!headerMode" id="breadcrumb-container" class="breadcrumb-container" />
|
||||||
<top-nav v-if="!headerMode && navType == 2" id="topmenu-container" class="topmenu-container" />
|
|
||||||
<div class="right-menu">
|
<div class="right-menu">
|
||||||
<template v-if="device!=='mobile'">
|
<template v-if="device!=='mobile'">
|
||||||
<el-tooltip content="菜单搜索" effect="dark" placement="bottom">
|
<el-tooltip content="菜单搜索" effect="dark" placement="bottom">
|
||||||
@@ -34,9 +33,6 @@
|
|||||||
<router-link to="/user/profile">
|
<router-link to="/user/profile">
|
||||||
<el-dropdown-item icon="el-icon-user">个人中心</el-dropdown-item>
|
<el-dropdown-item icon="el-icon-user">个人中心</el-dropdown-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
<el-dropdown-item v-if="setting" icon="el-icon-s-tools" @click.native="setLayout">
|
|
||||||
<span>布局设置</span>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item icon="el-icon-lock" @click.native="lockScreen">
|
<el-dropdown-item icon="el-icon-lock" @click.native="lockScreen">
|
||||||
<span>锁定屏幕</span>
|
<span>锁定屏幕</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
@@ -52,7 +48,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import Breadcrumb from '@/components/Breadcrumb'
|
import Breadcrumb from '@/components/Breadcrumb'
|
||||||
import TopNav from './TopNav'
|
|
||||||
import Hamburger from '@/components/Hamburger'
|
import Hamburger from '@/components/Hamburger'
|
||||||
import Screenfull from '@/components/Screenfull'
|
import Screenfull from '@/components/Screenfull'
|
||||||
import Search from '@/components/HeaderSearch'
|
import Search from '@/components/HeaderSearch'
|
||||||
@@ -61,7 +56,6 @@ import HeaderNotice from './HeaderNotice'
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
TopNav,
|
|
||||||
Hamburger,
|
Hamburger,
|
||||||
Screenfull,
|
Screenfull,
|
||||||
Search,
|
Search,
|
||||||
@@ -85,16 +79,6 @@ export default {
|
|||||||
'nickName',
|
'nickName',
|
||||||
'roles'
|
'roles'
|
||||||
]),
|
]),
|
||||||
setting: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.showSettings
|
|
||||||
}
|
|
||||||
},
|
|
||||||
navType: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.navType
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 用户角色标签:根据 roles 数组智能映射为友好文本
|
// 用户角色标签:根据 roles 数组智能映射为友好文本
|
||||||
userRoleLabel() {
|
userRoleLabel() {
|
||||||
const roleMap = {
|
const roleMap = {
|
||||||
@@ -112,9 +96,6 @@ export default {
|
|||||||
toggleSideBar() {
|
toggleSideBar() {
|
||||||
this.$store.dispatch('app/toggleSideBar')
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
},
|
},
|
||||||
setLayout(event) {
|
|
||||||
this.$emit('setLayout')
|
|
||||||
},
|
|
||||||
handleCommand(command) {
|
handleCommand(command) {
|
||||||
// 预留:下拉菜单 command 事件入口
|
// 预留:下拉菜单 command 事件入口
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,219 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
:visible.sync="visible"
|
|
||||||
direction="rtl"
|
|
||||||
size="280px"
|
|
||||||
:title="'布局设置'"
|
|
||||||
class="drawer-setting"
|
|
||||||
:with-header="false"
|
|
||||||
:modal-append-to-body="false"
|
|
||||||
>
|
|
||||||
<div class="setting-drawer-index">
|
|
||||||
<div class="setting-drawer-index__title">主题色</div>
|
|
||||||
<div class="setting-drawer-index__main-color theme-color">
|
|
||||||
<ul class="ul-color">
|
|
||||||
<li
|
|
||||||
v-for="item in colorList"
|
|
||||||
:key="item.color"
|
|
||||||
class="li-theme"
|
|
||||||
:class="{ active: item.color === theme }"
|
|
||||||
:style="{ background: item.color }"
|
|
||||||
@click="changeTheme(item.color)"
|
|
||||||
>
|
|
||||||
<i v-show="item.color === theme" class="icon-check el-icon-check" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-drawer-index__title">界面功能</div>
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label">侧边栏颜色</span>
|
|
||||||
<el-dropdown trigger="click" @command="handleSideTheme">
|
|
||||||
<span class="setting-item__value">
|
|
||||||
{{ sideThemeLabel }}
|
|
||||||
<i class="el-icon-arrow-down" />
|
|
||||||
</span>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="theme-dark">深色主题</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="theme-light">浅色主题</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label">导航栏模式</span>
|
|
||||||
<el-dropdown trigger="click" @command="handleNavType">
|
|
||||||
<span class="setting-item__value">
|
|
||||||
{{ navTypeLabel }}
|
|
||||||
<i class="el-icon-arrow-down" />
|
|
||||||
</span>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="1">侧边栏模式</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="2">顶部导航模式</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="3">侧栏+顶栏</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label"> TagsView 标签栏</span>
|
|
||||||
<el-switch
|
|
||||||
:value="tagsView"
|
|
||||||
@change="changeSetting({ key: 'tagsView', value: !tagsView })"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label"> 侧边栏 Logo</span>
|
|
||||||
<el-switch
|
|
||||||
:value="sidebarLogo"
|
|
||||||
@change="changeSetting({ key: 'sidebarLogo', value: !sidebarLogo })"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<span class="setting-item__label"> 固定 Header</span>
|
|
||||||
<el-switch
|
|
||||||
:value="fixedHeader"
|
|
||||||
@change="changeSetting({ key: 'fixedHeader', value: !fixedHeader })"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Settings',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
visible: false,
|
|
||||||
/**
|
|
||||||
* 主题色列表
|
|
||||||
*/
|
|
||||||
colorList: [
|
|
||||||
{ color: '#00875A', title: '教育绿' },
|
|
||||||
{ color: '#304156', title: '深蓝' },
|
|
||||||
{ color: '#409EFF', title: '亮蓝' },
|
|
||||||
{ color: '#626AEF', title: '亮紫' },
|
|
||||||
{ color: '#EB2F96', title: '粉红' },
|
|
||||||
{ color: '#F8721F', title: '橙色' },
|
|
||||||
{ color: '#CD201F', title: '红色' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
theme: state => state.settings.theme,
|
|
||||||
sideTheme: state => state.settings.sideTheme,
|
|
||||||
navType: state => state.settings.navType,
|
|
||||||
tagsView: state => state.settings.tagsView,
|
|
||||||
sidebarLogo: state => state.settings.sidebarLogo,
|
|
||||||
fixedHeader: state => state.settings.fixedHeader
|
|
||||||
}),
|
|
||||||
sideThemeLabel() {
|
|
||||||
return this.sideTheme === 'theme-dark' ? '深色主题' : '浅色主题'
|
|
||||||
},
|
|
||||||
navTypeLabel() {
|
|
||||||
const map = { 1: '侧边栏模式', 2: '顶部导航模式', 3: '侧栏+顶栏' }
|
|
||||||
return map[this.navType] || '侧边栏模式'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
openSetting() {
|
|
||||||
this.visible = true
|
|
||||||
},
|
|
||||||
closeSetting() {
|
|
||||||
this.visible = false
|
|
||||||
},
|
|
||||||
// 修改主题色
|
|
||||||
changeTheme(color) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', { key: 'theme', value: color })
|
|
||||||
},
|
|
||||||
handleSideTheme(command) {
|
|
||||||
this.changeSetting({ key: 'sideTheme', value: command })
|
|
||||||
},
|
|
||||||
handleNavType(command) {
|
|
||||||
this.changeSetting({ key: 'navType', value: Number(command) })
|
|
||||||
},
|
|
||||||
// 修改布局设置,并持久化到本地存储
|
|
||||||
changeSetting(data) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', data)
|
|
||||||
const setting = JSON.parse(localStorage.getItem('layout-setting') || '{}')
|
|
||||||
setting[data.key] = data.value
|
|
||||||
localStorage.setItem('layout-setting', JSON.stringify(setting))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.setting-drawer-index {
|
|
||||||
padding: 0 20px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&__title {
|
|
||||||
margin-top: 26px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__main-color {
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-color {
|
|
||||||
.ul-color {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.li-theme {
|
|
||||||
list-style: none;
|
|
||||||
display: inline-block;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
margin-right: 6px;
|
|
||||||
border-radius: 50%;
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
box-shadow: 0 0 0 2px #fff, 0 0 0 4px currentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-check {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #606266;
|
|
||||||
|
|
||||||
&__value {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
padding: 0 12px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-drawer size="280px" :visible="showSettings" :with-header="false" :append-to-body="true" :before-close="closeSetting" :lock-scroll="false">
|
|
||||||
<div class="drawer-container">
|
|
||||||
<div>
|
|
||||||
<div class="setting-drawer-content">
|
|
||||||
<div class="setting-drawer-title">
|
|
||||||
<h3 class="drawer-title">菜单导航设置</h3>
|
|
||||||
</div>
|
|
||||||
<div class="nav-wrap">
|
|
||||||
<el-tooltip content="左侧菜单" placement="bottom">
|
|
||||||
<div class="item left" @click="handleNavType(1)" :style="{'--theme': theme}" :class="{ activeItem: navType == 1 }">
|
|
||||||
<b></b><b></b>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
|
|
||||||
<el-tooltip content="混合菜单" placement="bottom">
|
|
||||||
<div class="item mix" @click="handleNavType(2)" :style="{'--theme': theme}" :class="{ activeItem: navType == 2 }">
|
|
||||||
<b></b><b></b>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-tooltip content="顶部菜单" placement="bottom">
|
|
||||||
<div class="item top" @click="handleNavType(3)" :style="{'--theme': theme}" :class="{ activeItem: navType == 3 }">
|
|
||||||
<b></b><b></b>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-title">
|
|
||||||
<h3 class="drawer-title">主题风格设置</h3>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-block-checbox">
|
|
||||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
|
||||||
<img src="@/assets/images/dark.svg" alt="dark">
|
|
||||||
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
|
||||||
<i aria-label="图标: check" class="anticon anticon-check">
|
|
||||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
|
|
||||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
|
||||||
</svg>
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
|
||||||
<img src="@/assets/images/light.svg" alt="light">
|
|
||||||
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
|
||||||
<i aria-label="图标: check" class="anticon anticon-check">
|
|
||||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
|
|
||||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
|
||||||
</svg>
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>主题颜色</span>
|
|
||||||
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider/>
|
|
||||||
|
|
||||||
<h3 class="drawer-title">系统布局配置</h3>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>开启页签</span>
|
|
||||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>持久化标签页</span>
|
|
||||||
<el-switch v-model="tagsViewPersist" :disabled="!tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>显示页签图标</span>
|
|
||||||
<el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>标签页样式</span>
|
|
||||||
<el-radio-group v-model="tagsViewStyle" :disabled="!tagsView" size="mini" class="drawer-switch">
|
|
||||||
<el-radio-button label="card">卡片</el-radio-button>
|
|
||||||
<el-radio-button label="chrome">谷歌</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>固定 Header</span>
|
|
||||||
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>显示 Logo</span>
|
|
||||||
<el-switch v-model="sidebarLogo" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>动态标题</span>
|
|
||||||
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="drawer-item">
|
|
||||||
<span>底部版权</span>
|
|
||||||
<el-switch v-model="footerVisible" class="drawer-switch" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-divider/>
|
|
||||||
|
|
||||||
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
|
||||||
<el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ThemePicker from '@/components/ThemePicker'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { ThemePicker },
|
|
||||||
expose: ['openSetting'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
theme: this.$store.state.settings.theme,
|
|
||||||
sideTheme: this.$store.state.settings.sideTheme,
|
|
||||||
navType: this.$store.state.settings.navType,
|
|
||||||
showSettings: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
fixedHeader: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.fixedHeader
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'fixedHeader',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsViewPersist: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsViewPersist
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsViewPersist',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsView: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsView
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsView',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsIcon: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsIcon
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsIcon',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tagsViewStyle: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.tagsViewStyle
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'tagsViewStyle',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sidebarLogo: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.sidebarLogo
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'sidebarLogo',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dynamicTitle: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.dynamicTitle
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'dynamicTitle',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.$store.dispatch('settings/setTitle', this.$store.state.settings.title)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
footerVisible: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.footerVisible
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'footerVisible',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
navType: {
|
|
||||||
handler(val) {
|
|
||||||
if (val == 1) {
|
|
||||||
this.$store.dispatch("app/toggleSideBarHide", false)
|
|
||||||
}
|
|
||||||
if (val == 2) {
|
|
||||||
}
|
|
||||||
if (val == 3) {
|
|
||||||
this.$store.dispatch("app/toggleSideBarHide", true)
|
|
||||||
}
|
|
||||||
if ([1, 3].includes(val)) {
|
|
||||||
this.$store.commit("SET_SIDEBAR_ROUTERS",this.$store.state.permission.defaultRoutes)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
themeChange(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'theme',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.theme = val
|
|
||||||
},
|
|
||||||
handleTheme(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'sideTheme',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.sideTheme = val
|
|
||||||
},
|
|
||||||
handleNavType(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'navType',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
this.navType = val
|
|
||||||
},
|
|
||||||
openSetting() {
|
|
||||||
this.showSettings = true
|
|
||||||
},
|
|
||||||
closeSetting(){
|
|
||||||
this.showSettings = false
|
|
||||||
},
|
|
||||||
saveSetting() {
|
|
||||||
this.$modal.loading("正在保存到本地,请稍候...")
|
|
||||||
if (!this.tagsViewPersist) {
|
|
||||||
this.$cache.local.remove('tags-view-visited')
|
|
||||||
}
|
|
||||||
this.$cache.local.set(
|
|
||||||
"layout-setting",
|
|
||||||
`{
|
|
||||||
"navType":${this.navType},
|
|
||||||
"tagsView":${this.tagsView},
|
|
||||||
"tagsIcon":${this.tagsIcon},
|
|
||||||
"tagsViewStyle":"${this.tagsViewStyle}",
|
|
||||||
"tagsViewPersist":${this.tagsViewPersist},
|
|
||||||
"fixedHeader":${this.fixedHeader},
|
|
||||||
"sidebarLogo":${this.sidebarLogo},
|
|
||||||
"dynamicTitle":${this.dynamicTitle},
|
|
||||||
"footerVisible":${this.footerVisible},
|
|
||||||
"sideTheme":"${this.sideTheme}",
|
|
||||||
"theme":"${this.theme}"
|
|
||||||
}`
|
|
||||||
)
|
|
||||||
setTimeout(this.$modal.closeLoading(), 1000)
|
|
||||||
},
|
|
||||||
resetSetting() {
|
|
||||||
this.$modal.loading("正在清除设置缓存并刷新,请稍候...")
|
|
||||||
this.$cache.local.remove('tags-view-visited')
|
|
||||||
this.$cache.local.remove("layout-setting")
|
|
||||||
setTimeout("window.location.reload()", 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.setting-drawer-content {
|
|
||||||
.setting-drawer-title {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
color: rgba(0, 0, 0, .85);
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-drawer-block-checbox {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.setting-drawer-block-checbox-item {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 16px;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-drawer-block-checbox-selectIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-left: 24px;
|
|
||||||
color: #00875A;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-container {
|
|
||||||
padding: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
word-wrap: break-word;
|
|
||||||
|
|
||||||
.drawer-title {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
color: rgba(0, 0, 0, .85);
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-item {
|
|
||||||
color: rgba(0, 0, 0, .65);
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 12px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-switch {
|
|
||||||
float: right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导航模式
|
|
||||||
.nav-wrap {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.activeItem {
|
|
||||||
border: 2px solid #{'var(--theme)'} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 56px;
|
|
||||||
height: 48px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #f0f2f5;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
b:first-child {
|
|
||||||
display: block;
|
|
||||||
height: 30%;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
b:last-child {
|
|
||||||
width: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
border-radius: 4px 0 0 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.mix {
|
|
||||||
b:first-child {
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
display: block;
|
|
||||||
height: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
}
|
|
||||||
b:last-child {
|
|
||||||
width: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
position: absolute;
|
|
||||||
height: 70%;
|
|
||||||
border-radius: 0 0 0 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.top {
|
|
||||||
b:first-child {
|
|
||||||
display: block;
|
|
||||||
height: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
border-radius: 4px 4px 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['sidebar-theme-wrapper', settings.sideTheme]" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
|
<div :class="['sidebar-theme-wrapper', 'theme-dark']" :style="{ backgroundColor: variables.menuBackground }">
|
||||||
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
<el-scrollbar class="theme-dark" wrap-class="scrollbar-wrapper">
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
:collapse="isCollapse"
|
:collapse="isCollapse"
|
||||||
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
|
:background-color="variables.menuBackground"
|
||||||
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
:text-color="variables.menuColor"
|
||||||
:unique-opened="true"
|
:unique-opened="true"
|
||||||
:active-text-color="settings.sideTheme === 'theme-dark' ? '#ffffff' : settings.theme"
|
:active-text-color="'#ffffff'"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="tags-view-container" class="tags-view-container" :class="{ 'tags-view-container--chrome': tagsViewStyle === 'chrome' }" :style="chromeVars">
|
<div id="tags-view-container" class="tags-view-container">
|
||||||
<!-- 左切换箭头 -->
|
<!-- 左切换箭头 -->
|
||||||
<span class="tags-nav-btn tags-nav-btn--left" :class="{ disabled: !canScrollLeft }" @click="scrollLeft">
|
<span class="tags-nav-btn tags-nav-btn--left" :class="{ disabled: !canScrollLeft }" @click="scrollLeft">
|
||||||
<i class="el-icon-arrow-left" />
|
<i class="el-icon-arrow-left" />
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
v-for="tag in visitedViews"
|
v-for="tag in visitedViews"
|
||||||
ref="tag"
|
ref="tag"
|
||||||
:key="tag.path"
|
:key="tag.path"
|
||||||
:class="{ 'active': isActive(tag), 'has-icon': tagsIcon }"
|
:class="{ 'active': isActive(tag) }"
|
||||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||||
tag="span"
|
tag="span"
|
||||||
class="tags-view-item"
|
class="tags-view-item"
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
@click.middle.native="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
@click.middle.native="!isAffix(tag) ? closeSelectedTag(tag) : ''"
|
||||||
@contextmenu.prevent.native="openMenu(tag, $event)"
|
@contextmenu.prevent.native="openMenu(tag, $event)"
|
||||||
>
|
>
|
||||||
<svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon" style="margin-right: 3px;" />
|
|
||||||
{{ tag.title }}
|
{{ tag.title }}
|
||||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -91,26 +90,8 @@ export default {
|
|||||||
routes() {
|
routes() {
|
||||||
return this.$store.state.permission.routes
|
return this.$store.state.permission.routes
|
||||||
},
|
},
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
tagsIcon() {
|
|
||||||
return this.$store.state.settings.tagsIcon
|
|
||||||
},
|
|
||||||
tagsViewStyle() {
|
|
||||||
return this.$store.state.settings.tagsViewStyle
|
|
||||||
},
|
|
||||||
selectedDropdownTag() {
|
selectedDropdownTag() {
|
||||||
return this.visitedViews.find(v => this.isActive(v)) || {}
|
return this.visitedViews.find(v => this.isActive(v)) || {}
|
||||||
},
|
|
||||||
chromeVars() {
|
|
||||||
if (this.tagsViewStyle !== 'chrome') return {}
|
|
||||||
const primary = this.theme || '#00875A'
|
|
||||||
return {
|
|
||||||
'--chrome-tab-active-bg': this.mixHexWithWhite(primary, 0.15),
|
|
||||||
'--chrome-tab-text-active': primary,
|
|
||||||
'--chrome-wing-r': '10px'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -148,24 +129,14 @@ export default {
|
|||||||
this.toggleFullscreen()
|
this.toggleFullscreen()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixHexWithWhite(hex, ratio) {
|
|
||||||
const clean = hex.replace('#', '')
|
|
||||||
const r = parseInt(clean.substring(0, 2), 16)
|
|
||||||
const g = parseInt(clean.substring(2, 4), 16)
|
|
||||||
const b = parseInt(clean.substring(4, 6), 16)
|
|
||||||
const mr = Math.round(r * ratio + 255 * (1 - ratio))
|
|
||||||
const mg = Math.round(g * ratio + 255 * (1 - ratio))
|
|
||||||
const mb = Math.round(b * ratio + 255 * (1 - ratio))
|
|
||||||
return `rgb(${mr}, ${mg}, ${mb})`
|
|
||||||
},
|
|
||||||
isActive(route) {
|
isActive(route) {
|
||||||
return route.path === this.$route.path
|
return route.path === this.$route.path
|
||||||
},
|
},
|
||||||
tagActiveStyle(tag) {
|
tagActiveStyle(tag) {
|
||||||
if (!this.isActive(tag) || this.tagsViewStyle !== 'card') return {}
|
if (!this.isActive(tag)) return {}
|
||||||
return {
|
return {
|
||||||
"background-color": this.theme,
|
"background-color": "#00875A",
|
||||||
"border-color": this.theme
|
"border-color": "#00875A"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isAffix(tag) {
|
isAffix(tag) {
|
||||||
@@ -209,9 +180,6 @@ export default {
|
|||||||
return tags
|
return tags
|
||||||
},
|
},
|
||||||
initTags() {
|
initTags() {
|
||||||
if (this.$store.state.settings.tagsViewPersist) {
|
|
||||||
this.$store.dispatch('tagsView/loadPersistedViews')
|
|
||||||
}
|
|
||||||
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
||||||
for (const tag of affixTags) {
|
for (const tag of affixTags) {
|
||||||
if (tag.name) {
|
if (tag.name) {
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-menu
|
|
||||||
:default-active="activeMenu"
|
|
||||||
mode="horizontal"
|
|
||||||
@select="handleSelect"
|
|
||||||
>
|
|
||||||
<template v-for="(item, index) in topMenus">
|
|
||||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
|
|
||||||
<svg-icon
|
|
||||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
|
||||||
:icon-class="item.meta.icon"/>
|
|
||||||
{{ item.meta.title }}
|
|
||||||
</el-menu-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 顶部菜单超出数量折叠 -->
|
|
||||||
<el-submenu :style="{'--theme': theme}" index="more" :key="visibleNumber" v-if="topMenus.length > visibleNumber">
|
|
||||||
<template slot="title">更多菜单</template>
|
|
||||||
<template v-for="(item, index) in topMenus">
|
|
||||||
<el-menu-item
|
|
||||||
:index="item.path"
|
|
||||||
:key="index"
|
|
||||||
v-if="index >= visibleNumber">
|
|
||||||
<svg-icon
|
|
||||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
|
||||||
:icon-class="item.meta.icon"/>
|
|
||||||
{{ item.meta.title }}
|
|
||||||
</el-menu-item>
|
|
||||||
</template>
|
|
||||||
</el-submenu>
|
|
||||||
</el-menu>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { constantRoutes } from "@/router"
|
|
||||||
import { isHttp } from "@/utils/validate"
|
|
||||||
|
|
||||||
// 隐藏侧边栏路由
|
|
||||||
const hideList = ['/index', '/user/profile']
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 顶部栏初始数
|
|
||||||
visibleNumber: 5,
|
|
||||||
// 当前激活菜单的 index
|
|
||||||
currentIndex: undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
theme() {
|
|
||||||
return this.$store.state.settings.theme
|
|
||||||
},
|
|
||||||
// 顶部显示菜单
|
|
||||||
topMenus() {
|
|
||||||
let topMenus = []
|
|
||||||
this.routers.map((menu) => {
|
|
||||||
if (menu.hidden !== true) {
|
|
||||||
// 兼容顶部栏一级菜单内部跳转
|
|
||||||
if (menu.path === '/' && menu.children) {
|
|
||||||
topMenus.push(menu.children[0])
|
|
||||||
} else {
|
|
||||||
topMenus.push(menu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return topMenus
|
|
||||||
},
|
|
||||||
// 所有的路由信息
|
|
||||||
routers() {
|
|
||||||
return this.$store.state.permission.topbarRouters
|
|
||||||
},
|
|
||||||
// 设置子路由
|
|
||||||
childrenMenus() {
|
|
||||||
var childrenMenus = []
|
|
||||||
this.routers.map((router) => {
|
|
||||||
for (var item in router.children) {
|
|
||||||
if (router.children[item].parentPath === undefined) {
|
|
||||||
if (router.path === "/") {
|
|
||||||
router.children[item].path = "/" + router.children[item].path
|
|
||||||
} else {
|
|
||||||
if (!isHttp(router.children[item].path)) {
|
|
||||||
router.children[item].path = router.path + "/" + router.children[item].path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
router.children[item].parentPath = router.path
|
|
||||||
}
|
|
||||||
childrenMenus.push(router.children[item])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return constantRoutes.concat(childrenMenus)
|
|
||||||
},
|
|
||||||
// 默认激活的菜单
|
|
||||||
activeMenu() {
|
|
||||||
const path = this.$route.path
|
|
||||||
let activePath = path
|
|
||||||
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
|
|
||||||
const tmpPath = path.substring(1, path.length)
|
|
||||||
if (!this.$route.meta.link) {
|
|
||||||
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"))
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false)
|
|
||||||
}
|
|
||||||
} else if (!this.$route.children) {
|
|
||||||
activePath = path
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
|
||||||
}
|
|
||||||
this.activeRoutes(activePath)
|
|
||||||
return activePath
|
|
||||||
},
|
|
||||||
},
|
|
||||||
beforeMount() {
|
|
||||||
window.addEventListener('resize', this.setVisibleNumber)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
window.removeEventListener('resize', this.setVisibleNumber)
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.setVisibleNumber()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 根据宽度计算设置显示栏数
|
|
||||||
setVisibleNumber() {
|
|
||||||
const width = document.body.getBoundingClientRect().width / 3
|
|
||||||
this.visibleNumber = parseInt(width / 85)
|
|
||||||
},
|
|
||||||
// 菜单选择事件
|
|
||||||
handleSelect(key, keyPath) {
|
|
||||||
this.currentIndex = key
|
|
||||||
const route = this.routers.find(item => item.path === key)
|
|
||||||
if (isHttp(key)) {
|
|
||||||
// http(s):// 路径新窗口打开
|
|
||||||
window.open(key, "_blank")
|
|
||||||
} else if (!route || !route.children) {
|
|
||||||
// 没有子路由路径内部打开
|
|
||||||
const routeMenu = this.childrenMenus.find(item => item.path === key)
|
|
||||||
if (routeMenu && routeMenu.query) {
|
|
||||||
let query = JSON.parse(routeMenu.query)
|
|
||||||
this.$router.push({ path: key, query: query })
|
|
||||||
} else {
|
|
||||||
this.$router.push({ path: key })
|
|
||||||
}
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
|
||||||
} else {
|
|
||||||
// 显示左侧联动菜单
|
|
||||||
this.activeRoutes(key)
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 当前激活的路由
|
|
||||||
activeRoutes(key) {
|
|
||||||
var routes = []
|
|
||||||
if (this.childrenMenus && this.childrenMenus.length > 0) {
|
|
||||||
this.childrenMenus.map((item) => {
|
|
||||||
if (key == item.parentPath || (key == "index" && "" == item.path)) {
|
|
||||||
routes.push(item)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (routes.length > 0) {
|
|
||||||
this.$store.commit("SET_SIDEBAR_ROUTERS", routes)
|
|
||||||
} else {
|
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.topmenu-container.el-menu--horizontal > .el-menu-item {
|
|
||||||
float: left;
|
|
||||||
height: 50px !important;
|
|
||||||
line-height: 50px !important;
|
|
||||||
color: #303133 !important;
|
|
||||||
padding: 0 5px !important;
|
|
||||||
margin: 0 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
|
|
||||||
border-bottom: 2px solid #{'var(--theme)'} !important;
|
|
||||||
color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* submenu item */
|
|
||||||
.topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
|
|
||||||
float: left;
|
|
||||||
height: 50px !important;
|
|
||||||
line-height: 50px !important;
|
|
||||||
color: #303133 !important;
|
|
||||||
padding: 0 5px !important;
|
|
||||||
margin: 0 10px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
export { default as AppMain } from './AppMain'
|
export { default as AppMain } from './AppMain'
|
||||||
export { default as Navbar } from './Navbar'
|
export { default as Navbar } from './Navbar'
|
||||||
export { default as Settings } from './Settings'
|
|
||||||
export { default as Sidebar } from './Sidebar/index.vue'
|
export { default as Sidebar } from './Sidebar/index.vue'
|
||||||
export { default as TagsView } from './TagsView/index.vue'
|
export { default as TagsView } from './TagsView/index.vue'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme, '--current-color-light': theme + '1a', '--current-color-dark-bg': theme + '33'}">
|
<div :class="classObj" class="app-wrapper" :style="{'--current-color': '#00875A', '--current-color-light': '#00875A1a', '--current-color-dark-bg': '#00875A33'}">
|
||||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||||
|
|
||||||
<!-- 顶部全宽 Header -->
|
<!-- 顶部全宽 Header -->
|
||||||
@@ -15,23 +15,22 @@
|
|||||||
<span class="sys-title">教学管理信息系统</span>
|
<span class="sys-title">教学管理信息系统</span>
|
||||||
</div>
|
</div>
|
||||||
<semester-bar class="top-header__center" />
|
<semester-bar class="top-header__center" />
|
||||||
<navbar class="top-header__right" @setLayout="setLayout" :header-mode="true" />
|
<navbar class="top-header__right" :header-mode="true" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 下方:侧边栏 + 主内容 -->
|
<!-- 下方:侧边栏 + 主内容 -->
|
||||||
<div class="lower-container" :class="{sidebarHide:sidebar.hide}">
|
<div class="lower-container" :class="{sidebarHide:sidebar.hide}">
|
||||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
<div :class="{hasTagsView:true,sidebarHide:sidebar.hide}" class="main-container">
|
||||||
<tags-view v-if="needTagsView"/>
|
<tags-view/>
|
||||||
<app-main/>
|
<app-main/>
|
||||||
<settings ref="settingRef"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
import { AppMain, Navbar, Sidebar, TagsView } from './components'
|
||||||
import SemesterBar from './components/SemesterBar'
|
import SemesterBar from './components/SemesterBar'
|
||||||
import Hamburger from '@/components/Hamburger'
|
import Hamburger from '@/components/Hamburger'
|
||||||
import ResizeMixin from './mixin/ResizeHandler'
|
import ResizeMixin from './mixin/ResizeHandler'
|
||||||
@@ -43,7 +42,6 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
AppMain,
|
AppMain,
|
||||||
Navbar,
|
Navbar,
|
||||||
Settings,
|
|
||||||
Sidebar,
|
Sidebar,
|
||||||
TagsView,
|
TagsView,
|
||||||
SemesterBar,
|
SemesterBar,
|
||||||
@@ -52,11 +50,8 @@ export default {
|
|||||||
mixins: [ResizeMixin],
|
mixins: [ResizeMixin],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
theme: state => state.settings.theme,
|
|
||||||
sideTheme: state => state.settings.sideTheme,
|
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device
|
||||||
needTagsView: state => state.settings.tagsView
|
|
||||||
}),
|
}),
|
||||||
classObj() {
|
classObj() {
|
||||||
return {
|
return {
|
||||||
@@ -74,9 +69,6 @@ export default {
|
|||||||
},
|
},
|
||||||
toggleSideBar() {
|
toggleSideBar() {
|
||||||
this.$store.dispatch('app/toggleSideBar')
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
},
|
|
||||||
setLayout() {
|
|
||||||
this.$refs.settingRef.openSetting()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
@@ -18,7 +18,6 @@ const isWhiteList = (path) => {
|
|||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
if (getToken()) {
|
if (getToken()) {
|
||||||
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
|
|
||||||
const isLock = store.getters.isLock
|
const isLock = store.getters.isLock
|
||||||
/* has token*/
|
/* has token*/
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* 网页标题
|
|
||||||
*/
|
|
||||||
title: process.env.VUE_APP_TITLE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
|
||||||
*/
|
|
||||||
sideTheme: 'theme-dark',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统布局配置
|
|
||||||
*/
|
|
||||||
showSettings: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
|
|
||||||
*/
|
|
||||||
navType: 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示 tagsView
|
|
||||||
*/
|
|
||||||
tagsView: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 持久化标签页
|
|
||||||
*/
|
|
||||||
tagsViewPersist: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示页签图标
|
|
||||||
*/
|
|
||||||
tagsIcon: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标签页样式:card 卡片(默认)、chrome 谷歌浏览器风格
|
|
||||||
*/
|
|
||||||
tagsViewStyle: 'card',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否固定头部
|
|
||||||
*/
|
|
||||||
fixedHeader: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示logo
|
|
||||||
*/
|
|
||||||
sidebarLogo: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示动态标题
|
|
||||||
*/
|
|
||||||
dynamicTitle: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否显示底部版权
|
|
||||||
*/
|
|
||||||
footerVisible: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 底部版权文本内容
|
|
||||||
*/
|
|
||||||
footerContent: 'Copyright © 2018-2026 roomroot. All Rights Reserved.'
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import app from './modules/app'
|
import app from './modules/app'
|
||||||
import lock from './modules/lock'
|
import lock from './modules/lock'
|
||||||
@@ -6,7 +6,6 @@ import dict from './modules/dict'
|
|||||||
import user from './modules/user'
|
import user from './modules/user'
|
||||||
import tagsView from './modules/tagsView'
|
import tagsView from './modules/tagsView'
|
||||||
import permission from './modules/permission'
|
import permission from './modules/permission'
|
||||||
import settings from './modules/settings'
|
|
||||||
import getters from './getters'
|
import getters from './getters'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
@@ -18,8 +17,7 @@ const store = new Vuex.Store({
|
|||||||
dict,
|
dict,
|
||||||
user,
|
user,
|
||||||
tagsView,
|
tagsView,
|
||||||
permission,
|
permission
|
||||||
settings
|
|
||||||
},
|
},
|
||||||
getters
|
getters
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
import defaultSettings from '@/settings'
|
|
||||||
import { useDynamicTitle } from '@/utils/dynamicTitle'
|
|
||||||
|
|
||||||
const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
|
|
||||||
|
|
||||||
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
|
||||||
const state = {
|
|
||||||
title: '',
|
|
||||||
theme: storageSetting.theme || '#00875A',
|
|
||||||
sideTheme: storageSetting.sideTheme || sideTheme,
|
|
||||||
showSettings: showSettings,
|
|
||||||
navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
|
|
||||||
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
|
|
||||||
tagsViewPersist: storageSetting.tagsViewPersist === undefined ? tagsViewPersist : storageSetting.tagsViewPersist,
|
|
||||||
tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
|
|
||||||
tagsViewStyle: storageSetting.tagsViewStyle === undefined ? tagsViewStyle : storageSetting.tagsViewStyle,
|
|
||||||
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
|
|
||||||
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
|
|
||||||
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
|
|
||||||
footerVisible: storageSetting.footerVisible === undefined ? footerVisible : storageSetting.footerVisible,
|
|
||||||
footerContent: footerContent
|
|
||||||
}
|
|
||||||
const mutations = {
|
|
||||||
CHANGE_SETTING: (state, { key, value }) => {
|
|
||||||
if (state.hasOwnProperty(key)) {
|
|
||||||
state[key] = value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
SET_TITLE: (state, title) => {
|
|
||||||
state.title = title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
// 修改布局设置
|
|
||||||
changeSetting({ commit }, data) {
|
|
||||||
commit('CHANGE_SETTING', data)
|
|
||||||
},
|
|
||||||
// 设置网页标题
|
|
||||||
setTitle({ commit }, title) {
|
|
||||||
commit('SET_TITLE', title)
|
|
||||||
useDynamicTitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
mutations,
|
|
||||||
actions
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import store from '@/store'
|
|
||||||
import cache from '@/plugins/cache'
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const PERSIST_KEY = 'tags-view-visited'
|
const PERSIST_KEY = 'tags-view-visited'
|
||||||
|
|
||||||
|
// 布局已固定,不启用标签页持久化
|
||||||
function isPersistEnabled() {
|
function isPersistEnabled() {
|
||||||
return store.state.settings.tagsViewPersist
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveVisitedViews(views) {
|
function saveVisitedViews(views) {
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
import store from '@/store'
|
|
||||||
import defaultSettings from '@/settings'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态修改标题
|
|
||||||
*/
|
|
||||||
export function useDynamicTitle() {
|
|
||||||
if (store.state.settings.dynamicTitle) {
|
|
||||||
document.title = store.state.settings.title + ' - ' + defaultSettings.title
|
|
||||||
} else {
|
|
||||||
document.title = defaultSettings.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
|
||||||
<h3 class="title">{{title}}</h3>
|
<h3 class="title">{{title}}</h3>
|
||||||
@@ -50,14 +50,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import Cookies from "js-cookie"
|
import Cookies from "js-cookie"
|
||||||
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
||||||
import defaultSettings from '@/settings'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: "Login",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
title: process.env.VUE_APP_TITLE,
|
||||||
footerContent: defaultSettings.footerContent,
|
footerContent: "Copyright © 2018-2026 roomroot. All Rights Reserved.",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "admin123",
|
password: "admin123",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="register">
|
<div class="register">
|
||||||
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
|
||||||
<h3 class="title">{{title}}</h3>
|
<h3 class="title">{{title}}</h3>
|
||||||
@@ -55,14 +55,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import { register } from "@/api/login"
|
import { register } from "@/api/login"
|
||||||
import passwordRule from "@/utils/passwordRule"
|
import passwordRule from "@/utils/passwordRule"
|
||||||
import defaultSettings from '@/settings'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [passwordRule],
|
mixins: [passwordRule],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: process.env.VUE_APP_TITLE,
|
title: process.env.VUE_APP_TITLE,
|
||||||
footerContent: defaultSettings.footerContent,
|
footerContent: "Copyright © 2018-2026 roomroot. All Rights Reserved.",
|
||||||
registerForm: {
|
registerForm: {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
|
|||||||
Reference in New Issue
Block a user