Commit b094eedf by 高源

状态保持优化及页面优化

parent 373f393e
# backend service base url, prod environment # backend service base url, prod environment
VITE_SERVICE_BASE_URL='http://localhost:80' VITE_SERVICE_BASE_URL=''
# other backend service base url, prod environment # other backend service base url, prod environment
VITE_OTHER_SERVICE_BASE_URL= `{ VITE_OTHER_SERVICE_BASE_URL= `{
......
<!doctype html> <!doctype html>
<html lang="zh-cmn-Hans"> <html lang="zh-cmn-Hans">
<head> <head>
<meta name="buildTime" content="2024-11-15 14:25:42"> <meta name="buildTime" content="2024-12-10 17:34:19">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" /> <link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" /> <meta name="color-scheme" content="light dark" />
<title>VueDashboard</title> <title>VueDashboard</title>
<script type="module" crossorigin src="/Content/VueDashboardUi/VueDashboard1/assets/index-C21dpL_i.js"></script> <script type="module" crossorigin src="/Content/VueDashboardUi/VueDashboard1/assets/index-BMlV-6Dx.js"></script>
<link rel="stylesheet" crossorigin href="/Content/VueDashboardUi/VueDashboard1/assets/index-obeHIzyq.css"> <link rel="stylesheet" crossorigin href="/Content/VueDashboardUi/VueDashboard1/assets/index-9k_B1ZU8.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
......
...@@ -133,7 +133,8 @@ function getSiderCollapsedWidth() { ...@@ -133,7 +133,8 @@ function getSiderCollapsedWidth() {
<GlobalSider /> <GlobalSider />
</template> </template>
<GlobalMenu /> <GlobalMenu />
<GlobalContent /> <GlobalContent style="display: none;" />
<div id="extjs-root" style="width: 100%; height: 100%"></div>
<ThemeDrawer /> <ThemeDrawer />
<template #footer> <template #footer>
<GlobalFooter /> <GlobalFooter />
......
...@@ -45,7 +45,7 @@ function resetScroll() { ...@@ -45,7 +45,7 @@ function resetScroll() {
<KeepAlive :include="routeStore.cacheRoutes"> <KeepAlive :include="routeStore.cacheRoutes">
<component <component
:is="Component" :is="Component"
v-if="appStore.reloadFlag" v-show="appStore.reloadFlag"
:key="tabStore.getTabIdByRoute(route)" :key="tabStore.getTabIdByRoute(route)"
:class="{ 'p-16px': showPadding }" :class="{ 'p-16px': showPadding }"
class="flex-grow bg-layout transition-300" class="flex-grow bg-layout transition-300"
......
...@@ -40,7 +40,7 @@ const { isFullscreen, toggle } = useFullscreen(); ...@@ -40,7 +40,7 @@ const { isFullscreen, toggle } = useFullscreen();
<div class="h-full flex-y-center justify-end"> <div class="h-full flex-y-center justify-end">
<GlobalSearch /> <GlobalSearch />
<FullScreen v-if="!appStore.isMobile" :full="isFullscreen" @click="toggle" /> <FullScreen v-if="!appStore.isMobile" :full="isFullscreen" @click="toggle" />
<LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" @change-lang="appStore.changeLocale" /> <!-- <LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" @change-lang="appStore.changeLocale" /> -->
<ThemeSchemaSwitch <ThemeSchemaSwitch
:theme-schema="themeStore.themeScheme" :theme-schema="themeStore.themeScheme"
:is-dark="themeStore.darkMode" :is-dark="themeStore.darkMode"
......
...@@ -5,6 +5,9 @@ defineOptions({ ...@@ -5,6 +5,9 @@ defineOptions({
name: 'GlobalLogo' name: 'GlobalLogo'
}); });
const DisplayName = window.uiGlobalConfig.DisplayName;
const Icon = window.uiGlobalConfig.Icon;
interface Props { interface Props {
/** Whether to show the title */ /** Whether to show the title */
showTitle?: boolean; showTitle?: boolean;
...@@ -17,9 +20,14 @@ withDefaults(defineProps<Props>(), { ...@@ -17,9 +20,14 @@ withDefaults(defineProps<Props>(), {
<template> <template>
<RouterLink to="/" class="w-full flex-center nowrap-hidden"> <RouterLink to="/" class="w-full flex-center nowrap-hidden">
<SystemLogo class="text-32px text-primary" /> <!-- <SystemLogo class="text-32px text-primary" />
<h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out"> <h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out">
{{ $t('system.title') }} {{ $t('system.title') }}
</h2> -->
<img v-if="Icon" :src="Icon" alt="" style="width: 32px" />
<SystemLogo v-else class="text-32px text-primary" />
<h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out">
{{ DisplayName }}
</h2> </h2>
</RouterLink> </RouterLink>
</template> </template>
......
...@@ -16,7 +16,7 @@ import GlobalLogo from '../../global-logo/index.vue'; ...@@ -16,7 +16,7 @@ import GlobalLogo from '../../global-logo/index.vue';
defineOptions({ defineOptions({
name: 'VerticalMenuMix' name: 'VerticalMenuMix'
}); });
const DisplayName = window.uiGlobalConfig.DisplayName;
const route = useRoute(); const route = useRoute();
const appStore = useAppStore(); const appStore = useAppStore();
const themeStore = useThemeStore(); const themeStore = useThemeStore();
...@@ -125,7 +125,7 @@ const renderIcon = (menuOption: any) => { ...@@ -125,7 +125,7 @@ const renderIcon = (menuOption: any) => {
:style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }" :style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
> >
<header class="flex-y-center justify-between px-12px" :style="{ height: themeStore.header.height + 'px' }"> <header class="flex-y-center justify-between px-12px" :style="{ height: themeStore.header.height + 'px' }">
<h2 class="text-16px text-primary font-bold">{{ $t('system.title') }}</h2> <h2 class="text-16px text-primary font-bold">{{ DisplayName }}</h2>
<PinToggler <PinToggler
:pin="appStore.mixSiderFixed" :pin="appStore.mixSiderFixed"
:class="{ 'text-white:88 !hover:text-white': inverted }" :class="{ 'text-white:88 !hover:text-white': inverted }"
......
...@@ -4,19 +4,21 @@ import { $t } from '@/locales'; ...@@ -4,19 +4,21 @@ import { $t } from '@/locales';
import { useThemeStore } from '@/store/modules/theme'; import { useThemeStore } from '@/store/modules/theme';
import { themePageAnimationModeOptions, themeScrollModeOptions, themeTabModeOptions } from '@/constants/app'; import { themePageAnimationModeOptions, themeScrollModeOptions, themeTabModeOptions } from '@/constants/app';
import { translateOptions } from '@/utils/common'; import { translateOptions } from '@/utils/common';
import { useAuthStore } from '@/store/modules/auth';
import SettingItem from '../components/setting-item.vue'; import SettingItem from '../components/setting-item.vue';
defineOptions({ defineOptions({
name: 'PageFun' name: 'PageFun'
}); });
const authStore = useAuthStore();
const themeStore = useThemeStore(); const themeStore = useThemeStore();
themeStore.watermark.text = authStore.userInfo.FullName
const layoutMode = computed(() => themeStore.layout.mode); const layoutMode = computed(() => themeStore.layout.mode);
const isMixLayoutMode = computed(() => layoutMode.value.includes('mix')); const isMixLayoutMode = computed(() => layoutMode.value.includes('mix'));
const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wrapper'); const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wrapper');
const DisplayName = window.uiGlobalConfig.DisplayName;
</script> </script>
<template> <template>
...@@ -104,7 +106,7 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra ...@@ -104,7 +106,7 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
<SettingItem v-if="themeStore.watermark" key="8" :label="$t('theme.watermark.visible')"> <SettingItem v-if="themeStore.watermark" key="8" :label="$t('theme.watermark.visible')">
<NSwitch v-model:value="themeStore.watermark.visible" /> <NSwitch v-model:value="themeStore.watermark.visible" />
</SettingItem> </SettingItem>
<SettingItem v-if="themeStore.watermark?.visible" key="8-1" :label="$t('theme.watermark.text')"> <SettingItem v-show="false" key="8-1" :label="$t('theme.watermark.text')">
<NInput <NInput
v-model:value="themeStore.watermark.text" v-model:value="themeStore.watermark.text"
autosize autosize
......
...@@ -8,7 +8,8 @@ export function setupLoading() { ...@@ -8,7 +8,8 @@ export function setupLoading() {
const themeColor = localStg.get('themeColor') || '#646cff'; const themeColor = localStg.get('themeColor') || '#646cff';
const { r, g, b } = getRgb(themeColor); const { r, g, b } = getRgb(themeColor);
// const DisplayName = '123';
const DisplayName = window.uiGlobalConfig.DisplayName;
const primaryColor = `--primary-color: ${r} ${g} ${b}`; const primaryColor = `--primary-color: ${r} ${g} ${b}`;
const loadingClasses = [ const loadingClasses = [
...@@ -34,7 +35,7 @@ export function setupLoading() { ...@@ -34,7 +35,7 @@ export function setupLoading() {
${dot} ${dot}
</div> </div>
</div> </div>
<h2 class="text-28px font-500 text-#646464">${$t('system.title')}</h2> <h2 class="text-28px font-500 text-#646464">${DisplayName}</h2>
</div>`; </div>`;
const app = document.getElementById('app'); const app = document.getElementById('app');
......
...@@ -5,6 +5,7 @@ import { getRootMenu } from '@/service/api'; ...@@ -5,6 +5,7 @@ import { getRootMenu } from '@/service/api';
import { generatedRoutes } from '../elegant/routes'; import { generatedRoutes } from '../elegant/routes';
import { layouts, views } from '../elegant/imports'; import { layouts, views } from '../elegant/imports';
import { transformElegantRoutesToVueRoutes } from '../elegant/transform'; import { transformElegantRoutesToVueRoutes } from '../elegant/transform';
import { truncate } from 'fs/promises';
/** /**
* custom routes * custom routes
* *
......
declare module 'vue3-sfc-loader' {
import type { Component } from 'vue';
interface Options {
moduleCache?: any;
getFile: (url: string) => Promise<string>;
addStyle: (textContent: string) => void;
log?: (type: string, ...args: any[]) => void;
}
export function loadModule(url: string, options: Options): Promise<Component>;
}
...@@ -18,7 +18,6 @@ declare module 'vue' { ...@@ -18,7 +18,6 @@ declare module 'vue' {
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default'] IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default'] IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default'] IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
IconLocalBanner: typeof import('~icons/local/banner')['default']
IconLocalLogo: typeof import('~icons/local/logo')['default'] IconLocalLogo: typeof import('~icons/local/logo')['default']
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default'] IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default'] IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
...@@ -28,7 +27,6 @@ declare module 'vue' { ...@@ -28,7 +27,6 @@ declare module 'vue' {
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default'] LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
LookForward: typeof import('./../components/custom/look-forward.vue')['default'] LookForward: typeof import('./../components/custom/look-forward.vue')['default']
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default'] MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
NAlert: typeof import('naive-ui')['NAlert']
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb'] NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem'] NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
...@@ -48,8 +46,6 @@ declare module 'vue' { ...@@ -48,8 +46,6 @@ declare module 'vue' {
NInput: typeof import('naive-ui')['NInput'] NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup'] NInputGroup: typeof import('naive-ui')['NInputGroup']
NInputNumber: typeof import('naive-ui')['NInputNumber'] NInputNumber: typeof import('naive-ui')['NInputNumber']
NList: typeof import('naive-ui')['NList']
NListItem: typeof import('naive-ui')['NListItem']
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider'] NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider'] NMessageProvider: typeof import('naive-ui')['NMessageProvider']
...@@ -62,7 +58,6 @@ declare module 'vue' { ...@@ -62,7 +58,6 @@ declare module 'vue' {
NSwitch: typeof import('naive-ui')['NSwitch'] NSwitch: typeof import('naive-ui')['NSwitch']
NTab: typeof import('naive-ui')['NTab'] NTab: typeof import('naive-ui')['NTab']
NTabs: typeof import('naive-ui')['NTabs'] NTabs: typeof import('naive-ui')['NTabs']
NThing: typeof import('naive-ui')['NThing']
NTooltip: typeof import('naive-ui')['NTooltip'] NTooltip: typeof import('naive-ui')['NTooltip']
NWatermark: typeof import('naive-ui')['NWatermark'] NWatermark: typeof import('naive-ui')['NWatermark']
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default'] PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
......
<!-- eslint-disable no-console -->
<!-- eslint-disable @typescript-eslint/no-shadow -->
<script setup lang="ts"> <script setup lang="ts">
import { onActivated, onMounted, ref } from 'vue'; import { onActivated, onMounted, ref, shallowRef } from 'vue';
import { loadModule } from 'vue3-sfc-loader';
import { getSelectMenu } from '@/service/api'; import { getSelectMenu } from '@/service/api';
import NotFound from '@/views/_builtin/404/index.vue'; // 引入 404 组件 import NotFound from '@/views/_builtin/404/index.vue'; // 引入 404 组件
import ExtJsComponent from './extJs.vue';
import WebviewComponent from './webview.vue';
interface Props { interface Props {
url: string; url: string;
...@@ -9,13 +14,19 @@ interface Props { ...@@ -9,13 +14,19 @@ interface Props {
kvid: string; kvid: string;
type: string; type: string;
} }
// 定义一个响应式变量来存储异步加载的组件
const asyncComponent = shallowRef<any>(null);
const { url, kvid, type } = defineProps<Props>(); const { url, kvid, type } = defineProps<Props>();
const selectTag = ref(''); // 定义响应式变量 const selectTag = ref(''); // 定义响应式变量
const extTag = ref(''); // 定义响应式变量
const hasError = ref(false); // 标志位,用于指示是否发生错误 const hasError = ref(false); // 标志位,用于指示是否发生错误
onMounted(() => { onMounted(() => {
// console.log('mounted'); // console.log('mounted');
const origin = window.location.origin;
origin.split('/').slice(0, 3).join('/');
// loadExternalComponent(`${origin}/codet/testComponent.vue`);
// loadExternalComponent(`localhost:8081//src/views/_builtin/iframe-page/extJs.vue`);
}); });
onActivated(async () => { onActivated(async () => {
...@@ -24,9 +35,12 @@ onActivated(async () => { ...@@ -24,9 +35,12 @@ onActivated(async () => {
origin.split('/').slice(0, 3).join('/'); origin.split('/').slice(0, 3).join('/');
// const origin = 'http://localhost:80'; // const origin = 'http://localhost:80';
if (type === 'System') { if (type === 'System') {
console.log(url);
if (url.startsWith('App')) { if (url.startsWith('App')) {
selectTag.value = `${origin}/extjs6/classic/${url}`; // selectTag.value = `${origin}/extjs6/classic/${url}`;
extTag.value = url;
} else { } else {
selectTag.value = `${origin}/${url}`; selectTag.value = `${origin}/${url}`;
} }
...@@ -40,7 +54,8 @@ onActivated(async () => { ...@@ -40,7 +54,8 @@ onActivated(async () => {
if (selectMenu.Results[0].Handler !== undefined && selectMenu.Results[0].Handler.slice(0, 1) === '/') { if (selectMenu.Results[0].Handler !== undefined && selectMenu.Results[0].Handler.slice(0, 1) === '/') {
selectTag.value = `${origin}${selectMenu.Results[0].Handler}`; selectTag.value = `${origin}${selectMenu.Results[0].Handler}`;
} else { } else {
selectTag.value = `${origin}/extjs6/classic/${selectMenu.Results[0].Handler}`; // selectTag.value = `${origin}/extjs6/classic/${selectMenu.Results[0].Handler}`;
extTag.value = selectMenu.Results[0].Handler;
} }
} else { } else {
hasError.value = true; // 设置错误标志位 hasError.value = true; // 设置错误标志位
...@@ -49,16 +64,48 @@ onActivated(async () => { ...@@ -49,16 +64,48 @@ onActivated(async () => {
hasError.value = true; // 如果请求失败,也设置错误标志位 hasError.value = true; // 如果请求失败,也设置错误标志位
} }
} }
// iframeList.value.push(selectTag.value);
// console.log(iframeList.value)
}); });
// 定义加载外部组件的函数
const loadExternalComponent = async (url: string) => {
const options = {
moduleCache: {
vue: await import('vue')
},
// eslint-disable-next-line @typescript-eslint/no-shadow
async getFile(url: string) {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}`);
}
return await res.text();
},
addStyle(textContent: string) {
const style = document.createElement('style');
style.textContent = textContent;
document.head.appendChild(style);
},
log(type: string, ...args: any[]) {
console[type](...args);
}
};
// 使用 loadModule 加载外部组件
loadModule(url, options)
.then(component => {
asyncComponent.value = component;
console.log('Component loaded:', asyncComponent.value);
})
.catch(error => {
console.error('Error loading component:', error);
});
};
</script> </script>
<template> <template>
<div class="h-full"> <div class="h-full">
<iframe v-show="!hasError" id="iframePage" class="size-full" :src="selectTag"></iframe> <WebviewComponent v-if="selectTag && !hasError" id="iframePage" class="size-full" :url="selectTag"></WebviewComponent>
<NotFound v-if="hasError" /> <ExtJsComponent v-else-if="extTag && !hasError" :key="extTag" :url="extTag"></ExtJsComponent>
<!-- 使用引入的 404 组件 --> <NotFound v-else />
</div> </div>
</template> </template>
......
<!-- MyComponent.vue -->
<script setup lang="ts">
import { nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
// 接收一个名为 url 的 prop
const props = defineProps<{
url: string;
}>();
let extComponent: any = null;
// 控制组件显示状态的变量
const isActive = ref(true);
const extjsContainerId = `extjs-${Math.random().toString(36).substr(2, 9)}`;
function initializeExtComponent() {
extComponent = Ext.create('Ext.panel.Panel', {
renderTo: extjsContainerId,
layout: 'fit',
width: '100%',
height: '100%',
hidden: false,
items: [Ext.create(props.url)]
});
}
function updateExtComponent(newUrl: string) {
if (extComponent) {
// 更新 ExtJS 组件的内容,而不销毁整个组件
// 这里假设您可以通过某种方式更新组件的内容
// 例如,替换面板中的子组件
// 获取当前的子组件
const oldItem = extComponent.items.getAt(0);
// 移除旧的子组件
extComponent.remove(oldItem, true); // 第二个参数为 true,表示销毁组件
// 创建新的子组件
const newItem = Ext.create(newUrl);
// 添加新的子组件到面板
extComponent.add(newItem);
}
}
onMounted(() => {
nextTick(() => {
if (!extComponent) {
initializeExtComponent();
} else {
extComponent.show();
isActive.value = true;
}
});
});
onActivated(() => {
// if (extComponent) {
// extComponent.show();
isActive.value = true;
// }
});
onDeactivated(() => {
// if (extComponent) {
// extComponent.hide();
isActive.value = false;
// }
});
onBeforeUnmount(() => {
if (extComponent) {
extComponent.destroy();
extComponent = null;
}
});
// 监听 props.url 的变化
watch(
() => props.url,
(newUrl, oldUrl) => {
if (newUrl !== oldUrl) {
updateExtComponent(newUrl);
}
}
);
</script>
<template>
<!-- 使用 Teleport 将 extjs-container 渲染到组件外部的 extjs-root 中 -->
<Teleport to="#extjs-root">
<div v-show="isActive" :id="extjsContainerId" style="width: 100%; height: 100%"></div>
</Teleport>
</template>
<style scoped>
/* 您的样式代码 */
</style>
<!-- eslint-disable vue/multi-word-component-names -->
<script setup lang="ts">
import { nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
// 接收一个名为 url 的 prop
const props = defineProps<{
url: string;
}>();
// 控制组件显示状态的变量
const isActive = ref(true);
// 生成唯一的容器 ID
const extjsContainerId = `webview-${Math.random().toString(36).substr(2, 9)}`;
// 用来存储创建的 iframe 元素引用
let iframeEl: HTMLIFrameElement | null = null;
function initializeExtComponent() {
const container = document.getElementById(extjsContainerId);
if (!container) return;
// 创建 iframe
iframeEl = document.createElement('iframe');
iframeEl.style.width = '100%';
iframeEl.style.height = '100%';
iframeEl.style.border = 'none';
iframeEl.src = props.url;
container.appendChild(iframeEl);
}
function updateExtComponent(newUrl: string) {
if (iframeEl) {
// 更新 iframe 的地址
iframeEl.src = newUrl;
}
}
onMounted(() => {
nextTick(() => {
// 初次挂载时创建 iframe
if (!iframeEl) {
initializeExtComponent();
} else {
isActive.value = true;
}
});
});
onActivated(() => {
isActive.value = true;
});
onDeactivated(() => {
isActive.value = false;
});
onBeforeUnmount(() => {
// 组件卸载前清理
const container = document.getElementById(extjsContainerId);
if (container && iframeEl) {
container.removeChild(iframeEl);
iframeEl = null;
}
});
// 监听 props.url 的变化,当地址变化时更新 iframe 的 src
watch(
() => props.url,
(newUrl, oldUrl) => {
if (newUrl !== oldUrl) {
updateExtComponent(newUrl);
}
}
);
</script>
<template>
<!-- 使用 Teleport 将容器渲染到组件外部的 extjs-root 中 -->
<Teleport to="#extjs-root">
<div v-show="isActive" :id="extjsContainerId" style="width: 100%; height: 100%"></div>
</Teleport>
</template>
<style scoped>
/* 您的样式代码 */
</style>
...@@ -21,7 +21,8 @@ const props = defineProps<Props>(); ...@@ -21,7 +21,8 @@ const props = defineProps<Props>();
const appStore = useAppStore(); const appStore = useAppStore();
const themeStore = useThemeStore(); const themeStore = useThemeStore();
const DisplayName = window.uiGlobalConfig.DisplayName;
const Icon = window.uiGlobalConfig.Icon;
interface LoginModule { interface LoginModule {
label: string; label: string;
component: Component; component: Component;
...@@ -56,13 +57,14 @@ const bgColor = computed(() => { ...@@ -56,13 +57,14 @@ const bgColor = computed(() => {
<NCard :bordered="false" class="relative z-4 w-auto rd-12px"> <NCard :bordered="false" class="relative z-4 w-auto rd-12px">
<div class="w-400px lt-sm:w-300px"> <div class="w-400px lt-sm:w-300px">
<header class="flex-y-center justify-between"> <header class="flex-y-center justify-between">
<SystemLogo class="text-64px text-primary lt-sm:text-48px" /> <img v-if="Icon" :src="Icon" alt="" style="width: 50px;" />
<h3 class="text-28px text-primary font-500 lt-sm:text-22px">{{ $t('system.title') }}</h3> <SystemLogo v-else class="text-64px text-primary lt-sm:text-48px" />
<h3 class="text-28px text-primary font-500 lt-sm:text-22px">{{ DisplayName }}</h3>
<div class="i-flex-col"> <div class="i-flex-col">
<ThemeSchemaSwitch :theme-schema="themeStore.themeScheme" :show-tooltip="false" <ThemeSchemaSwitch :theme-schema="themeStore.themeScheme" :show-tooltip="false"
class="text-20px lt-sm:text-18px" @switch="themeStore.toggleThemeScheme" /> class="text-20px lt-sm:text-18px" @switch="themeStore.toggleThemeScheme" />
<LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" :show-tooltip="false" <!-- <LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" :show-tooltip="false"
@change-lang="appStore.changeLocale" /> @change-lang="appStore.changeLocale" /> -->
</div> </div>
</header> </header>
<main class="pt-24px"> <main class="pt-24px">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment