mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-11 16:57:09 +08:00
feat: 新增应用配置开关属性,迁移主题配置至 src/config/setting.ts
,新增色弱模式与哀悼模式
This commit is contained in:
@@ -13,3 +13,6 @@ VITE_BASE = '/'
|
|||||||
|
|
||||||
# 是否开启开发者工具
|
# 是否开启开发者工具
|
||||||
VITE_OPEN_DEVTOOLS = false
|
VITE_OPEN_DEVTOOLS = false
|
||||||
|
|
||||||
|
# 应用配置面板
|
||||||
|
VITE_APP_SETTING = true
|
@@ -9,3 +9,6 @@ VITE_API_WS_URL = 'wss://api.continew.top'
|
|||||||
|
|
||||||
# 地址前缀
|
# 地址前缀
|
||||||
VITE_BASE = '/'
|
VITE_BASE = '/'
|
||||||
|
|
||||||
|
# 应用配置面板
|
||||||
|
VITE_APP_SETTING = false
|
@@ -14,3 +14,6 @@ VITE_BASE = '/test'
|
|||||||
|
|
||||||
# 是否开启开发者工具
|
# 是否开启开发者工具
|
||||||
VITE_OPEN_DEVTOOLS = true
|
VITE_OPEN_DEVTOOLS = true
|
||||||
|
|
||||||
|
# 应用配置面板
|
||||||
|
VITE_APP_SETTING = false
|
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"theme": "light",
|
|
||||||
"themeColor": "#165DFF",
|
|
||||||
"tab": true,
|
|
||||||
"tabMode": "card-gutter",
|
|
||||||
"animate": false,
|
|
||||||
"animateMode": "zoom-fade",
|
|
||||||
"menuCollapse": true,
|
|
||||||
"menuAccordion": true,
|
|
||||||
"menuDark": false,
|
|
||||||
"copyrightDisplay": true,
|
|
||||||
"layout": "left"
|
|
||||||
}
|
|
19
src/config/setting.ts
Normal file
19
src/config/setting.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export const defaultSettings: App.AppSettings = {
|
||||||
|
theme: 'light',
|
||||||
|
themeColor: '#165DFF',
|
||||||
|
tab: true,
|
||||||
|
tabMode: 'card-gutter',
|
||||||
|
animate: false,
|
||||||
|
animateMode: 'zoom-fade',
|
||||||
|
menuCollapse: true,
|
||||||
|
menuAccordion: true,
|
||||||
|
menuDark: false,
|
||||||
|
copyrightDisplay: true,
|
||||||
|
layout: 'left',
|
||||||
|
enableColorWeaknessMode: false,
|
||||||
|
enableMourningMode: false,
|
||||||
|
}
|
||||||
|
// 根据环境返回配置
|
||||||
|
export const getSettings = (): App.AppSettings => {
|
||||||
|
return defaultSettings
|
||||||
|
}
|
@@ -1,8 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-drawer v-model:visible="visible" title="项目配置" width="300px" unmount-on-close :footer="false">
|
<a-drawer v-model:visible="visible" title="项目配置" width="300px" unmount-on-close :footer="false">
|
||||||
<a-space :size="15" direction="vertical" fill>
|
<a-space :size="15" direction="vertical" fill>
|
||||||
<a-divider orientation="center">系统布局</a-divider>
|
<a-alert v-if="settingOpen" :show-icon="false" type="info">
|
||||||
<a-row justify="center">
|
「复制配置」按钮,并将配置粘贴到 src/config/settings.ts 文件中。
|
||||||
|
</a-alert>
|
||||||
|
<a-divider v-if="settingOpen" orientation="center">系统布局</a-divider>
|
||||||
|
<a-row v-if="settingOpen" justify="center">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-badge>
|
<a-badge>
|
||||||
<template #content>
|
<template #content>
|
||||||
@@ -35,9 +38,9 @@
|
|||||||
></ColorPicker>
|
></ColorPicker>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
<a-divider orientation="center">界面显示</a-divider>
|
<a-divider v-if="settingOpen" orientation="center">界面显示</a-divider>
|
||||||
|
|
||||||
<a-descriptions :column="1" :align="{ value: 'right' }" :value-style="{ paddingRight: 0 }">
|
<a-descriptions v-if="settingOpen" :column="1" :align="{ value: 'right' }" :value-style="{ paddingRight: 0 }">
|
||||||
<a-descriptions-item label="页签显示">
|
<a-descriptions-item label="页签显示">
|
||||||
<a-switch v-model="appStore.tab" />
|
<a-switch v-model="appStore.tab" />
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
@@ -70,10 +73,28 @@
|
|||||||
<a-descriptions-item label="水印">
|
<a-descriptions-item label="水印">
|
||||||
<a-switch v-model="appStore.isOpenWatermark" />
|
<a-switch v-model="appStore.isOpenWatermark" />
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item v-if="appStore.isOpenWatermark" label="水印信息">
|
<a-descriptions-item label="水印信息">
|
||||||
<a-input v-model="appStore.watermark" placeholder="留空则显示用户名" />
|
<a-input v-model="appStore.watermark" placeholder="留空则显示用户名" />
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
|
|
||||||
|
<a-divider orientation="center">其它</a-divider>
|
||||||
|
<a-descriptions :column="1" :align="{ value: 'right' }" :value-style="{ paddingRight: 0 }">
|
||||||
|
<a-descriptions-item label="色弱模式">
|
||||||
|
<a-switch v-model="appStore.enableColorWeaknessMode" />
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item v-if="settingOpen" label="哀悼模式">
|
||||||
|
<a-switch v-model="appStore.enableMourningMode" />
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
<a-space v-if="settingOpen" direction="vertical" fill>
|
||||||
|
<a-button type="primary" long @click="copySettings">
|
||||||
|
<template #icon>
|
||||||
|
<icon-copy />
|
||||||
|
</template>
|
||||||
|
复制配置
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
@@ -81,13 +102,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ColorPicker } from 'vue-color-kit'
|
import { ColorPicker } from 'vue-color-kit'
|
||||||
import 'vue-color-kit/dist/vue-color-kit.css'
|
import 'vue-color-kit/dist/vue-color-kit.css'
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
import LayoutItem from './components/LayoutItem.vue'
|
import LayoutItem from './components/LayoutItem.vue'
|
||||||
import { useAppStore } from '@/stores'
|
import { useAppStore } from '@/stores'
|
||||||
|
|
||||||
defineOptions({ name: 'SettingDrawer' })
|
defineOptions({ name: 'SettingDrawer' })
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
|
const settingOpen = JSON.parse(import.meta.env.VITE_APP_SETTING)
|
||||||
const tabModeList: App.TabItem[] = [
|
const tabModeList: App.TabItem[] = [
|
||||||
{ label: '卡片', value: 'card' },
|
{ label: '卡片', value: 'card' },
|
||||||
{ label: '间隔卡片', value: 'card-gutter' },
|
{ label: '间隔卡片', value: 'card-gutter' },
|
||||||
@@ -138,6 +161,36 @@ const changeColor = (colorObj: ColorObj) => {
|
|||||||
appStore.setThemeColor(colorObj.hex)
|
appStore.setThemeColor(colorObj.hex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 复制配置
|
||||||
|
const copySettings = () => {
|
||||||
|
const settings: App.AppSettings = {
|
||||||
|
theme: 'light',
|
||||||
|
themeColor: appStore.themeColor,
|
||||||
|
tab: appStore.tab,
|
||||||
|
tabMode: appStore.tabMode,
|
||||||
|
animate: appStore.animate,
|
||||||
|
animateMode: appStore.animateMode,
|
||||||
|
menuCollapse: appStore.menuCollapse,
|
||||||
|
menuAccordion: appStore.menuAccordion,
|
||||||
|
menuDark: appStore.menuDark,
|
||||||
|
copyrightDisplay: appStore.copyrightDisplay,
|
||||||
|
layout: appStore.layout,
|
||||||
|
isOpenWatermark: appStore.isOpenWatermark,
|
||||||
|
watermark: appStore.watermark,
|
||||||
|
enableColorWeaknessMode: appStore.enableColorWeaknessMode,
|
||||||
|
enableMourningMode: appStore.enableMourningMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingJson = JSON.stringify(settings, null, 2)
|
||||||
|
const { isSupported, copy } = useClipboard({ source: settingJson })
|
||||||
|
if (isSupported) {
|
||||||
|
copy(settingJson)
|
||||||
|
Message.success({ content: '复制成功!' })
|
||||||
|
} else {
|
||||||
|
Message.error({ content: '请检查浏览器权限是否开启' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -80,7 +80,6 @@ import { isMobile } from '@/utils'
|
|||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
|
|
||||||
defineOptions({ name: 'HeaderRight' })
|
defineOptions({ name: 'HeaderRight' })
|
||||||
|
|
||||||
let socket: WebSocket
|
let socket: WebSocket
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (socket) {
|
if (socket) {
|
||||||
|
@@ -2,11 +2,11 @@ import { defineStore } from 'pinia'
|
|||||||
import { computed, reactive, toRefs } from 'vue'
|
import { computed, reactive, toRefs } from 'vue'
|
||||||
import { generate, getRgbStr } from '@arco-design/color'
|
import { generate, getRgbStr } from '@arco-design/color'
|
||||||
import { type BasicConfig, listSiteOptionDict } from '@/apis'
|
import { type BasicConfig, listSiteOptionDict } from '@/apis'
|
||||||
import defaultSettings from '@/config/setting.json'
|
import { getSettings } from '@/config/setting'
|
||||||
|
|
||||||
const storeSetup = () => {
|
const storeSetup = () => {
|
||||||
// App配置
|
// App配置
|
||||||
const settingConfig = reactive({ ...defaultSettings }) as App.SettingConfig
|
const settingConfig = reactive({ ...getSettings() }) as App.AppSettings
|
||||||
// 页面切换动画类名
|
// 页面切换动画类名
|
||||||
const transitionName = computed(() => (settingConfig.animate ? settingConfig.animateMode : ''))
|
const transitionName = computed(() => (settingConfig.animate ? settingConfig.animateMode : ''))
|
||||||
|
|
||||||
@@ -81,6 +81,27 @@ const storeSetup = () => {
|
|||||||
document.title = config.SITE_TITLE || ''
|
document.title = config.SITE_TITLE || ''
|
||||||
document.querySelector('link[rel="shortcut icon"]')?.setAttribute('href', config.SITE_FAVICON || '/favicon.ico')
|
document.querySelector('link[rel="shortcut icon"]')?.setAttribute('href', config.SITE_FAVICON || '/favicon.ico')
|
||||||
}
|
}
|
||||||
|
// 监听 色弱模式 和 哀悼模式
|
||||||
|
watch([
|
||||||
|
() => settingConfig.enableMourningMode,
|
||||||
|
() => settingConfig.enableColorWeaknessMode,
|
||||||
|
], ([mourningMode, colorWeaknessMode]) => {
|
||||||
|
const filters = [] as string[]
|
||||||
|
if (mourningMode) {
|
||||||
|
filters.push('grayscale(100%)')
|
||||||
|
}
|
||||||
|
if (colorWeaknessMode) {
|
||||||
|
filters.push('invert(80%)')
|
||||||
|
}
|
||||||
|
// 如果没有任何滤镜条件,移除 `filter` 样式
|
||||||
|
if (filters.length === 0) {
|
||||||
|
document.documentElement.style.removeProperty('filter')
|
||||||
|
} else {
|
||||||
|
document.documentElement.style.setProperty('filter', filters.join(' '))
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
|
})
|
||||||
|
|
||||||
const getFavicon = () => {
|
const getFavicon = () => {
|
||||||
return siteConfig.SITE_FAVICON
|
return siteConfig.SITE_FAVICON
|
||||||
|
30
src/types/app.d.ts
vendored
30
src/types/app.d.ts
vendored
@@ -1,20 +1,22 @@
|
|||||||
declare namespace App {
|
declare namespace App {
|
||||||
/** 系统配置 */
|
interface AppSettings {
|
||||||
interface SettingConfig {
|
theme: 'light' | 'dark'
|
||||||
theme: 'light' | 'dark' // 主题
|
themeColor: string
|
||||||
themeColor: string // 主题色
|
tab: boolean
|
||||||
tab: boolean // 是否显示页签
|
tabMode: 'card' | 'card-gutter' | 'rounded'
|
||||||
tabMode: TabType // 页签风格
|
animate: boolean
|
||||||
animate: boolean // 是否显示动画
|
animateMode: 'zoom-fade' | 'slide-dynamic-origin' | 'fade-slide' | 'fade' | 'fade-bottom' | 'fade-scale'
|
||||||
animateMode: AnimateType // 动画类名
|
menuCollapse: boolean
|
||||||
menuCollapse: boolean // 左侧菜单折叠状态
|
menuAccordion: boolean
|
||||||
menuAccordion: boolean // 左侧菜单手风琴效果
|
menuDark: boolean
|
||||||
copyrightDisplay: boolean // 是否显示底部版权信息
|
copyrightDisplay: boolean
|
||||||
menuDark: boolean // 菜单深色模式
|
|
||||||
layout: 'left' | 'mix'
|
layout: 'left' | 'mix'
|
||||||
isOpenWatermark: boolean // 是否开启水印
|
isOpenWatermark?: boolean
|
||||||
watermark: string // 水印
|
watermark?: string
|
||||||
|
enableColorWeaknessMode?: boolean
|
||||||
|
enableMourningMode?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 导航页签的样式类型 */
|
/** 导航页签的样式类型 */
|
||||||
type TabType = 'card' | 'card-gutter' | 'rounded'
|
type TabType = 'card' | 'card-gutter' | 'rounded'
|
||||||
interface TabItem {
|
interface TabItem {
|
||||||
|
1
src/types/env.d.ts
vendored
1
src/types/env.d.ts
vendored
@@ -5,6 +5,7 @@ interface ImportMetaEnv {
|
|||||||
readonly VITE_API_PREFIX: string
|
readonly VITE_API_PREFIX: string
|
||||||
readonly VITE_API_BASE_URL: string
|
readonly VITE_API_BASE_URL: string
|
||||||
readonly VITE_BASE: string
|
readonly VITE_BASE: string
|
||||||
|
readonly VITE_APP_SETTING: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
|
Reference in New Issue
Block a user