chore(projects): Merge branch 'main' into example

This commit is contained in:
Soybean 2024-07-30 17:26:42 +08:00
commit e7cd34ec37
26 changed files with 1478 additions and 855 deletions

View File

@ -1,6 +1,40 @@
# Changelog # Changelog
## [v1.3.2](https://github.com/honghuangdc/soybean-admin/compare/v1.3.1...v1.3.2) (2024-07-30)
###    🚀 Features
- **projects**:
- add color fading mode.close #567 &nbsp;-&nbsp; by @Azir-11 in https://github.com/honghuangdc/soybean-admin/issues/569 and https://github.com/honghuangdc/soybean-admin/issues/567 [<samp>(4dde4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4dde4c2)
- add full screen watermark. close#571 &nbsp;-&nbsp; by @paynezhuang in https://github.com/honghuangdc/soybean-admin/issues/573 and https://github.com/honghuangdc/soybean-admin/issues/571 [<samp>(ea8aa)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ea8aa6c)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**: fix vertical-mix menu selected &nbsp;-&nbsp; by @honghuangdc [<samp>(59f07)</samp>](https://github.com/honghuangdc/soybean-admin/commit/59f07d8)
### &nbsp;&nbsp;&nbsp;🛠 Optimizations
- **projects**:
- add type WatermarkProps &nbsp;-&nbsp; by @honghuangdc [<samp>(f26d0)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f26d0a6)
- remove home NAlert closable &nbsp;-&nbsp; by @honghuangdc [<samp>(98b75)</samp>](https://github.com/honghuangdc/soybean-admin/commit/98b75c2)
- optimize response code comparison &nbsp;-&nbsp; by @honghuangdc [<samp>(cf67d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cf67d55)
- **types**:
- remove useless types. &nbsp;-&nbsp; by **Azir** [<samp>(eed61)</samp>](https://github.com/honghuangdc/soybean-admin/commit/eed617f)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**: update CHANGELOG &nbsp;-&nbsp; by @honghuangdc [<samp>(d3759)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d37591d)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **deps**: update deps &nbsp;-&nbsp; by @honghuangdc [<samp>(993e9)</samp>](https://github.com/honghuangdc/soybean-admin/commit/993e9ca)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;[![paynezhuang](https://github.com/paynezhuang.png?size=48)](https://github.com/paynezhuang)&nbsp;&nbsp;[![Azir-11](https://github.com/Azir-11.png?size=48)](https://github.com/Azir-11)&nbsp;&nbsp;
[Azir](mailto:2075125282@qq.com),&nbsp;
## [v1.3.1](https://github.com/honghuangdc/soybean-admin/compare/v1.3.0...v1.3.1) (2024-07-22) ## [v1.3.1](https://github.com/honghuangdc/soybean-admin/compare/v1.3.0...v1.3.1) (2024-07-22)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes ### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes

View File

@ -1,5 +1,27 @@
# 更新日志 # 更新日志
## [v1.3.1](https://github.com/honghuangdc/soybean-admin/compare/v1.3.0...v1.3.1) (2024-07-22)
### &nbsp;&nbsp;&nbsp;🐞 Bug 修复
- **项目**:
- 修复顶部菜单混合和反向模式下侧边栏宽度异常的问题 &nbsp;-&nbsp;@Azir-11 在 https://github.com/honghuangdc/soybean-admin/issues/562 修复 [<samp>(c4695)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c469512)
- 修复水平混合菜单反转问题。修复 #563 &nbsp;-&nbsp;@honghuangdc 在 https://github.com/honghuangdc/soybean-admin/issues/563 修复 [<samp>(4e55b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4e55b0e)
- 修复当布局来自移动端时垂直菜单不渲染的问题 &nbsp;-&nbsp;@honghuangdc 修复 [<samp>(84027)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8402734)
### &nbsp;&nbsp;&nbsp;📖 文档
- **项目**: 更新更新日志 &nbsp;-&nbsp;@honghuangdc 更新 [<samp>(613c8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/613c836)
### &nbsp;&nbsp;&nbsp;🎨 样式
- **其他**: 修改灰度模式的中文名称 &nbsp;-&nbsp;**Azir** 修改 [<samp>(53770)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5377002)
### &nbsp;&nbsp;&nbsp;❤️ 贡献者
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;[![Azir-11](https://github.com/Azir-11.png?size=48)](https://github.com/Azir-11)&nbsp;&nbsp;
[Azir](mailto:2075125282@qq.com),&nbsp;
## [v1.3.0](https://github.com/soybeanjs/soybean-admin/compare/v1.2.8...v1.3.0) (2024-07-22) ## [v1.3.0](https://github.com/soybeanjs/soybean-admin/compare/v1.2.8...v1.3.0) (2024-07-22)

View File

@ -1,7 +1,7 @@
{ {
"name": "soybean-admin", "name": "soybean-admin",
"type": "module", "type": "module",
"version": "1.3.1", "version": "1.3.2",
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。", "description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
"author": { "author": {
"name": "Soybean", "name": "Soybean",
@ -65,13 +65,13 @@
"lodash-es": "4.17.21", "lodash-es": "4.17.21",
"naive-ui": "2.39.0", "naive-ui": "2.39.0",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"pinia": "2.1.7", "pinia": "2.2.0",
"pinyin-pro": "3.23.1", "pinyin-pro": "3.23.1",
"print-js": "1.6.0", "print-js": "1.6.0",
"swiper": "11.1.5", "swiper": "11.1.5",
"tailwind-merge": "2.4.0", "tailwind-merge": "2.4.0",
"vditor": "3.10.4", "vditor": "3.10.4",
"vue": "3.4.33", "vue": "3.4.34",
"vue-draggable-plus": "0.5.2", "vue-draggable-plus": "0.5.2",
"vue-i18n": "9.13.1", "vue-i18n": "9.13.1",
"vue-pdf-embed": "2.1.0", "vue-pdf-embed": "2.1.0",
@ -83,38 +83,38 @@
"devDependencies": { "devDependencies": {
"@amap/amap-jsapi-types": "0.0.15", "@amap/amap-jsapi-types": "0.0.15",
"@elegant-router/vue": "0.3.7", "@elegant-router/vue": "0.3.7",
"@iconify/json": "2.2.230", "@iconify/json": "2.2.232",
"@sa/scripts": "workspace:*", "@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*", "@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.7", "@soybeanjs/eslint-config": "1.3.7",
"@types/bmapgl": "0.0.7", "@types/bmapgl": "0.0.7",
"@types/dompurify": "3.0.5", "@types/dompurify": "3.0.5",
"@types/lodash-es": "4.17.12", "@types/lodash-es": "4.17.12",
"@types/node": "20.14.11", "@types/node": "22.0.0",
"@types/nprogress": "0.2.3", "@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.61.5", "@unocss/eslint-config": "0.61.7",
"@unocss/preset-icons": "0.61.5", "@unocss/preset-icons": "0.61.7",
"@unocss/preset-uno": "0.61.5", "@unocss/preset-uno": "0.61.7",
"@unocss/transformer-directives": "0.61.5", "@unocss/transformer-directives": "0.61.7",
"@unocss/transformer-variant-group": "0.61.5", "@unocss/transformer-variant-group": "0.61.7",
"@unocss/vite": "0.61.5", "@unocss/vite": "0.61.7",
"@vitejs/plugin-vue": "5.0.5", "@vitejs/plugin-vue": "5.1.1",
"@vitejs/plugin-vue-jsx": "4.0.0", "@vitejs/plugin-vue-jsx": "4.0.0",
"eslint": "9.7.0", "eslint": "9.8.0",
"eslint-plugin-vue": "9.27.0", "eslint-plugin-vue": "9.27.0",
"lint-staged": "15.2.7", "lint-staged": "15.2.7",
"sass": "1.77.8", "sass": "1.77.8",
"simple-git-hooks": "2.11.1", "simple-git-hooks": "2.11.1",
"tsx": "4.16.2", "tsx": "4.16.2",
"typescript": "5.5.3", "typescript": "5.5.4",
"unplugin-icons": "0.19.0", "unplugin-icons": "0.19.1",
"unplugin-vue-components": "0.27.3", "unplugin-vue-components": "0.27.3",
"vite": "5.3.4", "vite": "5.3.5",
"vite-plugin-progress": "0.0.7", "vite-plugin-progress": "0.0.7",
"vite-plugin-svg-icons": "2.0.1", "vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "7.3.6", "vite-plugin-vue-devtools": "7.3.7",
"vue-eslint-parser": "9.4.3", "vue-eslint-parser": "9.4.3",
"vue-tsc": "2.0.26" "vue-tsc": "2.0.29"
}, },
"simple-git-hooks": { "simple-git-hooks": {
"commit-msg": "pnpm sa git-commit-verify", "commit-msg": "pnpm sa git-commit-verify",

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/axios", "name": "@sa/axios",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },
@ -12,7 +12,7 @@
"dependencies": { "dependencies": {
"@sa/utils": "workspace:*", "@sa/utils": "workspace:*",
"axios": "1.7.2", "axios": "1.7.2",
"axios-retry": "4.4.1", "axios-retry": "4.4.2",
"qs": "6.12.3" "qs": "6.12.3"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/color", "name": "@sa/color",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/hooks", "name": "@sa/hooks",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/materials", "name": "@sa/materials",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/fetch", "name": "@sa/fetch",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/scripts", "name": "@sa/scripts",
"version": "1.3.1", "version": "1.3.2",
"bin": { "bin": {
"sa": "./bin.ts" "sa": "./bin.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/uno-preset", "name": "@sa/uno-preset",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@sa/utils", "name": "@sa/utils",
"version": "1.3.1", "version": "1.3.2",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import { NConfigProvider, darkTheme } from 'naive-ui'; import { NConfigProvider, darkTheme } from 'naive-ui';
import type { WatermarkProps } from 'naive-ui';
import { useAppStore } from './store/modules/app'; import { useAppStore } from './store/modules/app';
import { useThemeStore } from './store/modules/theme'; import { useThemeStore } from './store/modules/theme';
import { naiveDateLocales, naiveLocales } from './locales/naive'; import { naiveDateLocales, naiveLocales } from './locales/naive';
@ -21,6 +22,22 @@ const naiveLocale = computed(() => {
const naiveDateLocale = computed(() => { const naiveDateLocale = computed(() => {
return naiveDateLocales[appStore.locale]; return naiveDateLocales[appStore.locale];
}); });
const watermarkProps = computed<WatermarkProps>(() => {
return {
content: themeStore.watermark.text,
cross: true,
fullscreen: true,
fontSize: 16,
lineHeight: 16,
width: 384,
height: 384,
xOffset: 12,
yOffset: 60,
rotate: -15,
zIndex: 9999
};
});
</script> </script>
<template> <template>
@ -33,6 +50,7 @@ const naiveDateLocale = computed(() => {
> >
<AppProvider> <AppProvider>
<RouterView class="bg-layout" /> <RouterView class="bg-layout" />
<NWatermark v-if="themeStore.watermark.visible" v-bind="watermarkProps" />
</AppProvider> </AppProvider>
</NConfigProvider> </NConfigProvider>
</template> </template>

View File

@ -117,6 +117,7 @@ watch(
<NMenu <NMenu
v-model:expanded-keys="expandedKeys" v-model:expanded-keys="expandedKeys"
mode="vertical" mode="vertical"
:value="selectedKey"
:options="childLevelMenus" :options="childLevelMenus"
:collapsed="appStore.siderCollapse" :collapsed="appStore.siderCollapse"
:collapsed-width="themeStore.sider.collapsedWidth" :collapsed-width="themeStore.sider.collapsedWidth"

View File

@ -25,6 +25,10 @@ function handleGrayscaleChange(value: boolean) {
themeStore.setGrayscale(value); themeStore.setGrayscale(value);
} }
function handleColourWeaknessChange(value: boolean) {
themeStore.setColourWeakness(value);
}
const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layout.mode.includes('vertical')); const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layout.mode.includes('vertical'));
</script> </script>
@ -53,6 +57,9 @@ const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layo
<SettingItem :label="$t('theme.grayscale')"> <SettingItem :label="$t('theme.grayscale')">
<NSwitch :value="themeStore.grayscale" @update:value="handleGrayscaleChange" /> <NSwitch :value="themeStore.grayscale" @update:value="handleGrayscaleChange" />
</SettingItem> </SettingItem>
<SettingItem :label="$t('theme.colourWeakness')">
<NSwitch :value="themeStore.colourWeakness" @update:value="handleColourWeaknessChange" />
</SettingItem>
</div> </div>
</template> </template>

View File

@ -101,6 +101,19 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
> >
<NSwitch v-model:value="themeStore.footer.right" /> <NSwitch v-model:value="themeStore.footer.right" />
</SettingItem> </SettingItem>
<SettingItem key="8" :label="$t('theme.watermark.visible')">
<NSwitch v-model:value="themeStore.watermark.visible" />
</SettingItem>
<SettingItem v-if="themeStore.watermark.visible" key="8-1" :label="$t('theme.watermark.text')">
<NInput
v-model:value="themeStore.watermark.text"
autosize
type="text"
size="small"
class="w-120px"
placeholder="SoybeanAdmin"
/>
</SettingItem>
</TransitionGroup> </TransitionGroup>
</template> </template>

View File

@ -65,6 +65,7 @@ const local: App.I18n.Schema = {
auto: 'Follow System' auto: 'Follow System'
}, },
grayscale: 'Grayscale', grayscale: 'Grayscale',
colourWeakness: 'Colour Weakness',
layoutMode: { layoutMode: {
title: 'Layout Mode', title: 'Layout Mode',
vertical: 'Vertical Menu Mode', vertical: 'Vertical Menu Mode',
@ -134,6 +135,10 @@ const local: App.I18n.Schema = {
height: 'Footer Height', height: 'Footer Height',
right: 'Right Footer' right: 'Right Footer'
}, },
watermark: {
visible: 'Watermark Full Screen Visible',
text: 'Watermark Text'
},
themeDrawerTitle: 'Theme Configuration', themeDrawerTitle: 'Theme Configuration',
pageFunTitle: 'Page Function', pageFunTitle: 'Page Function',
configOperation: { configOperation: {

View File

@ -65,6 +65,7 @@ const local: App.I18n.Schema = {
auto: '跟随系统' auto: '跟随系统'
}, },
grayscale: '灰色模式', grayscale: '灰色模式',
colourWeakness: '色弱模式',
layoutMode: { layoutMode: {
title: '布局模式', title: '布局模式',
vertical: '左侧菜单模式', vertical: '左侧菜单模式',
@ -134,6 +135,10 @@ const local: App.I18n.Schema = {
height: '底部高度', height: '底部高度',
right: '底部局右' right: '底部局右'
}, },
watermark: {
visible: '显示全屏水印',
text: '水印文本'
},
themeDrawerTitle: '主题配置', themeDrawerTitle: '主题配置',
pageFunTitle: '页面功能', pageFunTitle: '页面功能',
configOperation: { configOperation: {

View File

@ -35,6 +35,7 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
}, },
async onBackendFail(response, instance) { async onBackendFail(response, instance) {
const authStore = useAuthStore(); const authStore = useAuthStore();
const responseCode = String(response.data.code);
function handleLogout() { function handleLogout() {
authStore.resetStore(); authStore.resetStore();
@ -49,14 +50,14 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
// when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page // when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page
const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || []; const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || [];
if (logoutCodes.includes(response.data.code)) { if (logoutCodes.includes(responseCode)) {
handleLogout(); handleLogout();
return null; return null;
} }
// when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal // when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || []; const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
if (modalLogoutCodes.includes(response.data.code) && !request.state.errMsgStack?.includes(response.data.msg)) { if (modalLogoutCodes.includes(responseCode) && !request.state.errMsgStack?.includes(response.data.msg)) {
request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg]; request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg];
// prevent the user from refreshing the page // prevent the user from refreshing the page
@ -82,7 +83,7 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
// when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token // when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token
// the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes` // the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes`
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || []; const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
if (expiredTokenCodes.includes(response.data.code) && !request.state.isRefreshingToken) { if (expiredTokenCodes.includes(responseCode) && !request.state.isRefreshingToken) {
request.state.isRefreshingToken = true; request.state.isRefreshingToken = true;
const refreshConfig = await handleRefreshToken(response.config); const refreshConfig = await handleRefreshToken(response.config);
@ -108,7 +109,7 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
// get backend error message and code // get backend error message and code
if (error.code === BACKEND_ERROR_CODE) { if (error.code === BACKEND_ERROR_CODE) {
message = error.response?.data?.msg || message; message = error.response?.data?.msg || message;
backendErrorCode = error.response?.data?.code || ''; backendErrorCode = String(error.response?.data?.code || '');
} }
// the error message is displayed in the modal // the error message is displayed in the modal

View File

@ -10,8 +10,8 @@ import {
createThemeToken, createThemeToken,
getNaiveTheme, getNaiveTheme,
initThemeSettings, initThemeSettings,
toggleCssDarkMode, toggleAuxiliaryColorModes,
toggleGrayscaleMode toggleCssDarkMode
} from './shared'; } from './shared';
/** Theme store */ /** Theme store */
@ -33,6 +33,9 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
/** grayscale mode */ /** grayscale mode */
const grayscaleMode = computed(() => settings.value.grayscale); const grayscaleMode = computed(() => settings.value.grayscale);
/** colourWeakness mode */
const colourWeaknessMode = computed(() => settings.value.colourWeakness);
/** Theme colors */ /** Theme colors */
const themeColors = computed(() => { const themeColors = computed(() => {
const { themeColor, otherColor, isInfoFollowPrimary } = settings.value; const { themeColor, otherColor, isInfoFollowPrimary } = settings.value;
@ -79,6 +82,15 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
settings.value.grayscale = isGrayscale; settings.value.grayscale = isGrayscale;
} }
/**
* Set colourWeakness value
*
* @param isColourWeakness
*/
function setColourWeakness(isColourWeakness: boolean) {
settings.value.colourWeakness = isColourWeakness;
}
/** Toggle theme scheme */ /** Toggle theme scheme */
function toggleThemeScheme() { function toggleThemeScheme() {
const themeSchemes: UnionKey.ThemeScheme[] = ['light', 'dark', 'auto']; const themeSchemes: UnionKey.ThemeScheme[] = ['light', 'dark', 'auto'];
@ -167,9 +179,9 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
); );
watch( watch(
grayscaleMode, [grayscaleMode, colourWeaknessMode],
val => { val => {
toggleGrayscaleMode(val); toggleAuxiliaryColorModes(val[0], val[1]);
}, },
{ immediate: true } { immediate: true }
); );
@ -197,6 +209,7 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
naiveTheme, naiveTheme,
settingsJson, settingsJson,
setGrayscale, setGrayscale,
setColourWeakness,
resetStore, resetStore,
setThemeScheme, setThemeScheme,
toggleThemeScheme, toggleThemeScheme,

View File

@ -180,20 +180,16 @@ export function toggleCssDarkMode(darkMode = false) {
} }
/** /**
* Toggle grayscale mode * Toggle auxiliary color modes
* *
* @param grayscaleMode Is grayscale mode * @param grayscaleMode
* @param colourWeakness
*/ */
export function toggleGrayscaleMode(grayscaleMode = false) { export function toggleAuxiliaryColorModes(grayscaleMode = false, colourWeakness = false) {
const GRAYSCALE_CLASS = 'grayscale'; const htmlElement = document.documentElement;
htmlElement.style.filter = [grayscaleMode ? 'grayscale(100%)' : '', colourWeakness ? 'invert(80%)' : '']
const { add, remove } = toggleHtmlClass(GRAYSCALE_CLASS); .filter(Boolean)
.join(' ');
if (grayscaleMode) {
add();
} else {
remove();
}
} }
type NaiveColorScene = '' | 'Suppl' | 'Hover' | 'Pressed' | 'Active'; type NaiveColorScene = '' | 'Suppl' | 'Hover' | 'Pressed' | 'Active';

View File

@ -11,7 +11,3 @@ body,
html { html {
overflow-x: hidden; overflow-x: hidden;
} }
html.grayscale {
filter: grayscale(100%);
}

View File

@ -2,6 +2,7 @@
export const themeSettings: App.Theme.ThemeSetting = { export const themeSettings: App.Theme.ThemeSetting = {
themeScheme: 'light', themeScheme: 'light',
grayscale: false, grayscale: false,
colourWeakness: false,
recommendColor: false, recommendColor: false,
themeColor: '#646cff', themeColor: '#646cff',
otherColor: { otherColor: {
@ -48,6 +49,10 @@ export const themeSettings: App.Theme.ThemeSetting = {
height: 48, height: 48,
right: true right: true
}, },
watermark: {
visible: false,
text: 'SoybeanAdmin'
},
tokens: { tokens: {
light: { light: {
colors: { colors: {

14
src/typings/app.d.ts vendored
View File

@ -10,6 +10,8 @@ declare namespace App {
themeScheme: UnionKey.ThemeScheme; themeScheme: UnionKey.ThemeScheme;
/** grayscale mode */ /** grayscale mode */
grayscale: boolean; grayscale: boolean;
/** colour weakness mode */
colourWeakness: boolean;
/** Whether to recommend color */ /** Whether to recommend color */
recommendColor: boolean; recommendColor: boolean;
/** Theme color */ /** Theme color */
@ -93,6 +95,13 @@ declare namespace App {
/** Whether float the footer to the right when the layout is 'horizontal-mix' */ /** Whether float the footer to the right when the layout is 'horizontal-mix' */
right: boolean; right: boolean;
}; };
/** Watermark */
watermark: {
/** Whether to show the watermark */
visible: boolean;
/** Watermark text */
text: string;
};
/** define some theme settings tokens, will transform to css variables */ /** define some theme settings tokens, will transform to css variables */
tokens: { tokens: {
light: ThemeSettingToken; light: ThemeSettingToken;
@ -332,6 +341,7 @@ declare namespace App {
theme: { theme: {
themeSchema: { title: string } & Record<UnionKey.ThemeScheme, string>; themeSchema: { title: string } & Record<UnionKey.ThemeScheme, string>;
grayscale: string; grayscale: string;
colourWeakness: string;
layoutMode: { title: string; reverseHorizontalMix: string } & Record<UnionKey.ThemeLayoutMode, string>; layoutMode: { title: string; reverseHorizontalMix: string } & Record<UnionKey.ThemeLayoutMode, string>;
recommendColor: string; recommendColor: string;
recommendColorDesc: string; recommendColorDesc: string;
@ -372,6 +382,10 @@ declare namespace App {
height: string; height: string;
right: string; right: string;
}; };
watermark: {
visible: string;
text: string;
};
themeDrawerTitle: string; themeDrawerTitle: string;
pageFunTitle: string; pageFunTitle: string;
configOperation: { configOperation: {

View File

@ -98,6 +98,7 @@ declare module 'vue' {
NThing: typeof import('naive-ui')['NThing'] NThing: typeof import('naive-ui')['NThing']
NTooltip: typeof import('naive-ui')['NTooltip'] NTooltip: typeof import('naive-ui')['NTooltip']
NTree: typeof import('naive-ui')['NTree'] NTree: typeof import('naive-ui')['NTree']
NWatermark: typeof import('naive-ui')['NWatermark']
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default'] PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
ReloadButton: typeof import('./../components/common/reload-button.vue')['default'] ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']