mirror of
https://github.com/dataease/dataease.git
synced 2025-02-24 19:42:56 +08:00
perf(X-Pack): 外观配置相关页面
This commit is contained in:
parent
72484e69fc
commit
ce7de33d3a
@ -70,7 +70,6 @@ const getTimeOut = () => {
|
||||
|
||||
xhr.open('get', url, false)
|
||||
xhr.send()
|
||||
console.log(time)
|
||||
return time
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@ import AboutPage from '@/views/about/index.vue'
|
||||
import LangSelector from './LangSelector.vue'
|
||||
import router from '@/router'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const { wsCache } = useCache()
|
||||
const userStore = useUserStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
@ -88,7 +91,12 @@ if (uid.value === '1') {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="top-info-container" ref="buttonRef" v-click-outside="openPopover">
|
||||
<div
|
||||
class="top-info-container"
|
||||
:class="{ 'is-light-top-info': navigateBg && navigateBg === 'light' }"
|
||||
ref="buttonRef"
|
||||
v-click-outside="openPopover"
|
||||
>
|
||||
<el-icon class="main-color">
|
||||
<Icon name="user-img" />
|
||||
</el-icon>
|
||||
@ -163,6 +171,14 @@ if (uid.value === '1') {
|
||||
height: 12px;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.is-light-top-info {
|
||||
.uname-span {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--ed-menu-hover-bg-color) !important;
|
||||
}
|
||||
}
|
||||
.top-info-container {
|
||||
height: 32px;
|
||||
display: flex;
|
||||
|
@ -13,6 +13,8 @@ import TopDoc from '@/layout/components/TopDoc.vue'
|
||||
import AccountOperator from '@/layout/components/AccountOperator.vue'
|
||||
import { isDesktop } from '@/utils/ModelUtil'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
@ -47,6 +49,8 @@ const initShowSystem = () => {
|
||||
const initShowToolbox = () => {
|
||||
showToolbox.value = permissionStore.getRouters.some(route => route.path === '/toolbox')
|
||||
}
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const navigate = computed(() => appearanceStore.getNavigate)
|
||||
onMounted(() => {
|
||||
initShowSystem()
|
||||
initShowToolbox()
|
||||
@ -54,8 +58,9 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-header class="header-flex">
|
||||
<Icon @click="handleIconClick" className="logo" name="logo"></Icon>
|
||||
<el-header class="header-flex" :class="{ 'header-light': navigateBg && navigateBg === 'light' }">
|
||||
<img class="logo" v-if="navigate" :src="navigate" alt="" />
|
||||
<Icon v-else @click="handleIconClick" className="logo" name="logo"></Icon>
|
||||
<el-menu
|
||||
:default-active="activeIndex"
|
||||
class="el-menu-demo"
|
||||
@ -76,7 +81,23 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.header-light {
|
||||
background-color: #ffffff !important;
|
||||
box-shadow: 0px 0.5px 0px 0px #1f232926 !important;
|
||||
.ed-menu {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
.ed-menu--horizontal {
|
||||
.ed-menu-item {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
:deep(.ed-sub-menu__title) {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-flex {
|
||||
margin-bottom: 0.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 56px;
|
||||
@ -143,4 +164,11 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-light {
|
||||
.operate-setting {
|
||||
.ed-icon {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,8 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { ElHeader } from 'element-plus-secondary'
|
||||
import { useRouter } from 'vue-router'
|
||||
import AccountOperator from '@/layout/components/AccountOperator.vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
const props = defineProps({
|
||||
title: propTypes.string.def('系统设置')
|
||||
@ -10,11 +13,17 @@ const props = defineProps({
|
||||
const backToMain = () => {
|
||||
push('/workbranch/index')
|
||||
}
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const navigate = computed(() => appearanceStore.getNavigate)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-header class="header-flex system-header">
|
||||
<Icon className="logo" name="logo"></Icon>
|
||||
<el-header
|
||||
class="header-flex system-header"
|
||||
:class="{ 'header-light': navigateBg && navigateBg === 'light' }"
|
||||
>
|
||||
<img class="logo" v-if="navigate" :src="navigate" alt="" />
|
||||
<Icon v-else className="logo" name="logo"></Icon>
|
||||
<el-divider direction="vertical" />
|
||||
<span class="system">{{ props.title || '系统设置' }}</span>
|
||||
<div class="operate-setting">
|
||||
@ -69,7 +78,15 @@ const backToMain = () => {
|
||||
margin: 0 -7px 0 20px !important;
|
||||
}
|
||||
}
|
||||
.header-light {
|
||||
background-color: #ffffff !important;
|
||||
box-shadow: 0px 0.5px 0px 0px #1f232926 !important;
|
||||
:deep(.work-bar) {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
}
|
||||
.header-flex {
|
||||
margin-bottom: 0.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 56px;
|
||||
@ -96,4 +113,11 @@ const backToMain = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-light {
|
||||
.operate-setting {
|
||||
.ed-icon {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,16 +1,25 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { ElHeader } from 'element-plus-secondary'
|
||||
import { useRouter } from 'vue-router'
|
||||
import AccountOperator from '@/layout/components/AccountOperator.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
const backToMain = () => {
|
||||
push('/workbranch/index')
|
||||
}
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const navigate = computed(() => appearanceStore.getNavigate)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-header class="header-flex system-header">
|
||||
<Icon className="logo" name="logo"></Icon>
|
||||
<el-header
|
||||
class="header-flex system-header"
|
||||
:class="{ 'header-light': navigateBg && navigateBg === 'light' }"
|
||||
>
|
||||
<img class="logo" v-if="navigate" :src="navigate" alt="" />
|
||||
<Icon v-else className="logo" name="logo"></Icon>
|
||||
<el-divider direction="vertical" />
|
||||
<span class="system">模板中心</span>
|
||||
<div class="operate-setting">
|
||||
@ -64,6 +73,13 @@ const backToMain = () => {
|
||||
margin: 0 -7px 0 20px !important;
|
||||
}
|
||||
}
|
||||
.header-light {
|
||||
background-color: #ffffff !important;
|
||||
box-shadow: 0px 0.5px 0px 0px #1f232926 !important;
|
||||
:deep(.work-bar) {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
}
|
||||
.header-flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -91,4 +107,11 @@ const backToMain = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-light {
|
||||
.operate-setting {
|
||||
.ed-icon {
|
||||
color: var(--ed-color-black) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { computed } from 'vue'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const { push, resolve } = useRouter()
|
||||
const redirectUser = () => {
|
||||
const sysMenu = resolve('/system')
|
||||
@ -10,7 +14,7 @@ const redirectUser = () => {
|
||||
|
||||
<template>
|
||||
<el-tooltip class="box-item" effect="dark" content="组织管理中心" placement="top">
|
||||
<div class="sys-setting">
|
||||
<div class="sys-setting" :class="{ 'is-light-setting': navigateBg && navigateBg === 'light' }">
|
||||
<el-icon @click="redirectUser">
|
||||
<Icon class="icon-setting" name="icon-setting" />
|
||||
</el-icon>
|
||||
@ -31,4 +35,9 @@ const redirectUser = () => {
|
||||
background-color: #1e2738;
|
||||
}
|
||||
}
|
||||
.is-light-setting {
|
||||
&:hover {
|
||||
background-color: var(--ed-menu-hover-bg-color) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,7 +1,10 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import TopDocCard from '@/layout/components/TopDocCard.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const { push, resolve } = useRouter()
|
||||
|
||||
const showToolbox = ref(true)
|
||||
@ -54,7 +57,13 @@ onMounted(() => {
|
||||
@click="toRouter(item)"
|
||||
></top-doc-card>
|
||||
<template #reference>
|
||||
<div class="sys-setting" :class="{ 'hidden-toolbox': !showToolbox }">
|
||||
<div
|
||||
class="sys-setting"
|
||||
:class="{
|
||||
'hidden-toolbox': !showToolbox,
|
||||
'is-light-setting': navigateBg && navigateBg === 'light'
|
||||
}"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon name="sys-tools" />
|
||||
</el-icon>
|
||||
@ -90,4 +99,9 @@ onMounted(() => {
|
||||
background-color: #1e2738;
|
||||
}
|
||||
}
|
||||
.is-light-setting {
|
||||
&:hover {
|
||||
background-color: var(--ed-menu-hover-bg-color) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,14 +1,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import TopDocCard from '@/layout/components/TopDocCard.vue'
|
||||
const helpLink = ref('https://dataease.io/docs/v2/')
|
||||
const openBlank = () => {
|
||||
window.open(helpLink.value)
|
||||
}
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const help = computed(() => appearanceStore.getHelp)
|
||||
|
||||
const cardInfoList = [
|
||||
{ name: '帮助文档', url: 'https://dataease.io/docs/v2/', icon: 'top-help-doc' },
|
||||
{ name: '帮助文档', url: help.value || 'https://dataease.io/docs/v2/', icon: 'top-help-doc' },
|
||||
{ name: '产品论坛', url: 'https://bbs.fit2cloud.com/c/de/6', icon: 'top-product-bbs' },
|
||||
{
|
||||
name: '技术博客',
|
||||
@ -36,7 +36,10 @@ const cardInfoList = [
|
||||
></top-doc-card>
|
||||
</el-row>
|
||||
<template #reference>
|
||||
<div class="sys-setting">
|
||||
<div
|
||||
class="sys-setting"
|
||||
:class="{ 'is-light-setting': navigateBg && navigateBg === 'light' }"
|
||||
>
|
||||
<el-icon>
|
||||
<Icon name="docs" />
|
||||
</el-icon>
|
||||
@ -58,6 +61,11 @@ const cardInfoList = [
|
||||
background-color: #1e2738;
|
||||
}
|
||||
}
|
||||
.is-light-setting {
|
||||
&:hover {
|
||||
background-color: var(--ed-menu-hover-bg-color) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
|
@ -9,6 +9,9 @@ import { getRoleRouters } from '@/api/common'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { isMobile } from '@/utils/utils'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
const permissionStore = usePermissionStoreWithOut()
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
@ -35,6 +38,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
await appStore.setAppModel()
|
||||
isDesktop = appStore.getDesktop
|
||||
}
|
||||
await appearanceStore.setAppearance()
|
||||
if (wsCache.get('user.token') || isDesktop) {
|
||||
if (!userStore.getUid) {
|
||||
await userStore.setUser()
|
||||
|
153
core/core-frontend/src/store/modules/appearance.ts
Normal file
153
core/core-frontend/src/store/modules/appearance.ts
Normal file
@ -0,0 +1,153 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { store } from '@/store/index'
|
||||
import { uiLoadApi } from '@/api/login'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const basePath = import.meta.env.VITE_API_BASEPATH
|
||||
const baseUrl = basePath + '/appearance/image/'
|
||||
interface AppearanceState {
|
||||
themeColor?: string
|
||||
customColor?: string
|
||||
navigateBg?: string
|
||||
navigate?: string
|
||||
help?: string
|
||||
bg?: string
|
||||
login?: string
|
||||
slogan?: string
|
||||
web?: string
|
||||
name?: string
|
||||
loaded: boolean
|
||||
}
|
||||
const { wsCache } = useCache()
|
||||
export const useAppearanceStore = defineStore('appearanceStore', {
|
||||
state: (): AppearanceState => {
|
||||
return {
|
||||
themeColor: '',
|
||||
customColor: '',
|
||||
navigateBg: '',
|
||||
navigate: '',
|
||||
help: '',
|
||||
bg: '',
|
||||
login: '',
|
||||
slogan: '',
|
||||
web: '',
|
||||
name: '',
|
||||
loaded: false
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getNavigate(): string {
|
||||
if (this.navigate) {
|
||||
return baseUrl + this.navigate
|
||||
}
|
||||
return null
|
||||
},
|
||||
getHelp(): string {
|
||||
return this.help
|
||||
},
|
||||
getThemeColor(): string {
|
||||
return this.themeColor
|
||||
},
|
||||
getCustomColor(): string {
|
||||
return this.customColor
|
||||
},
|
||||
getNavigateBg(): string {
|
||||
return this.navigateBg
|
||||
},
|
||||
getBg(): string {
|
||||
if (this.bg) {
|
||||
return baseUrl + this.bg
|
||||
}
|
||||
return null
|
||||
},
|
||||
getLogin(): string {
|
||||
if (this.login) {
|
||||
return baseUrl + this.login
|
||||
}
|
||||
return null
|
||||
},
|
||||
getSlogan(): string {
|
||||
return this.slogan
|
||||
},
|
||||
getWeb(): string {
|
||||
if (this.web) {
|
||||
return baseUrl + this.web
|
||||
}
|
||||
return null
|
||||
},
|
||||
getName(): string {
|
||||
return this.name
|
||||
},
|
||||
getLoaded(): boolean {
|
||||
return this.loaded
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setNavigate(data: string) {
|
||||
this.navigate = data
|
||||
},
|
||||
setHelp(data: string) {
|
||||
this.help = data
|
||||
},
|
||||
setNavigateBg(data: string) {
|
||||
this.navigateBg = data
|
||||
},
|
||||
setThemeColor(data: string) {
|
||||
this.themeColor = data
|
||||
},
|
||||
setCustomColor(data: string) {
|
||||
this.customColor = data
|
||||
},
|
||||
setLoaded(data: boolean) {
|
||||
this.loaded = data
|
||||
},
|
||||
async setAppearance() {
|
||||
const desktop = wsCache.get('app.desktop')
|
||||
if (desktop) {
|
||||
this.loaded = true
|
||||
}
|
||||
if (this.loaded) {
|
||||
return
|
||||
}
|
||||
const res = await uiLoadApi()
|
||||
this.loaded = true
|
||||
const resData = res.data
|
||||
if (!resData?.length) {
|
||||
return
|
||||
}
|
||||
const data: AppearanceState = { loaded: false }
|
||||
resData.forEach(item => {
|
||||
data[item.pkey] = item.pval
|
||||
})
|
||||
this.navigate = data.navigate
|
||||
this.help = data.help
|
||||
this.navigateBg = data.navigateBg
|
||||
this.themeColor = data.themeColor
|
||||
this.customColor = data.customColor
|
||||
if (this.themeColor === 'custom' && this.customColor) {
|
||||
document.documentElement.style.setProperty('--ed-color-primary', this.customColor)
|
||||
} else if (document.documentElement.style.getPropertyValue('--ed-color-primary')) {
|
||||
document.documentElement.style.setProperty('--ed-color-primary', '#3370FF')
|
||||
}
|
||||
this.bg = data.bg
|
||||
this.login = data.login
|
||||
this.slogan = data.slogan
|
||||
this.web = data.web
|
||||
this.name = data.name
|
||||
if (this.name) {
|
||||
document.title = this.name
|
||||
}
|
||||
const link = document.querySelector('link[rel="icon"]')
|
||||
if (link) {
|
||||
if (this.web) {
|
||||
link['href'] = baseUrl + this.web
|
||||
} else {
|
||||
link['href'] = '/dataease.svg'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const useAppearanceStoreWithOut = () => {
|
||||
return useAppearanceStore(store)
|
||||
}
|
@ -3,11 +3,12 @@ import { ref, reactive, onMounted, computed, nextTick } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { FormRules, FormInstance } from 'element-plus-secondary'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { loginApi, queryDekey, uiLoadApi } from '@/api/login'
|
||||
import { loginApi, queryDekey } from '@/api/login'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import { CustomPassword } from '@/components/custom-password'
|
||||
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { rsaEncryp } from '@/utils/encryption'
|
||||
import router from '@/router'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
@ -16,14 +17,14 @@ import { logoutHandler } from '@/utils/logout'
|
||||
import DeImage from '@/assets/login-desc-de.png'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import { isLarkPlatform } from '@/utils/utils'
|
||||
const basePath = import.meta.env.VITE_API_BASEPATH
|
||||
const { wsCache } = useCache()
|
||||
const appStore = useAppStoreWithOut()
|
||||
const userStore = useUserStoreWithOut()
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
const contentShow = ref(true)
|
||||
const loading = ref(false)
|
||||
const axiosFinished = ref(false)
|
||||
const axiosFinished = ref(true)
|
||||
const showFoot = ref(false)
|
||||
|
||||
const loginLogoUrl = ref(null)
|
||||
@ -172,23 +173,17 @@ const showLoginErrorMsg = () => {
|
||||
}
|
||||
ElMessage.error(loginErrorMsg.value)
|
||||
}
|
||||
|
||||
const loadArrearance = () => {
|
||||
const imgUrlPrefix = basePath + '/appearance/image/'
|
||||
uiLoadApi().then(res => {
|
||||
axiosFinished.value = true
|
||||
const items = res.data
|
||||
items.forEach(item => {
|
||||
const pkey = item.pkey
|
||||
const pval = item.pval
|
||||
if (pkey === 'bg') {
|
||||
loginImageUrl.value = imgUrlPrefix + pval
|
||||
} else if (pkey === 'login') {
|
||||
loginLogoUrl.value = imgUrlPrefix + pval
|
||||
} else if (pkey === 'slogan') {
|
||||
slogan.value = pval
|
||||
}
|
||||
})
|
||||
})
|
||||
if (appearanceStore.getBg) {
|
||||
loginImageUrl.value = appearanceStore.getBg
|
||||
}
|
||||
if (appearanceStore.getLogin) {
|
||||
loginLogoUrl.value = appearanceStore.getLogin
|
||||
}
|
||||
if (appearanceStore.getSlogan) {
|
||||
slogan.value = appearanceStore.getSlogan
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
loadArrearance()
|
||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit 7614b60f695b438e28bed0e2c7a987aef7aa8f3f
|
||||
Subproject commit 26bcec35ff7c37bd80d8d9192780b1b1d4ea19a0
|
Loading…
Reference in New Issue
Block a user