From 4a45d6c79b2157a149afcb3b49ba504ff7c5075f Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期三, 28 十月 2026 11:51:55 +0800
Subject: [PATCH] feat(portal): 门户字号改为保存到数据库全局生效

---
 src/layouts/basic.vue |  188 +++++++++++++++++++++++-----------------------
 1 files changed, 94 insertions(+), 94 deletions(-)

diff --git a/src/layouts/basic.vue b/src/layouts/basic.vue
index 469c8d3..4b7667b 100644
--- a/src/layouts/basic.vue
+++ b/src/layouts/basic.vue
@@ -1,34 +1,33 @@
 <script lang="ts" setup>
-import type { NotificationItem } from '..\packages\effects\layouts\src';
+import type { NotificationItem } from '@vben/layouts';
 
-import type { SystemTenantApi } from '#/api/system/tenant';
 
 import { computed, onMounted, ref, watch } from 'vue';
 
-import { useAccess } from '..\packages\effects\access\src';
-import { AuthenticationLoginExpiredModal, useVbenModal } from '..\packages\effects\common-ui\src';
-import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '..\packages\constants\src';
-import { isTenantEnable, useTabs, useWatermark } from '..\packages\effects\hooks\src';
+import { useDebounceFn } from '@vueuse/core';
+import { message } from 'ant-design-vue';
+
+import { AuthenticationLoginExpiredModal, useVbenModal } from '@vben/common-ui';
+import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
+import { useWatermark } from '@vben/hooks';
 import {
   AntdProfileOutlined,
   BookOpenText,
   CircleHelp,
   IconifyIcon,
   SvgGithubIcon,
-} from '..\packages\icons\src';
+} from '@vben/icons';
 import {
   BasicLayout,
   Help,
   LockScreen,
   Notification,
-  TenantDropdown,
   UserDropdown,
-} from '..\packages\effects\layouts\src';
-import { preferences, usePreferences } from '..\packages\preferences\src';
-import { useAccessStore, useUserStore } from '..\packages\stores\src';
-import { formatDateTime, openWindow } from '..\packages\utils\src';
+} from '@vben/layouts';
+import { preferences, usePreferences } from '@vben/preferences';
+import { useAccessStore, useUserStore } from '@vben/stores';
+import { formatDateTime, openWindow } from '@vben/utils';
 
-import { message, Tooltip } from 'ant-design-vue';
 
 import {
   getUnreadNotifyMessageCount,
@@ -36,18 +35,20 @@
   updateAllNotifyMessageRead,
   updateNotifyMessageRead,
 } from '#/api/system/notify/message';
-import { getSimpleTenantList } from '#/api/system/tenant';
 import { $t } from '#/locales';
 import { router } from '#/router';
 import { useAuthStore } from '#/store';
+import {
+  loadPortalUiConfig,
+  savePortalUiConfigToServer,
+} from '#/utils/portal-ui-config';
 import LoginForm from '#/views/_core/authentication/login.vue';
+import PortalBrandText from '#/components/portal/portal-brand-text.vue';
 
 const userStore = useUserStore();
 const authStore = useAuthStore();
 const accessStore = useAccessStore();
-const { hasAccessByCodes } = useAccess();
 const { destroyWatermark, updateWatermark } = useWatermark();
-const { closeOtherTabs, refreshTab } = useTabs();
 
 const notifications = ref<NotificationItem[]>([]);
 const unreadCount = ref(0);
@@ -67,30 +68,35 @@
     text: $t('ui.widgets.profile'),
   },
   {
-    handler: () => {
-      openWindow(VBEN_DOC_URL, {
-        target: '_blank',
-      });
-    },
-    icon: BookOpenText,
-    text: $t('ui.widgets.document'),
+    handler: () => router.push({ name: 'Profile', query: { section: 'resetPwd' } }),
+    icon: 'lucide:shield-check',
+    text: '瀵嗙爜璁剧疆',
   },
