From 823908afcaed06f1f373290733d818d7ba0d9520 Mon Sep 17 00:00:00 2001
From: Azir <2075125282@qq.com>
Date: Tue, 3 Dec 2024 16:34:54 +0800
Subject: [PATCH] feat(projects): theme init supports initialization based on
initial values.
---
.../modules/theme-drawer/modules/page-fun.vue | 6 +-
src/store/modules/theme/shared.ts | 12 ++--
src/typings/app.d.ts | 2 +-
src/utils/common.ts | 69 +++++++++++++++++++
4 files changed, 81 insertions(+), 8 deletions(-)
diff --git a/src/layouts/modules/theme-drawer/modules/page-fun.vue b/src/layouts/modules/theme-drawer/modules/page-fun.vue
index dbebb911..80ae6130 100644
--- a/src/layouts/modules/theme-drawer/modules/page-fun.vue
+++ b/src/layouts/modules/theme-drawer/modules/page-fun.vue
@@ -69,9 +69,6 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
-
-
-
@@ -130,6 +127,9 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
placeholder="SoybeanAdmin"
/>
+
+
+
diff --git a/src/store/modules/theme/shared.ts b/src/store/modules/theme/shared.ts
index 448c6992..3e63639b 100644
--- a/src/store/modules/theme/shared.ts
+++ b/src/store/modules/theme/shared.ts
@@ -2,30 +2,34 @@ import type { GlobalThemeOverrides } from 'naive-ui';
import { addColorAlpha, getColorPalette, getPaletteColorByNumber, getRgb } from '@sa/color';
import { overrideThemeSettings, themeSettings } from '@/theme/settings';
import { themeVars } from '@/theme/vars';
-import { toggleHtmlClass } from '@/utils/common';
+import { toggleHtmlClass, updateBase } from '@/utils/common';
import { localStg } from '@/utils/storage';
const DARK_CLASS = 'dark';
/** Init theme settings */
export function initThemeSettings() {
- const isProd = import.meta.env.PROD;
+ // const isProd = import.meta.env.PROD;
+ const isProd = true;
// if it is development mode, the theme settings will not be cached, by update `themeSettings` in `src/theme/settings.ts` to update theme settings
if (!isProd) return themeSettings;
+ const localSettings = localStg.get('themeSettings') || themeSettings;
+
// if it is production mode, the theme settings will be cached in localStorage
// if want to update theme settings when publish new version, please update `overrideThemeSettings` in `src/theme/settings.ts`
- const settings = localStg.get('themeSettings') || themeSettings;
+ const settings = updateBase(themeSettings, localSettings);
const isOverride = localStg.get('overrideThemeFlag') === BUILD_TIME;
-
if (!isOverride) {
Object.assign(settings, overrideThemeSettings);
localStg.set('overrideThemeFlag', BUILD_TIME);
}
+ localStg.set('themeSettings', settings);
+
return settings;
}
diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts
index 72c12314..853ec17d 100644
--- a/src/typings/app.d.ts
+++ b/src/typings/app.d.ts
@@ -103,7 +103,7 @@ declare namespace App {
right: boolean;
};
/** Watermark */
- watermark?: {
+ watermark: {
/** Whether to show the watermark */
visible: boolean;
/** Watermark text */
diff --git a/src/utils/common.ts b/src/utils/common.ts
index dc9a368f..0aca7007 100644
--- a/src/utils/common.ts
+++ b/src/utils/common.ts
@@ -1,3 +1,4 @@
+import { isObject } from 'lodash-es';
import { $t } from '@/locales';
/**
@@ -56,3 +57,71 @@ export function toggleHtmlClass(className: string) {
remove
};
}
+
+type AnyObject = { [key: string]: any };
+/** Auxiliary type: recursively make all attributes optional */
+type PartialDeep = {
+ [P in keyof T]?: T[P] extends AnyObject ? PartialDeep : T[P];
+};
+/**
+ * Deeply update base objects without adding keys that do not exist in the base.
+ *
+ * @example
+ * const base = {
+ * a: 1,
+ * b: {
+ * c: 2,
+ * d: 3,
+ * },
+ * e: [1, 2, 3],
+ * };
+ *
+ * const updates = {
+ * a: 10,
+ * b: {
+ * c: 20,
+ * e: 30, // Does not exist in base. b, will be ignored
+ * },
+ * f: 40, // Does not exist in base. b, will be ignored
+ * e: [4, 5], // Array will be replaced
+ * };
+ *
+ * const updatedBase = updateBase(base, updates);
+ *
+ * console.log(updatedBase);
+ * output:
+ * {
+ * a: 10,
+ * b: {
+ * c: 20,
+ * d: 3
+ * },
+ * e: [4, 5]
+ * }
+ *
+ * @param base - Base object
+ * @param updates - Update object
+ * @returns New object, a deep copy of the base object with updates applied
+ */
+export function updateBase(base: T, updates: PartialDeep): T {
+ // Deep copy the base object to avoid modifying the original object
+ const result: AnyObject = Array.isArray(base) ? [...base] : { ...base };
+
+ for (const key in updates) {
+ if (Object.hasOwn(base, key)) {
+ const baseValue = base[key];
+ const updateValue = updates[key];
+
+ if (isObject(baseValue) && isObject(updateValue)) {
+ // Recursively update nested objects
+ result[key] = updateBase(baseValue, updateValue);
+ } else {
+ // Directly assign updates
+ result[key] = updateValue;
+ }
+ }
+ // If the key in updates does not exist in base, ignore it
+ }
+
+ return result as T;
+}