|
@@ -22,8 +22,8 @@
|
|
|
</template>
|
|
</template>
|
|
|
<script lang="ts" setup>
|
|
<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 { computed, ref } from 'vue';
|
|
|
|
|
|
|
|
import { BasicModal } from '/@/components/Modal';
|
|
import { BasicModal } from '/@/components/Modal';
|
|
@@ -33,7 +33,7 @@
|
|
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
|
|
import { useMessage } from '/@/hooks/web/useMessage';
|
|
import { useMessage } from '/@/hooks/web/useMessage';
|
|
|
import { useGo } from '/@/hooks/web/usePage';
|
|
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 { updateDarkTheme } from '/@/logics/theme/dark';
|
|
|
import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
|
|
import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
|
|
|
|
|
|
|
@@ -60,43 +60,54 @@
|
|
|
return list;
|
|
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 记忆化缓存:同一会话只请求一次,失败清空可重试
|
|
// Promise 记忆化缓存:同一会话只请求一次,失败清空可重试
|
|
|
let homeStyleOptionsPromise: Promise<HomeStyleOption[]> | null = null;
|
|
let homeStyleOptionsPromise: Promise<HomeStyleOption[]> | null = null;
|
|
|
|
|
|
|
|
- /** 动态获取已注册首页选项 */
|
|
|
|
|
|
|
+ /** 动态获取最终可选首页:前端配置 × 后端菜单(按 component 匹配) */
|
|
|
function getHomeStyleOptions(): Promise<HomeStyleOption[]> {
|
|
function getHomeStyleOptions(): Promise<HomeStyleOption[]> {
|
|
|
if (!homeStyleOptionsPromise) {
|
|
if (!homeStyleOptionsPromise) {
|
|
|
homeStyleOptionsPromise = getPermissionList()
|
|
homeStyleOptionsPromise = getPermissionList()
|
|
|
.then((res: any) => {
|
|
.then((res: any) => {
|
|
|
- const optionMap = new Map<string, HomeStyleOption>();
|
|
|
|
|
|
|
+ // 后端菜单:component → 菜单项(同 component 多路由时优先 3D,2D 由路由守卫自动改写)
|
|
|
|
|
+ const menuByComponent = new Map<string, any>();
|
|
|
flattenMenu(Array.isArray(res) ? res : [])
|
|
flattenMenu(Array.isArray(res) ? res : [])
|
|
|
- .filter(isRegisteredHome)
|
|
|
|
|
|
|
+ .filter((item) => item && item.component && item.url)
|
|
|
.forEach((item) => {
|
|
.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) => {
|
|
.catch((e) => {
|
|
|
console.error('获取首页风格列表失败:', e);
|
|
console.error('获取首页风格列表失败:', e);
|