mirror of
https://gitee.com/dromara/go-view.git
synced 2024-11-29 18:28:28 +08:00
feat: 完成主题切换,语言切换的本地存储
This commit is contained in:
parent
7f67f482da
commit
557ddd6ee5
@ -8,12 +8,13 @@
|
||||
"lint": "eslint \"{src}/**/*.{vue,ts,tsx}\" --fix --ext"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vicons/ionicons5": "^0.11.0",
|
||||
"@vicons/ionicons5": "~0.11.0",
|
||||
"axios": "^0.23.0",
|
||||
"mockjs": "^1.1.0",
|
||||
"naive-ui": "^2.19.9",
|
||||
"pinia": "^2.0.6",
|
||||
"vue": "^3.2.16",
|
||||
"vue-i18n": "^9.2.0-beta.23",
|
||||
"vue-router": "4.0.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -23,6 +24,7 @@
|
||||
"@vitejs/plugin-vue": "^1.9.3",
|
||||
"@vitejs/plugin-vue-jsx": "^1.2.0",
|
||||
"@vue/compiler-sfc": "^3.2.20",
|
||||
"@vueuse/core": "^7.3.0",
|
||||
"default-passive-events": "^2.0.0",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
|
108
pnpm-lock.yaml
108
pnpm-lock.yaml
@ -4,10 +4,11 @@ specifiers:
|
||||
'@types/node': ^16.11.1
|
||||
'@typescript-eslint/eslint-plugin': ^5.6.0
|
||||
'@typescript-eslint/parser': ^5.6.0
|
||||
'@vicons/ionicons5': ^0.11.0
|
||||
'@vicons/ionicons5': ~0.11.0
|
||||
'@vitejs/plugin-vue': ^1.9.3
|
||||
'@vitejs/plugin-vue-jsx': ^1.2.0
|
||||
'@vue/compiler-sfc': ^3.2.20
|
||||
'@vueuse/core': ^7.3.0
|
||||
axios: ^0.23.0
|
||||
default-passive-events: ^2.0.0
|
||||
eslint: ^8.4.1
|
||||
@ -28,6 +29,7 @@ specifiers:
|
||||
vite-plugin-mock: ^2.9.6
|
||||
vite-plugin-style-import: ^1.2.1
|
||||
vue: ^3.2.16
|
||||
vue-i18n: ^9.2.0-beta.23
|
||||
vue-router: 4.0.12
|
||||
vue-tsc: ^0.28.7
|
||||
|
||||
@ -38,6 +40,7 @@ dependencies:
|
||||
naive-ui: rg.cnpmjs.org/naive-ui/2.21.5_vue@3.2.24
|
||||
pinia: rg.cnpmjs.org/pinia/2.0.6_typescript@4.5.2+vue@3.2.24
|
||||
vue: rg.cnpmjs.org/vue/3.2.24
|
||||
vue-i18n: rg.cnpmjs.org/vue-i18n/9.2.0-beta.23_vue@3.2.24
|
||||
vue-router: rg.cnpmjs.org/vue-router/4.0.12_vue@3.2.24
|
||||
|
||||
devDependencies:
|
||||
@ -47,6 +50,7 @@ devDependencies:
|
||||
'@vitejs/plugin-vue': rg.cnpmjs.org/@vitejs/plugin-vue/1.10.2_vite@2.7.1
|
||||
'@vitejs/plugin-vue-jsx': rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1
|
||||
'@vue/compiler-sfc': rg.cnpmjs.org/@vue/compiler-sfc/3.2.24
|
||||
'@vueuse/core': rg.cnpmjs.org/@vueuse/core/7.3.0_vue@3.2.24
|
||||
default-passive-events: rg.cnpmjs.org/default-passive-events/2.0.0
|
||||
eslint: rg.cnpmjs.org/eslint/8.4.1
|
||||
eslint-config-prettier: rg.cnpmjs.org/eslint-config-prettier/8.3.0_eslint@8.4.1
|
||||
@ -510,6 +514,54 @@ packages:
|
||||
version: 1.2.1
|
||||
dev: true
|
||||
|
||||
rg.cnpmjs.org/@intlify/core-base/9.2.0-beta.23:
|
||||
resolution: {integrity: sha512-sNet9/RpU/qydW1bOwVICYzGIC/SWyV+1gakcSP12XD1tGEiaoI1Ln+6nHh4dICfegR/5XyaoJ7NC4/ukH7/Ew==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@intlify/core-base/download/@intlify/core-base-9.2.0-beta.23.tgz}
|
||||
name: '@intlify/core-base'
|
||||
version: 9.2.0-beta.23
|
||||
engines: {node: '>= 12'}
|
||||
dependencies:
|
||||
'@intlify/devtools-if': rg.cnpmjs.org/@intlify/devtools-if/9.2.0-beta.23
|
||||
'@intlify/message-compiler': rg.cnpmjs.org/@intlify/message-compiler/9.2.0-beta.23
|
||||
'@intlify/shared': rg.cnpmjs.org/@intlify/shared/9.2.0-beta.23
|
||||
'@intlify/vue-devtools': rg.cnpmjs.org/@intlify/vue-devtools/9.2.0-beta.23
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/@intlify/devtools-if/9.2.0-beta.23:
|
||||
resolution: {integrity: sha512-f2iY2LFRHTwPnBpT0R/kG8CwZbUWiSccMzfXYLwhjJC1irCcFCXmVtL9Mkz5gc0Elqvl+zOWxk5g9rwhah5bBQ==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@intlify/devtools-if/download/@intlify/devtools-if-9.2.0-beta.23.tgz}
|
||||
name: '@intlify/devtools-if'
|
||||
version: 9.2.0-beta.23
|
||||
engines: {node: '>= 12'}
|
||||
dependencies:
|
||||
'@intlify/shared': rg.cnpmjs.org/@intlify/shared/9.2.0-beta.23
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/@intlify/message-compiler/9.2.0-beta.23:
|
||||
resolution: {integrity: sha512-qmGN8k5yGGdZ5St8yg8U4Tg2K9Sc6h3BhWCdJKAqQVs5jnfZG+nMtsLVgnJUWkDvhjzyg7/rEOhHm2uJcu4vjw==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.23.tgz}
|
||||
name: '@intlify/message-compiler'
|
||||
version: 9.2.0-beta.23
|
||||
engines: {node: '>= 12'}
|
||||
dependencies:
|
||||
'@intlify/shared': rg.cnpmjs.org/@intlify/shared/9.2.0-beta.23
|
||||
source-map: rg.cnpmjs.org/source-map/0.6.1
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/@intlify/shared/9.2.0-beta.23:
|
||||
resolution: {integrity: sha512-3aELL2KTp1MWKGm2gIUKSagthgKzcK5hpQEFzOwkJ1SAthpTXR7BHeWGEaD+Lj+Pbiz3U8cspvp8s2lFWVbYxg==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@intlify/shared/download/@intlify/shared-9.2.0-beta.23.tgz}
|
||||
name: '@intlify/shared'
|
||||
version: 9.2.0-beta.23
|
||||
engines: {node: '>= 12'}
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/@intlify/vue-devtools/9.2.0-beta.23:
|
||||
resolution: {integrity: sha512-5uGvrtUQhiyEqrMpDYh1FAU5uZviLaiEy1HAs+ypX46EdaDvyEYYpWvhezTWZ7hsDBsbsKJ9ICjgTvZxm6PDcw==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@intlify/vue-devtools/download/@intlify/vue-devtools-9.2.0-beta.23.tgz}
|
||||
name: '@intlify/vue-devtools'
|
||||
version: 9.2.0-beta.23
|
||||
engines: {node: '>= 12'}
|
||||
dependencies:
|
||||
'@intlify/core-base': rg.cnpmjs.org/@intlify/core-base/9.2.0-beta.23
|
||||
'@intlify/shared': rg.cnpmjs.org/@intlify/shared/9.2.0-beta.23
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/@jest/types/27.4.2:
|
||||
resolution: {integrity: sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@jest/types/download/@jest/types-27.4.2.tgz}
|
||||
name: '@jest/types'
|
||||
@ -1044,6 +1096,43 @@ packages:
|
||||
name: '@vue/shared'
|
||||
version: 3.2.24
|
||||
|
||||
rg.cnpmjs.org/@vueuse/core/7.3.0_vue@3.2.24:
|
||||
resolution: {integrity: sha512-gPJyMMAquva9Qwqz63qGQT122m5hWI8Kuy8kfPV/JLQU7m01CXooyv8FIrX9TV8OxVcHBTPXPJHY0oyUiFoNgw==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vueuse/core/download/@vueuse/core-7.3.0.tgz}
|
||||
id: rg.cnpmjs.org/@vueuse/core/7.3.0
|
||||
name: '@vueuse/core'
|
||||
version: 7.3.0
|
||||
peerDependencies:
|
||||
'@vue/composition-api': ^1.1.0
|
||||
vue: ^2.6.0 || ^3.2.0
|
||||
peerDependenciesMeta:
|
||||
'@vue/composition-api':
|
||||
optional: true
|
||||
vue:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@vueuse/shared': rg.cnpmjs.org/@vueuse/shared/7.3.0_vue@3.2.24
|
||||
vue: rg.cnpmjs.org/vue/3.2.24
|
||||
vue-demi: rg.cnpmjs.org/vue-demi/0.12.1_vue@3.2.24
|
||||
dev: true
|
||||
|
||||
rg.cnpmjs.org/@vueuse/shared/7.3.0_vue@3.2.24:
|
||||
resolution: {integrity: sha512-vOAeI84tIXKVkzm8s/Mxbrzhj0QN6NyVc/sC6LrW0AjVNdvpD8sB1dZiDn9yh8T77WJmloCEt4zZVIppeq7I+w==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vueuse/shared/download/@vueuse/shared-7.3.0.tgz}
|
||||
id: rg.cnpmjs.org/@vueuse/shared/7.3.0
|
||||
name: '@vueuse/shared'
|
||||
version: 7.3.0
|
||||
peerDependencies:
|
||||
'@vue/composition-api': ^1.1.0
|
||||
vue: ^2.6.0 || ^3.2.0
|
||||
peerDependenciesMeta:
|
||||
'@vue/composition-api':
|
||||
optional: true
|
||||
vue:
|
||||
optional: true
|
||||
dependencies:
|
||||
vue: rg.cnpmjs.org/vue/3.2.24
|
||||
vue-demi: rg.cnpmjs.org/vue-demi/0.12.1_vue@3.2.24
|
||||
dev: true
|
||||
|
||||
rg.cnpmjs.org/acorn-jsx/5.3.2_acorn@8.6.0:
|
||||
resolution: {integrity: sha1-ftW7VZCLOy8bxVxq8WU7rafweTc=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/acorn-jsx/download/acorn-jsx-5.3.2.tgz}
|
||||
id: rg.cnpmjs.org/acorn-jsx/5.3.2
|
||||
@ -4260,7 +4349,6 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
vue: rg.cnpmjs.org/vue/3.2.24
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/vue-eslint-parser/8.0.1_eslint@8.4.1:
|
||||
resolution: {integrity: sha1-JeCLIKQUVRUx8+GfmZkC4ez0XxM=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/vue-eslint-parser/download/vue-eslint-parser-8.0.1.tgz}
|
||||
@ -4283,6 +4371,22 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
rg.cnpmjs.org/vue-i18n/9.2.0-beta.23_vue@3.2.24:
|
||||
resolution: {integrity: sha512-9zpylFVjhMDiNnSpa8pFf/lXiALKzxDKEo9QrSV906cN0m6jtyjvjCWw6dRx/7Q4ZJuwXYg0wi/UtUkgu0wkQw==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/vue-i18n/download/vue-i18n-9.2.0-beta.23.tgz}
|
||||
id: rg.cnpmjs.org/vue-i18n/9.2.0-beta.23
|
||||
name: vue-i18n
|
||||
version: 9.2.0-beta.23
|
||||
engines: {node: '>= 12'}
|
||||
peerDependencies:
|
||||
vue: ^3.0.0
|
||||
dependencies:
|
||||
'@intlify/core-base': rg.cnpmjs.org/@intlify/core-base/9.2.0-beta.23
|
||||
'@intlify/shared': rg.cnpmjs.org/@intlify/shared/9.2.0-beta.23
|
||||
'@intlify/vue-devtools': rg.cnpmjs.org/@intlify/vue-devtools/9.2.0-beta.23
|
||||
'@vue/devtools-api': rg.cnpmjs.org/@vue/devtools-api/6.0.0-beta.20.1
|
||||
vue: rg.cnpmjs.org/vue/3.2.24
|
||||
dev: false
|
||||
|
||||
rg.cnpmjs.org/vue-router/4.0.12_vue@3.2.24:
|
||||
resolution: {integrity: sha1-jceSzd9bsavMOQj5BkE23n4TxGA=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/vue-router/download/vue-router-4.0.12.tgz}
|
||||
id: rg.cnpmjs.org/vue-router/4.0.12
|
||||
|
3
src/components/LangSelect/index.ts
Normal file
3
src/components/LangSelect/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import LangSelect from './index.vue';
|
||||
|
||||
export { LangSelect };
|
28
src/components/LangSelect/index.vue
Normal file
28
src/components/LangSelect/index.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<n-dropdown
|
||||
trigger="hover"
|
||||
@select="handleSelect"
|
||||
:show-arrow="true"
|
||||
:options="options"
|
||||
>
|
||||
<n-button quaternary>
|
||||
<n-icon size="20" :depth="1">
|
||||
<LanguageIcon />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useLangStore } from '@/store/modules/langStore/langStore'
|
||||
import { Language as LanguageIcon } from '@vicons/ionicons5'
|
||||
import { langList } from '@/settings/designSetting'
|
||||
import { LangEnum } from '@/enums/styleEnum'
|
||||
|
||||
const langStore = useLangStore()
|
||||
const options = langList
|
||||
|
||||
const handleSelect = (key: LangEnum) => {
|
||||
langStore.changeLang(key)
|
||||
}
|
||||
</script>
|
@ -1,12 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-button quaternary @click="changeTheme">
|
||||
<n-icon size="20" :depth="1">
|
||||
<MoonIcon v-if="designStore.darkTheme" />
|
||||
<SunnyIcon v-else />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
<n-button quaternary @click="changeTheme">
|
||||
<n-icon size="20" :depth="1">
|
||||
<MoonIcon v-if="designStore.darkTheme" />
|
||||
<SunnyIcon v-else />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -1,4 +1,9 @@
|
||||
export enum ThemeEnum {
|
||||
dark = 'dark',
|
||||
light = 'light'
|
||||
}
|
||||
}
|
||||
|
||||
export enum LangEnum {
|
||||
zh = 'zh',
|
||||
en = 'en'
|
||||
}
|
||||
|
12
src/i18n/en/index.ts
Normal file
12
src/i18n/en/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import login from './login'
|
||||
|
||||
const global = {
|
||||
doc_addr: "Doc Address",
|
||||
form_account: "Please enter your account or email",
|
||||
form_password: "Please enter your password"
|
||||
}
|
||||
|
||||
export default {
|
||||
global: global,
|
||||
login: login
|
||||
}
|
7
src/i18n/en/login.ts
Normal file
7
src/i18n/en/login.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
desc: "Log in to GoView",
|
||||
form_auto: "Sign in automatically",
|
||||
form_button: "Login",
|
||||
login_success: "Login success",
|
||||
login_message: "Please complete the letter",
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
//语言
|
||||
import { lang } from '@/settings/designSetting'
|
||||
import { createI18n } from 'vue-i18n' //引入vue-i18n组件
|
||||
import { getLocalStorage } from '@/utils/index'
|
||||
import { GO_LANG_SELECT } from '@/settings/storageConst'
|
||||
import zh from './zh/index'
|
||||
import en from './en/index'
|
||||
|
||||
const lang_storage = getLocalStorage(GO_LANG_SELECT)
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: lang_storage || lang,
|
||||
globalInjection: true,
|
||||
messages: {
|
||||
zh: zh,
|
||||
en: en
|
||||
}
|
||||
})
|
||||
|
||||
export default i18n
|
12
src/i18n/zh/index.ts
Normal file
12
src/i18n/zh/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import login from './login'
|
||||
|
||||
const global = {
|
||||
doc_addr: "文档地址",
|
||||
form_account: "请输入账号或邮箱",
|
||||
form_password: "请输入密码",
|
||||
}
|
||||
|
||||
export default {
|
||||
global: global,
|
||||
login: login
|
||||
}
|
7
src/i18n/zh/login.ts
Normal file
7
src/i18n/zh/login.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
desc: "登录 GoView",
|
||||
form_auto: "自动登录",
|
||||
form_button: "登录",
|
||||
login_success: "登录成功",
|
||||
login_message: "请填写完整信息",
|
||||
}
|
@ -2,12 +2,17 @@
|
||||
<div class="go-header">
|
||||
<header class="go-header-box">
|
||||
<div class="li">
|
||||
<slot name="left"></slot>
|
||||
<n-space>
|
||||
<slot name="left"></slot>
|
||||
</n-space>
|
||||
</div>
|
||||
<div class="ri">
|
||||
<slot name="right">
|
||||
<ThemeSelect />
|
||||
</slot>
|
||||
<n-space>
|
||||
<slot name="right">
|
||||
<LangSelect />
|
||||
<ThemeSelect />
|
||||
</slot>
|
||||
</n-space>
|
||||
</div>
|
||||
</header>
|
||||
<n-divider class="go-header-divider" />
|
||||
@ -16,6 +21,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ThemeSelect } from '@/components/ThemeSelect'
|
||||
import { LangSelect } from '@/components/LangSelect'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
44
src/main.ts
44
src/main.ts
@ -1,38 +1,42 @@
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import router, { setupRouter } from '@/router';
|
||||
import { setupStore } from '@/store';
|
||||
import { setupNaive, setupDirectives } from '@/plugins';
|
||||
import { AppProvider } from '@/components/Application';
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router, { setupRouter } from '@/router'
|
||||
import i18n from '@/i18n/index'
|
||||
import { setupStore } from '@/store'
|
||||
import { setupNaive, setupDirectives } from '@/plugins'
|
||||
import { AppProvider } from '@/components/Application'
|
||||
import { setHtmlTheme } from '@/utils/style'
|
||||
|
||||
async function appInit() {
|
||||
const appProvider = createApp(AppProvider);
|
||||
const appProvider = createApp(AppProvider)
|
||||
|
||||
const app = createApp(App);
|
||||
const app = createApp(App)
|
||||
|
||||
// 注册全局常用的 naive-ui 组件
|
||||
setupNaive(app);
|
||||
setupNaive(app)
|
||||
|
||||
// 注册全局自定义指令,如:v-permission权限指令
|
||||
setupDirectives(app);
|
||||
setupDirectives(app)
|
||||
|
||||
// 挂载状态管理
|
||||
setupStore(app);
|
||||
setupStore(app)
|
||||
|
||||
// 处理主题色
|
||||
setHtmlTheme()
|
||||
|
||||
//优先挂载一下 Provider 解决路由守卫,Axios中可使用,Dialog,Message 等之类组件
|
||||
appProvider.mount('#appProvider', true);
|
||||
// 优先挂载一下 Provider 解决路由守卫,Axios中可使用,Dialog,Message 等之类组件
|
||||
appProvider.mount('#appProvider', true)
|
||||
|
||||
// 挂载路由
|
||||
await setupRouter(app);
|
||||
await setupRouter(app)
|
||||
|
||||
// 路由准备就绪后挂载APP实例
|
||||
await router.isReady();
|
||||
await router.isReady()
|
||||
|
||||
app.mount('#app', true);
|
||||
// Store 准备就绪后处理主题色
|
||||
setHtmlTheme()
|
||||
|
||||
// 语言注册
|
||||
app.use(i18n)
|
||||
|
||||
app.mount('#app', true)
|
||||
}
|
||||
|
||||
void appInit();
|
||||
void appInit()
|
||||
|
@ -1,4 +1,21 @@
|
||||
// app theme preset color
|
||||
import { LangEnum } from '@/enums/styleEnum'
|
||||
|
||||
// 默认语言
|
||||
export const lang = LangEnum.zh
|
||||
|
||||
// 语言数组
|
||||
export const langList = [
|
||||
{
|
||||
label: '中文',
|
||||
key: LangEnum.zh
|
||||
},
|
||||
{
|
||||
label: 'English',
|
||||
key: LangEnum.en
|
||||
}
|
||||
]
|
||||
|
||||
// 主体色
|
||||
export const appThemeList: string[] = [
|
||||
'#2d8cf0',
|
||||
'#0960bd',
|
||||
@ -17,22 +34,20 @@ export const appThemeList: string[] = [
|
||||
'#78DEC7',
|
||||
'#1768AC',
|
||||
'#FB9300',
|
||||
'#FC5404',
|
||||
];
|
||||
'#FC5404'
|
||||
]
|
||||
|
||||
export const theme = {
|
||||
darkThemeName: 'dark',
|
||||
lightThemeName: 'light',
|
||||
//深色主题
|
||||
darkTheme: true,
|
||||
//系统主题色
|
||||
appTheme: '#63e2b7',
|
||||
//系统内置主题色列表
|
||||
appThemeList,
|
||||
};
|
||||
appThemeList
|
||||
}
|
||||
|
||||
// 修改边框圆角
|
||||
export const borderRadius = '8px'
|
||||
|
||||
// 轮播间隔
|
||||
export const carouselInterval = 5000
|
||||
export const carouselInterval = 4000
|
||||
|
4
src/settings/storageConst.ts
Normal file
4
src/settings/storageConst.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export const GO_ACCESS_TOKEN = 'GO-ACCESS-TOKEN' // 用户token
|
||||
export const GO_CURRENT_USER = 'GO-CURRENT-USER' // 当前用户信息
|
||||
export const GO_LANG_SELECT = 'GO-LANG-SELECT' // 当前选择的语言类型
|
||||
export const GO_Theme_SELECT = 'GO-Theme-SELECT' // 当前选择的主题
|
@ -1,6 +1,10 @@
|
||||
import { ThemeEnum } from '@/enums/styleEnum'
|
||||
|
||||
export interface DesignStateType {
|
||||
//深色主题
|
||||
// 是否是深色主题
|
||||
darkTheme: boolean;
|
||||
// 主题名称
|
||||
themeName: ThemeEnum;
|
||||
//系统风格
|
||||
appTheme: string;
|
||||
//系统内置风格
|
||||
|
@ -1,34 +1,47 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { store } from '@/store';
|
||||
import { theme } from '@/settings/designSetting';
|
||||
const { darkTheme, appTheme, appThemeList } = theme;
|
||||
import { defineStore } from 'pinia'
|
||||
import { store } from '@/store'
|
||||
import { theme } from '@/settings/designSetting'
|
||||
import { DesignStateType } from './designStore.d'
|
||||
import { setLocalStorage, getLocalStorage } from '@/utils/index'
|
||||
import { GO_Theme_SELECT } from '@/settings/storageConst'
|
||||
import { ThemeEnum } from '@/enums/styleEnum'
|
||||
|
||||
const { darkTheme, appTheme, appThemeList } = theme
|
||||
const storageThemeName = getLocalStorage(GO_Theme_SELECT)
|
||||
|
||||
export const useDesignStore = defineStore({
|
||||
id: 'useDesignStore',
|
||||
state: (): DesignStateType => ({
|
||||
darkTheme,
|
||||
// 是否暗黑
|
||||
darkTheme: storageThemeName === ThemeEnum.dark,
|
||||
// 主题名称
|
||||
themeName:
|
||||
storageThemeName || (darkTheme && ThemeEnum.dark) || ThemeEnum.light,
|
||||
// 颜色色号
|
||||
appTheme,
|
||||
appThemeList,
|
||||
// 颜色列表
|
||||
appThemeList
|
||||
}),
|
||||
getters: {
|
||||
getDarkTheme(): boolean {
|
||||
return this.darkTheme;
|
||||
getDarkTheme(e): boolean {
|
||||
return this.darkTheme
|
||||
},
|
||||
getAppTheme(): string {
|
||||
return this.appTheme;
|
||||
return this.appTheme
|
||||
},
|
||||
getAppThemeList(): string[] {
|
||||
return this.appThemeList;
|
||||
},
|
||||
return this.appThemeList
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
changeTheme():void {
|
||||
changeTheme(): void {
|
||||
this.darkTheme = !this.darkTheme
|
||||
this.themeName = this.darkTheme ? ThemeEnum.dark : ThemeEnum.light
|
||||
setLocalStorage(GO_Theme_SELECT, this.themeName)
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
export function useDesignSettingWithOut() {
|
||||
return useDesignStore(store);
|
||||
return useDesignStore(store)
|
||||
}
|
||||
|
5
src/store/modules/langStore/langStore.d.ts
vendored
Normal file
5
src/store/modules/langStore/langStore.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { LangEnum } from '@/enums/styleEnum'
|
||||
export interface LangStateType {
|
||||
// 当前语言
|
||||
lang: LangEnum
|
||||
}
|
26
src/store/modules/langStore/langStore.ts
Normal file
26
src/store/modules/langStore/langStore.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { lang } from '@/settings/designSetting'
|
||||
import { LangStateType } from './langStore.d'
|
||||
import { LangEnum } from '@/enums/styleEnum'
|
||||
import i18n from '@/i18n/index'
|
||||
import { setLocalStorage } from '@/utils/index'
|
||||
import { GO_LANG_SELECT } from '@/settings/storageConst'
|
||||
|
||||
export const useLangStore = defineStore({
|
||||
id: 'useLangStore',
|
||||
state: (): LangStateType => ({
|
||||
lang
|
||||
}),
|
||||
getters: {
|
||||
getLang(): LangEnum {
|
||||
return this.lang
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
changeLang(lang: LangEnum): void {
|
||||
this.lang = lang
|
||||
i18n.global.locale = lang
|
||||
setLocalStorage(GO_LANG_SELECT, lang)
|
||||
}
|
||||
}
|
||||
})
|
@ -1,2 +0,0 @@
|
||||
export const ACCESS_TOKEN = 'ACCESS-TOKEN'; // 用户token
|
||||
export const CURRENT_USER = 'CURRENT-USER'; // 当前用户信息
|
@ -1,5 +1,7 @@
|
||||
import { DesignStateType } from '@/store/modules/designStore/designStore.d';
|
||||
import { LangStateType } from '@/store/modules/langStore/langStore.d';
|
||||
|
||||
export interface allStore {
|
||||
useDesignStore: DesignStateType;
|
||||
useLangStore: LangStateType;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { h } from 'vue';
|
||||
import { NIcon } from 'naive-ui';
|
||||
import { h } from 'vue'
|
||||
import { NIcon } from 'naive-ui'
|
||||
|
||||
/**
|
||||
* * 生成一个用不重复的ID
|
||||
@ -7,24 +7,76 @@ import { NIcon } from 'naive-ui';
|
||||
*/
|
||||
export function getUUID(randomLength: number) {
|
||||
return Number(
|
||||
Math.random()
|
||||
.toString()
|
||||
.substr(2, randomLength) + Date.now()
|
||||
).toString(36);
|
||||
Math.random().toString().substr(2, randomLength) + Date.now()
|
||||
).toString(36)
|
||||
}
|
||||
|
||||
/**
|
||||
* * render 图标
|
||||
*/
|
||||
export const renderIcon = (icon: typeof NIcon) => {
|
||||
return () => h(NIcon, null, { default: () => h(icon) });
|
||||
return () => h(NIcon, null, { default: () => h(icon) })
|
||||
}
|
||||
|
||||
/**
|
||||
* * 处理 vite 中无法使用 require 的问题
|
||||
* @param name
|
||||
* @returns
|
||||
* @param name
|
||||
* @returns url
|
||||
*/
|
||||
export const requireUrl = (path: string, name: string) => {
|
||||
return new URL(`${path}/${name}`, import.meta.url).href
|
||||
}
|
||||
|
||||
/**
|
||||
* * 存储本地会话数据
|
||||
* @param k 键名
|
||||
* @param v 键值
|
||||
* @returns RemovableRef
|
||||
*/
|
||||
export const setLocalStorage = <T>(k: string, v: T) => {
|
||||
try {
|
||||
window.localStorage.setItem(k, JSON.stringify(v))
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * 获取本地会话数据
|
||||
* @returns any
|
||||
*/
|
||||
export const getLocalStorage: (k: string) => any = (k: string) => {
|
||||
const item = window.localStorage.getItem(k)
|
||||
try {
|
||||
return item ? JSON.parse(item) : item
|
||||
} catch (err) {
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * 存储临时会话数据
|
||||
* @param k 键名
|
||||
* @param v 键值
|
||||
* @returns RemovableRef
|
||||
*/
|
||||
export const setSessionStorage = <T>(k: string, v: T) => {
|
||||
try {
|
||||
window.sessionStorage.setItem(k, JSON.stringify(v))
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * 获取临时会话数据
|
||||
* @returns any
|
||||
*/
|
||||
export const getSessionStorage: (k: string) => any = (k: string) => {
|
||||
const item = window.sessionStorage.getItem(k)
|
||||
try {
|
||||
return item ? JSON.parse(item) : item
|
||||
} catch (err) {
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,31 @@
|
||||
import { ResultEnum } from "@/enums/httpEnum"
|
||||
import { ErrorPageNameMap } from "@/enums/pageEnum"
|
||||
import router from '@/router';
|
||||
import { ResultEnum } from '@/enums/httpEnum'
|
||||
import { ErrorPageNameMap } from '@/enums/pageEnum'
|
||||
import router from '@/router'
|
||||
|
||||
/**
|
||||
* * 错误页重定向
|
||||
* @param icon
|
||||
* @returns
|
||||
* @param icon
|
||||
* @returns
|
||||
*/
|
||||
export const redirectErrorPage = (code: ResultEnum) => {
|
||||
if(!code) return false
|
||||
if (!code) return false
|
||||
const pageName = ErrorPageNameMap.get(code)
|
||||
if(!pageName) return false
|
||||
if (!pageName) return false
|
||||
routerTurnByName(pageName)
|
||||
}
|
||||
|
||||
/**
|
||||
* * 根据名字跳转路由
|
||||
* @param pageName
|
||||
* @param pageName
|
||||
*/
|
||||
export const routerTurnByName = (pageName: string) => {
|
||||
export const routerTurnByName = (pageName: string, isReplace?: boolean) => {
|
||||
if (isReplace) {
|
||||
router.replace({
|
||||
name: pageName
|
||||
})
|
||||
return
|
||||
}
|
||||
router.push({
|
||||
name: pageName
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { theme as themeEnum } from '@/settings/designSetting'
|
||||
|
||||
export const setHtmlTheme = (themeName?: string) => {
|
||||
const e = window.document.documentElement
|
||||
if (themeName) {
|
||||
e.setAttribute("data-theme", themeName);
|
||||
e.setAttribute('data-theme', themeName)
|
||||
return
|
||||
}
|
||||
const designStore = useDesignStore()
|
||||
e.setAttribute("data-theme", designStore.getDarkTheme ? themeEnum.darkThemeName : themeEnum.lightThemeName);
|
||||
}
|
||||
e.setAttribute('data-theme', designStore.themeName)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
<Header>
|
||||
<template #left></template>
|
||||
<template #right>
|
||||
<LangSelect />
|
||||
<ThemeSelect />
|
||||
</template>
|
||||
</Header>
|
||||
@ -28,14 +29,14 @@
|
||||
:key="i"
|
||||
class="go-login-carousel-img"
|
||||
:src="getImageUrl(item, 'login')"
|
||||
alt="展示图片"
|
||||
alt="image"
|
||||
/>
|
||||
</n-carousel>
|
||||
</div>
|
||||
<div class="login-account">
|
||||
<div class="login-account-container">
|
||||
<n-collapse-transition :appear="true" :show="show">
|
||||
<n-card class="login-account-card" title="登录 GoView">
|
||||
<n-card class="login-account-card" :title="$t('login.desc')">
|
||||
<div class="login-account-top">
|
||||
<img
|
||||
class="login-account-top-logo"
|
||||
@ -53,7 +54,7 @@
|
||||
<n-form-item path="username">
|
||||
<n-input
|
||||
v-model:value="formInline.username"
|
||||
placeholder="请输入用户名"
|
||||
:placeholder="$t('global.form_account')"
|
||||
>
|
||||
<template #prefix>
|
||||
<n-icon size="18">
|
||||
@ -67,7 +68,7 @@
|
||||
v-model:value="formInline.password"
|
||||
type="password"
|
||||
show-password-toggle
|
||||
placeholder="请输入密码"
|
||||
:placeholder="$t('global.form_password')"
|
||||
>
|
||||
<template #prefix>
|
||||
<n-icon size="18">
|
||||
@ -80,7 +81,7 @@
|
||||
<div class="flex justify-between">
|
||||
<div class="flex-initial">
|
||||
<n-checkbox v-model:checked="autoLogin">
|
||||
自动登录
|
||||
{{ $t('login.form_auto') }}
|
||||
</n-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
@ -93,7 +94,7 @@
|
||||
:loading="loading"
|
||||
block
|
||||
>
|
||||
登录
|
||||
{{ $t('login.form_button') }}
|
||||
</n-button>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
@ -104,7 +105,7 @@
|
||||
</div>
|
||||
|
||||
<div class="go-login-box-footer">
|
||||
<n-a>文档地址: </n-a>
|
||||
<n-a>{{ $t('global.doc_addr') }}: </n-a>
|
||||
<n-a italic href="http://www.mtruning.club/">
|
||||
http://www.mtruning.club/
|
||||
</n-a>
|
||||
@ -116,16 +117,20 @@
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import {
|
||||
PersonOutline as PersonOutlineIcon,
|
||||
LockClosedOutline as LockClosedOutlineIcon
|
||||
} from '@vicons/ionicons5'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { requireUrl } from '@/utils/index'
|
||||
import { routerTurnByName } from '@/utils/page'
|
||||
import shuffle from 'lodash/shuffle'
|
||||
import { carouselInterval } from '@/settings/designSetting'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { ThemeSelect } from '@/components/ThemeSelect'
|
||||
import { LangSelect } from '@/components/LangSelect'
|
||||
import { Header } from '@/layout/components/Header'
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
import {
|
||||
PersonOutline as PersonOutlineIcon,
|
||||
LockClosedOutline as LockClosedOutlineIcon
|
||||
} from '@vicons/ionicons5'
|
||||
|
||||
interface FormState {
|
||||
username: string
|
||||
@ -139,6 +144,7 @@ const loading = ref(false)
|
||||
const autoLogin = ref(true)
|
||||
const show = ref(false)
|
||||
const designStore = useDesignStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
@ -152,8 +158,16 @@ const formInline = reactive({
|
||||
})
|
||||
|
||||
const rules = {
|
||||
username: { required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
password: { required: true, message: '请输入密码', trigger: 'blur' }
|
||||
username: {
|
||||
required: true,
|
||||
message: t('global.form_account'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
password: {
|
||||
required: true,
|
||||
message: t('global.form_password'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
}
|
||||
|
||||
// 定时器
|
||||
@ -194,11 +208,10 @@ const handleSubmit = (e: Event) => {
|
||||
if (!errors) {
|
||||
const { username, password } = formInline
|
||||
loading.value = true
|
||||
|
||||
message.success('登录成功!')
|
||||
router.replace('/')
|
||||
message.success(`${t('login.login_success')}!`)
|
||||
routerTurnByName(PageEnum.BASE_HOME_NAME, true)
|
||||
} else {
|
||||
message.error('请填写完整信息,并且进行验证码校验')
|
||||
message.error(`${t('login.login_message')}!`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
1
types/config.d.ts
vendored
1
types/config.d.ts
vendored
@ -1 +0,0 @@
|
||||
|
Loading…
Reference in New Issue
Block a user