Przeglądaj źródła

[Mod 0000] 首页风格选择功能加强过滤规则

houzekong 2 tygodni temu
rodzic
commit
6895de2729

+ 37 - 26
src/layouts/default/header/components/user-dropdown/HomeStyleSelect.vue

@@ -22,8 +22,8 @@
 </template>
 <script lang="ts" setup>
   // 首页风格切换弹窗:下拉框选择首页风格,右下角 取消 / 恢复默认 / 确认。
-  // 选项动态获取自 /sys/permissionNew/list(getPermissionList),component 以 vent/home/ 开头视为已注册首页;
-  // 主题按标题关键词推导(绿→GREEN、蓝→DEEPBLUE、5.5→DEEPBLUE+theme5_5,其余→VENT1);本地存储见 /@/utils/homeStyle。
+  // 最终可选首页 = 前端配置数组 HOME_STYLE_CONFIG × 后端 /sys/permissionNew/list 数据(按 component 精确匹配):
+  // 前端配置提供候选与名称/主题,后端确认"已注册"并提供路由 url;本地存储见 /@/utils/homeStyle。
   import { computed, ref } from 'vue';
 
   import { BasicModal } from '/@/components/Modal';
@@ -33,7 +33,7 @@
   import { useRootSetting } from '/@/hooks/setting/useRootSetting';
   import { useMessage } from '/@/hooks/web/useMessage';
   import { useGo } from '/@/hooks/web/usePage';
-  import { ThemeModel } from '/@/layouts/default/layout.data';
+  // import { ThemeModel } from '/@/layouts/default/layout.data';
   import { updateDarkTheme } from '/@/logics/theme/dark';
   import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
 
@@ -60,43 +60,54 @@
     return list;
   }
 
-  /** 是否已注册首页:component 以 vent/home/ 开头且配置了路由 */
-  function isRegisteredHome(item: any): boolean {
-    return !!item && !!item.component && String(item.component).startsWith('vent/home/') && !!item.url;
+  /** 前端配置的首页风格候选:与后端菜单按 component 精确匹配,匹配上才可选(component 需唯一) */
+  interface HomeStyleConfig {
+    /** 对应后端菜单的 component(匹配依据) */
+    component: string;
+    /** 首页风格名称(下拉框显示);缺省时取后端菜单 title */
+    name?: string;
+    /** 主题模式:ThemeEnum.VENT1 / DEEPBLUE / GREEN / LIGHT / DARK */
+    theme: ThemeEnum;
+    /** 可选:页面样式变量(如 ThemeModel.theme5_5) */
+    cssVars?: Record<string, string>;
   }
 
-  /** 由菜单节点生成首页风格选项,主题按标题关键词推导 */
-  function toHomeStyleOption(item: any): HomeStyleOption {
-    const route: string = item.url;
-    const name: string = item.title || item.name || route;
-    const is55 = name.includes('5.5') || route.includes('modelchannel/model3D');
-    let theme = ThemeEnum.VENT1;
-    if (name.includes('绿')) theme = ThemeEnum.GREEN;
-    else if (name.includes('蓝') || is55) theme = ThemeEnum.DEEPBLUE;
-    return { id: String(item.id), name, route, theme, cssVars: is55 ? ThemeModel.theme5_5 : undefined };
-  }
+  const HOME_STYLE_CONFIG: HomeStyleConfig[] = [
+    { component: 'vent/home/configurable/vent182', name: '一通三防首页-默认', theme: ThemeEnum.VENT1 },
+    { component: 'vent/home/configurable/green/fusion-warn-green', name: '一通三防首页-绿主题', theme: ThemeEnum.GREEN },
+    { component: 'vent/home/configurable/blue/dustNew', name: '一通三防首页-蓝主题', theme: ThemeEnum.DEEPBLUE },
+  ];
 
   // Promise 记忆化缓存:同一会话只请求一次,失败清空可重试
   let homeStyleOptionsPromise: Promise<HomeStyleOption[]> | null = null;
 
-  /** 动态获取已注册首页选项 */
+  /** 动态获取最终可选首页:前端配置 × 后端菜单(按 component 匹配) */
   function getHomeStyleOptions(): Promise<HomeStyleOption[]> {
     if (!homeStyleOptionsPromise) {
       homeStyleOptionsPromise = getPermissionList()
         .then((res: any) => {
-          const optionMap = new Map<string, HomeStyleOption>();
+          // 后端菜单:component → 菜单项(同 component 多路由时优先 3D,2D 由路由守卫自动改写)
+          const menuByComponent = new Map<string, any>();
           flattenMenu(Array.isArray(res) ? res : [])
-            .filter(isRegisteredHome)
+            .filter((item) => item && item.component && item.url)
             .forEach((item) => {
-              const option = toHomeStyleOption(item);
-              // 2D/3D 去重:按归一化路由去重,同键优先 3D 项(2D 由路由守卫自动改写)
-              const key = `${item.component}|${option.route.replace('micro-vent-2dModal', 'micro-vent-3dModal')}`;
-              const existed = optionMap.get(key);
-              if (!existed || (!existed.route.includes('micro-vent-3dModal') && option.route.includes('micro-vent-3dModal'))) {
-                optionMap.set(key, option);
+              const component = String(item.component);
+              const existed = menuByComponent.get(component);
+              if (!existed || (item.url.includes('micro-vent-3dModal') && !existed.url.includes('micro-vent-3dModal'))) {
+                menuByComponent.set(component, item);
               }
             });
-          return [...optionMap.values()];
+          // 配置数组 ∩ 后端已注册:路由取后端 url,名称/主题/样式变量取配置
+          return HOME_STYLE_CONFIG.filter((config) => menuByComponent.has(config.component)).map((config) => {
+            const item = menuByComponent.get(config.component);
+            return {
+              id: config.component, // 持久化 id 用配置的 component(稳定,不随后端菜单 id 变化)
+              name: config.name || item.title || item.name || config.component,
+              route: item.url,
+              theme: config.theme,
+              cssVars: config.cssVars,
+            };
+          });
         })
         .catch((e) => {
           console.error('获取首页风格列表失败:', e);

+ 4 - 4
src/utils/homeStyle.ts

@@ -4,15 +4,15 @@ import { HOME_STYLE_KEY } from '/@/enums/cacheEnum';
 /**
  * 首页风格选择:localStorage 的存放与读取工具。
  * key 定义见 /@/enums/cacheEnum 的 HOME_STYLE_KEY;
- * 选项数据本身由 HomeStyleSelect.vue 从 /sys/permissionNew/list 动态获取(component 以 vent/home/ 开头视为已注册首页)
+ * 最终可选首页由 HomeStyleSelect.vue 的前端配置数组与 /sys/permissionNew/list 后端数据按 component 匹配得出
  */
 
 export interface HomeStyleOption {
-  /** 唯一标识(菜单 id 字符串化,持久化用) */
+  /** 唯一标识(持久化用,取前端配置的 component,稳定) */
   id: string;
-  /** 首页风格名称(下拉框显示,对应菜单 title) */
+  /** 首页风格名称(下拉框显示) */
   name: string;
-  /** 首页路由(对应菜单 url) */
+  /** 首页路由(对应后端菜单 url) */
   route: string;
   /** 主题模式:ThemeEnum.VENT1 / DEEPBLUE / GREEN / LIGHT / DARK */
   theme: ThemeEnum;