-  {
-    handler: () => {
-      openWindow(VBEN_GITHUB_URL, {
-        target: '_blank',
-      });
-    },
-    icon: SvgGithubIcon,
-    text: 'GitHub',
-  },
-  {
-    handler: () => {
-      helpModalApi.open();
-    },
-    icon: CircleHelp,
-    text: $t('ui.widgets.qa'),
-  },
+  // {
+  //   handler: () => {
+  //     openWindow(VBEN_DOC_URL, {
+  //       target: '_blank',
+  //     });
+  //   },
+  //   icon: BookOpenText,
+  //   text: $t('ui.widgets.document'),
+  // },
+  // {
+  //   handler: () => {
+  //     openWindow(VBEN_GITHUB_URL, {
+  //       target: '_blank',
+  //     });
+  //   },
+  //   icon: SvgGithubIcon,
+  //   text: 'GitHub',
+  // },
+  // {
+  //   handler: () => {
+  //     helpModalApi.open();
+  //   },
+  //   icon: CircleHelp,
+  //   text: $t('ui.widgets.qa'),
+  // },
 ]);
 
 const avatar = computed(() => {
@@ -157,47 +163,45 @@
   handleNotificationGetUnreadCount();
 }
 
-/** 鎵撳紑 IM 鑱婂ぉ */
-function handleOpenImHome() {
-  const { href } = router.resolve({ name: 'ImHome' });
-  window.open(href, '_blank');
-}
+// ========== 闂ㄦ埛瀛楀彿鍏ㄥ眬閰嶇疆锛堝瓨鏁版嵁搴擄紝鎵�鏈夌敤鎴峰叡鐢級 ==========
+/** 宸插悓姝ュ埌鏁版嵁搴撶殑瀛楀彿锛岀敤浜庨伩鍏嶈鍙栧悗鍥炲啓 */
+let portalFontBaseline: null | { home: number; menu: number } = null;
+/** 淇濆瓨澶辫触鍙彁绀轰竴娆★紝閬垮厤杩炵画璋冭妭鏃跺弽澶嶅脊绐� */
+let portalFontSaveWarned = false;
 
-// 绉熸埛鍒楄〃
-const tenants = ref<SystemTenantApi.Tenant[]>([]);
-const tenantEnable = computed(
-  () => hasAccessByCodes(['system:tenant:visit']) && isTenantEnable(),
-);
-
-/** 鑾峰彇绉熸埛鍒楄〃 */
-async function handleGetTenantList() {
-  if (tenantEnable.value) {
-    tenants.value = await getSimpleTenantList();
-  }
-}
-
-/** 澶勭悊绉熸埛鍒囨崲 */
-async function handleTenantChange(tenant: SystemTenantApi.Tenant) {
-  if (!tenant || !tenant.id) {
-    message.error('鍒囨崲绉熸埛澶辫触');
+const persistPortalFontConfig = useDebounceFn(async () => {
+  const home = preferences.app.homeFontSize;
+  const menu = preferences.navigation.fontSize;
+  if (portalFontBaseline && portalFontBaseline.home === home && portalFontBaseline.menu === menu) {
     return;
   }
-  // 璁剧疆璁块棶绉熸埛 ID
-  accessStore.setVisitTenantId(tenant.id as number);
-  // 鍏抽棴鍏朵粬鏍囩椤碉紝鍙繚鐣欏綋鍓嶉〉
-  await closeOtherTabs();
-  // 鍒锋柊褰撳墠椤甸潰
-  await refreshTab();
-  // 鎻愮ず鍒囨崲鎴愬姛
-  message.success(`鍒囨崲褰撳墠绉熸埛涓�: ${tenant.name}`);
-}
+  try {
+    await savePortalUiConfigToServer({ homeFontSize: home, menuFontSize: menu });
+    portalFontBaseline = { home, menu };
+    portalFontSaveWarned = false;
+  } catch {
+    if (!portalFontSaveWarned) {
+      portalFontSaveWarned = true;
+      message.warning('瀛楀彿宸插湪鏈満鐢熸晥锛屼絾淇濆瓨鍒板叏灞�澶辫触锛岃纭鏄惁鏈夊弬鏁伴厤缃慨鏀规潈闄�');
+    }
+  }
+}, 800);
+
+watch(
+  () => [preferences.app.homeFontSize, preferences.navigation.fontSize],
+  () => persistPortalFontConfig(),
+);
 
 // ========== 鍒濆鍖� ==========
-onMounted(() => {
+onMounted(async () => {
+  // 璇诲彇鏁版嵁搴撲腑鐨勫叏灞�瀛楀彿閰嶇疆骞跺簲鐢�
+  await loadPortalUiConfig();
+  portalFontBaseline = {
+    home: preferences.app.homeFontSize,
+    menu: preferences.navigation.fontSize,
+  };
   // 棣栨鍔犺浇鏈鏁伴噺
   handleNotificationGetUnreadCount();
-  // 鑾峰彇绉熸埛鍒楄〃
-  handleGetTenantList();
   // 杞鍒锋柊鏈鏁伴噺
   setInterval(
     () => {
@@ -275,9 +279,13 @@
 </script>
 
 <template>
-  <BasicLayout @clear-preferences-and-logout="handleLogout">
+  <BasicLayout class="supply-portal-shell" @clear-preferences-and-logout="handleLogout" @click-logo="router.push('/analytics')">
+    <template #logo-text>
+      <PortalBrandText />
+    </template>
     <template #user-dropdown>
       <UserDropdown
+        show-text
         :avatar
         :menus
         :text="userStore.userInfo?.nickname"
@@ -286,6 +294,9 @@
         @logout="handleLogout"
         @clear-preferences-and-logout="handleLogout"
       />
+    </template>
+    <template #header-right-165>
+      <button type="button" class="portal-personal-entry" aria-label="涓汉涓績" title="涓汉涓績" :class="{ 'is-current': router.currentRoute.value.name === 'Profile' }" @click="router.push({ name: 'Profile' })"><IconifyIcon icon="lucide:user-round" /><span>涓汉涓績</span></button>
     </template>
     <template #notification>
       <Notification
@@ -299,26 +310,15 @@
         @on-click="handleClick"
       />
     </template>
-    <template #header-right-1>
-      <div v-if="tenantEnable">
-        <TenantDropdown
-          class="mr-2"
-          :tenant-list="tenants"
-          :visit-tenant-id="accessStore.visitTenantId"
-          @success="handleTenantChange"
-        />
-      </div>
-    </template>
-    <template #header-right-900>
-      <Tooltip title="IM 鑱婂ぉ">
-        <button
-          class="hover:bg-accent hover:text-accent-foreground mr-1 inline-flex size-8 items-center justify-center rounded-md transition-colors"
-          type="button"
-          @click="handleOpenImHome"
-        >
-          <IconifyIcon class="size-4" icon="lucide:message-circle" />
-        </button>
-      </Tooltip>
+    <template v-if="router.hasRoute('MesWorkbench') && accessStore.accessMenus.some((menu) => /鐢熶骇|MES/i.test(menu.name))" #header-right-170>
+      <button
+        type="button"
+        class="flex cursor-pointer items-center gap-1.5 rounded-md border-none bg-primary/15 px-3 py-1.5 text-sm font-medium text-primary transition-colors hover:bg-primary/25"
+        @click="router.push({ name: 'MesWorkbench' })"
+      >
+        <IconifyIcon icon="lucide:factory" class="size-4" />
+        <span>宸ヤ綔鍙�</span>
+      </button>
     </template>
     <template #extra>
       <AuthenticationLoginExpiredModal

--
Gitblit v1.9.3