| src/bootstrap.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/layouts/auth-scene.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/layouts/auth.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/preferences.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/styles/herbal-theme.css | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/_core/authentication/login.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/bootstrap.ts
@@ -7,7 +7,6 @@ import { initStores } from './packages/stores/src'; import './packages/styles/src'; import './packages/styles/src/antd/index.css'; import './styles/herbal-theme.css'; import { useTitle } from '@vueuse/core'; src/layouts/auth-scene.vue
ÎļþÒÑɾ³ý src/layouts/auth.vue
@@ -1,16 +1,15 @@ <script lang="ts" setup> import { computed, onMounted } from 'vue'; import { preferences, usePreferences } from '@vben/preferences'; import { AuthPageLayout } from '@vben/layouts'; import { preferences } from '@vben/preferences'; import { $t } from '#/locales'; import { useCompanyConfigStore } from '#/store/company-config'; import AuthenticationToolbar from '../packages/effects/layouts/src/authentication/toolbar.vue'; import AuthScene from './auth-scene.vue'; declare const __APP_LOGO__: string; const companyConfigStore = useCompanyConfigStore(); const { isDark } = usePreferences(); onMounted(() => { // ç»å½é¡µå±ç¤º loginTitleï¼å¯å¨å è½½èµ°çæ¯çº¯å½æ°ï¼ä¸å¡« storeï¼ï¼è¿å ¥ç»å½é¡µæ¶æå䏿¬¡ @@ -20,26 +19,29 @@ const appName = computed(() => preferences.copyright.companyName); // ç»å½é¡µ logo ä¼å åæ°æ®åºé ç½®ï¼preferences.logo.sourceï¼ï¼æªé ç½®æ¶åéç¼è¯æé»è®¤ __APP_LOGO__ const logo = computed(() => { const source = (isDark.value && preferences.logo.sourceDark) || preferences.logo.source || __APP_LOGO__; const source = preferences.logo.source || __APP_LOGO__; // æªé ç½®å ¬å¸æ å¿æ¶ä¸å±ç¤ºæ¡æ¶æ¼ç¤º Logoã return source?.includes('@vbenjs/static-source') ? '' : source; }); const pageTitle = computed(() => companyConfigStore.loginTitle || 'æ»è¡¥åè¡ä¸æ°åå管çå¹³å°'); const pageDescription = computed(() => companyConfigStore.loginDescription || 'ä¼ æ¿ä¸å»è¯ç²¾å · æå¡å¥åº·ç¾å¥½çæ´»'); const logoDark = computed(() => preferences.logo.sourceDark); // æ é¢/æè¿°ä¼å åå ¬å¸ä¿¡æ¯é ç½®ï¼æªé ç½®æ¶åéæ åææ¡ const pageTitle = computed( () => companyConfigStore.loginTitle || $t('authentication.pageTitle'), ); const pageDescription = computed( () => companyConfigStore.loginDescription || $t('authentication.pageDesc'), ); </script> <template> <AuthScene <AuthPageLayout :app-name="appName" :logo="logo" :platform-description="pageDescription" :platform-title="pageTitle" :logo-dark="logoDark" :page-description="pageDescription" :page-title="pageTitle" > <template #toolbar><AuthenticationToolbar :toolbar-list="['language', 'theme']" /></template> <RouterView v-slot="{ Component, route }"> <KeepAlive :include="['Login']"> <component :is="Component" :key="route.fullPath" /> </KeepAlive> </RouterView> </AuthScene> <!-- èªå®ä¹å·¥å ·æ --> <!-- <template #toolbar></template> --> </AuthPageLayout> </template> src/main.ts
@@ -1,5 +1,4 @@ import { watch } from 'vue'; import { initPreferences, preferences, preferencesManager } from './packages/preferences/src'; import { initPreferences, preferencesManager } from './packages/preferences/src'; import { unmountGlobalLoading } from './packages/utils/src'; import { overridesPreferences, preferencesExtension } from './preferences'; @@ -25,27 +24,21 @@ overrides: overridesPreferences, }); // 馿¬¡åçº§åæ¥åç主è²ï¼é¿å æ§çèè²å好é®çæ¬æ¬¡ä¸»é¢æ´æ°ã // å级åç¨æ·å¨å好设置ä¸éæ©çé¢è²åæææ¨¡å¼ä»ä¼ä¿çã document.documentElement.dataset.brandTheme = 'herbal'; const brandThemeKey = `${namespace}-herbal-theme-v1`; // æ¢å¤æ åé»è®¤èè²ä¸»é¢ï¼æ¸ æä¹åç¼åçæ±ç 红åçè²ã // 䏿¬¡æ§è¿ç§»ï¼ä¹åç¨æ·å¨å好设置ä¸éæ©çé¢è²ä»ä¼ä¿çã const themeMigrationKey = `${namespace}-default-blue-theme-v1`; const defaultTheme = { theme: { builtinType: 'default' as const, colorPrimary: 'hsl(212 100% 45%)' }, }; try { if (!localStorage.getItem(brandThemeKey)) { preferencesManager.updatePreferences({ theme: { builtinType: 'custom', colorPrimary: '#a51d24' }, }); localStorage.setItem(brandThemeKey, '1'); if (!localStorage.getItem(themeMigrationKey)) { preferencesManager.updatePreferences(defaultTheme); localStorage.setItem(themeMigrationKey, '1'); localStorage.removeItem(`${namespace}-herbal-theme-v1`); } } catch { preferencesManager.updatePreferences({ theme: { builtinType: 'custom', colorPrimary: '#a51d24' }, }); preferencesManager.updatePreferences(defaultTheme); } watch( () => preferences.theme.colorPrimary, (color) => { document.documentElement.dataset.herbalPalette = String(color.toLowerCase() === '#a51d24'); }, { immediate: true, flush: 'sync' }, ); // 强å¶è¦çå ¬å¸ logo å faviconï¼ç»è¿ localStorage ç¼å if (__APP_LOGO__) { src/preferences.ts
@@ -20,10 +20,6 @@ */ export const overridesPreferences = defineOverridesPreferences({ // overrides theme: { builtinType: 'custom', colorPrimary: '#a51d24', }, app: { /** åç«¯è·¯ç±æ¨¡å¼ */ accessMode: 'backend', src/styles/herbal-theme.css
ÎļþÒÑɾ³ý src/views/_core/authentication/login.vue
@@ -126,7 +126,7 @@ </script> <template> <div class="herbal-login"> <div> <AuthenticationLogin ref="loginRef" :form-schema="formSchema" @@ -138,14 +138,7 @@ :show-forget-password="false" :show-doc-link="false" @submit="handleLogin" > <template #title> <div class="herbal-login__heading"> <h1>{{ $t('authentication.welcomeBack') }}<svg class="herbal-login__seal" viewBox="0 0 20 30" aria-hidden="true"><rect x="1" y="1" width="18" height="28" rx="2"/><path d="M5 5h10v8H5V5Zm0 12h10v8H5v-8Zm5-12v8m0 4v8"/></svg></h1> <p>{{ $t('authentication.loginSubtitle') }}</p> </div> </template> </AuthenticationLogin> /> <Verification ref="verifyRef" v-if="captchaEnable" @@ -158,24 +151,3 @@ /> </div> </template> <style scoped> .herbal-login__heading{margin-bottom:32px} .herbal-login__heading h1{font-size:clamp(28px,2.4vw,36px);font-weight:700;line-height:1.4;letter-spacing:-.02em;margin:0 0 12px;color:#29251f;display:flex;align-items:center;gap:14px} .herbal-login__heading p{font-size:15px;line-height:1.7;color:#756d63;margin:0} .herbal-login__seal{width:20px;height:30px;flex-shrink:0;color:#a51d24;fill:none;stroke:currentColor;stroke-width:1.2} .herbal-login :deep(input:not([type='checkbox'])){min-height:56px;border-radius:9px;border:1px solid #ddd6cc;background:rgba(255,255,255,.82);padding:12px 16px;font-size:16px;color:#30281f} .herbal-login :deep(input::placeholder){color:#7a7167;opacity:1} .herbal-login :deep(input:focus-visible){outline:2px solid #a51d24;outline-offset:3px} .herbal-login :deep(input[autocomplete='current-password']){padding-right:44px} .herbal-login :deep(button[aria-label='login']){min-height:58px;margin-top:8px;border-radius:9px;background:#a51d24;color:#fff;font-size:19px;font-weight:600;letter-spacing:.12em;box-shadow:0 5px 12px rgba(137,24,30,.12)} .herbal-login :deep(button[aria-label='login']:hover){background:#87171d} .herbal-login :deep(button[aria-label='login']:focus-visible){outline:2px solid #a51d24;outline-offset:4px} .herbal-login :deep(button[aria-label='login']:disabled){opacity:.65;cursor:wait} :global(.dark .herbal-login__heading h1){color:#f5eee4} :global(.dark .herbal-login__heading p){color:#d1c1ae} :global(.dark .herbal-login__seal){color:#eea5a4} :global(.dark .herbal-login input:not([type='checkbox'])){background:#302720;border-color:#6f5b48;color:#f5eee4} :global(.dark .herbal-login input::placeholder){color:#c2b29e} @media(max-width:540px){.herbal-login__heading h1{font-size:28px}.herbal-login__heading p{font-size:14px}.herbal-login :deep(input:not([type='checkbox'])){min-height:52px}} </style>