Ver Fonte

fix: 修复三个问题:偏好配置项修改后重启不会生效;锁屏弹出框的按钮文字错误;右上角偏好设置按钮排序问题优化; (#7930)

* fix: 修正偏好设置加载缓存的偏好设置并与初始配置合并的顺序

* fix: 修正锁屏弹出框的按钮文字

* fix: 偏好设置按钮排序优化(取第三个占位的数字,若是第三个占位不是数字,则自动分配排序索引)

* fix: 修正偏好设置加载缓存的偏好设置并与初始配置合并的顺序 - 代码QC问题修改

---------

Co-authored-by: PanFu <panfu@zhihuaai.com>
PanFu há 3 semanas atrás
pai
commit
769c970e08

+ 3 - 3
packages/@core/preferences/src/preferences.ts

@@ -124,19 +124,19 @@ class PreferenceManager {
     // 使用命名空间初始化存储管理器
     this.cache = new StorageManager({ prefix: namespace });
 
-    // 合并初始偏好设置
+    // 合并初始偏好设置:前面的对象优先,后面的对象仅补齐缺失字段
     this.initialPreferences = merge({}, overrides, defaultPreferences);
     this.customPreferencesExtension = extension ?? null;
     this.initialCustomPreferences = this.resolveCustomPreferencesDefaults(
       this.customPreferencesExtension,
     );
 
-    // 加载缓存的偏好设置并与初始配置合并
+    // 加载缓存的偏好设置,并仅用缓存补齐初始化配置中未显式设置的字段
     const cachedPreferences = (await this.loadFromCache()) || {};
     const mergedPreference = merge(
       {},
+      this.initialPreferences, // 初始化配置优先,缓存仅补齐缺失字段
       cachedPreferences,
-      this.initialPreferences,
     );
 
     // 更新偏好设置

+ 57 - 27
packages/effects/layouts/src/basic/header/header.vue

@@ -33,52 +33,61 @@ withDefaults(defineProps<Props>(), {
 
 const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
 
-const REFERENCE_VALUE = 50;
+const REFERENCE_VALUE = 100;
 
 const accessStore = useAccessStore();
 const { globalSearchShortcutKey, preferencesButtonPosition } = usePreferences();
 const slots = useSlots();
 const { refresh } = useRefresh();
 
+/**
+ * 插槽列表类型
+ */
+type SlotItem = { index: number; name: string };
+
 const rightSlots = computed(() => {
-  const list = [{ index: REFERENCE_VALUE + 100, name: 'user-dropdown' }];
+  const list: Array<SlotItem> = [];
+  // 全局搜索
   if (preferences.widget.globalSearch) {
     list.push({
       index: REFERENCE_VALUE,
       name: 'global-search',
     });
   }
-
+  // 偏好设置快捷功能
   if (preferencesButtonPosition.value.header) {
     list.push({
       index: REFERENCE_VALUE + 10,
       name: 'preferences',
     });
+    // 将偏好设置中的子功能分组到同一个按钮位置控制逻辑下
+    if (preferences.widget.themeToggle) {
+      list.push({
+        index: REFERENCE_VALUE + 20,
+        name: 'theme-toggle',
+      });
+    }
+    if (preferences.widget.languageToggle) {
+      list.push({
+        index: REFERENCE_VALUE + 30,
+        name: 'language-toggle',
+      });
+    }
+    if (preferences.widget.timezone) {
+      list.push({
+        index: REFERENCE_VALUE + 40,
+        name: 'timezone',
+      });
+    }
   }
-  if (preferences.widget.themeToggle) {
-    list.push({
-      index: REFERENCE_VALUE + 20,
-      name: 'theme-toggle',
-    });
-  }
-  if (preferences.widget.languageToggle) {
-    list.push({
-      index: REFERENCE_VALUE + 30,
-      name: 'language-toggle',
-    });
-  }
-  if (preferences.widget.timezone) {
-    list.push({
-      index: REFERENCE_VALUE + 40,
-      name: 'timezone',
-    });
-  }
+  // 全屏
   if (preferences.widget.fullscreen) {
     list.push({
       index: REFERENCE_VALUE + 50,
       name: 'fullscreen',
     });
   }
+  // 消息通知
   if (preferences.widget.notification) {
     list.push({
       index: REFERENCE_VALUE + 60,
@@ -87,17 +96,24 @@ const rightSlots = computed(() => {
   }
 
   Object.keys(slots).forEach((key) => {
-    const name = key.split('-');
+    // 适配插槽名称,例如第一个插槽名:header-right-1
     if (key.startsWith('header-right')) {
-      list.push({ index: Number(name[2]), name: key });
+      // 取第三个占位的数字,若是第三个占位不是数字,则自动分配排序索引
+      const slotIndex = Number(key.split('-')[2]);
+      const index = Number.isNaN(slotIndex) ? nextIndex(list) : slotIndex;
+      list.push({ index, name: key });
     }
   });
+  // 最后追加用户下拉框,若是索引值超过1000时则固定在1000(适配用户按钮不在最后的场景)
+  const userDropdownIndex = Math.min(1000, nextIndex(list));
+  list.push({ index: userDropdownIndex, name: 'user-dropdown' });
+  // 按照索引排序,保证插槽顺序
   return list.toSorted((a, b) => a.index - b.index);
 });
 
 const leftSlots = computed(() => {
-  const list: Array<{ index: number; name: string }> = [];
-
+  const list: Array<SlotItem> = [];
+  // 刷新
   if (preferences.widget.refresh) {
     list.push({
       index: 0,
@@ -106,14 +122,28 @@ const leftSlots = computed(() => {
   }
 
   Object.keys(slots).forEach((key) => {
-    const name = key.split('-');
+    // 适配插槽名称,例如第一个插槽名:header-left-1
     if (key.startsWith('header-left')) {
-      list.push({ index: Number(name[2]), name: key });
+      // 取第三个占位的数字,若是第三个占位不是数字,则自动分配排序索引
+      const slotIndex = Number(key.split('-')[2]);
+      const index = Number.isNaN(slotIndex) ? nextIndex(list) : slotIndex;
+      list.push({ index, name: key });
     }
   });
+  // 按照索引排序,保证插槽顺序
   return list.toSorted((a, b) => a.index - b.index);
 });
 
+/**
+ * 获取列表下一个索引值(用于排序)
+ * @param list 列表
+ */
+function nextIndex(list: Array<SlotItem>) {
+  const index =
+    list.length > 0 ? Math.max(...list.map((item) => item.index)) : 0;
+  return index + 1;
+}
+
 function clearPreferencesAndLogout() {
   emit('clearPreferencesAndLogout');
 }

+ 1 - 1
packages/locales/src/langs/en-US/ui.json

@@ -149,7 +149,7 @@
     },
     "lockScreen": {
       "title": "Lock Screen",
-      "screenButton": "Locking",
+      "screenButton": "Unlock",
       "password": "Password",
       "placeholder": "Please enter password",
       "unlock": "Click to unlock",

+ 1 - 1
packages/locales/src/langs/zh-CN/ui.json

@@ -149,7 +149,7 @@
     },
     "lockScreen": {
       "title": "锁定屏幕",
-      "screenButton": "锁",
+      "screenButton": "锁",
       "password": "密码",
       "placeholder": "请输入锁屏密码",
       "unlock": "点击解锁",