diff --git a/easyflow-ui-admin/app/src/components/collapseViewItem/CollapseViewItem.vue b/easyflow-ui-admin/app/src/components/collapseViewItem/CollapseViewItem.vue index b9e03c9..9485eff 100644 --- a/easyflow-ui-admin/app/src/components/collapseViewItem/CollapseViewItem.vue +++ b/easyflow-ui-admin/app/src/components/collapseViewItem/CollapseViewItem.vue @@ -19,6 +19,7 @@ const props = defineProps({ }, }); const emits = defineEmits(['delete']); +const fallbackAvatarUrl = `${import.meta.env.BASE_URL || '/'}favicon.svg`; const handleDelete = (item: any) => { ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), { confirmButtonText: $t('button.confirm'), @@ -40,7 +41,7 @@ const handleDelete = (item: any) => {
- +
{{ item[titleKey] }}
diff --git a/easyflow-ui-admin/app/src/components/commonSelectModal/CommonSelectDataModal.vue b/easyflow-ui-admin/app/src/components/commonSelectModal/CommonSelectDataModal.vue index aeee7b8..b1fa3f6 100644 --- a/easyflow-ui-admin/app/src/components/commonSelectModal/CommonSelectDataModal.vue +++ b/easyflow-ui-admin/app/src/components/commonSelectModal/CommonSelectDataModal.vue @@ -57,6 +57,7 @@ const emit = defineEmits(['getData', 'buttonClick']); const dialogVisible = ref(false); const pageDataRef = ref(); const loading = ref(false); +const fallbackAvatarUrl = `${import.meta.env.BASE_URL || '/'}favicon.svg`; const selectedIds = ref<(number | string)[]>([]); // 存储上一级id与选中tool.name的关联关系 const selectedToolMap = ref>({}); @@ -231,7 +232,11 @@ const handleSearch = (query: string) => { >
- +
@@ -326,7 +331,11 @@ const handleSearch = (query: string) => {
- +
diff --git a/easyflow-ui-admin/app/src/views/_core/authentication/login.vue b/easyflow-ui-admin/app/src/views/_core/authentication/login.vue index 92d9568..dae53a8 100644 --- a/easyflow-ui-admin/app/src/views/_core/authentication/login.vue +++ b/easyflow-ui-admin/app/src/views/_core/authentication/login.vue @@ -13,6 +13,9 @@ onMounted(() => {}); const authStore = useAuthStore(); const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); +const assetBase = import.meta.env.BASE_URL || '/'; +const captchaAssetBase = `${assetBase}tac`; +const captchaButtonUrl = `${assetBase}tac-btn.png`; const formSchema = computed((): EasyFlowFormSchema[] => { return [ @@ -71,11 +74,11 @@ function onSubmit(values: any) { const style = { logoUrl: null, // 去除logo // logoUrl: "/xx/xx/xxx.png" // 替换成自定义的logo - btnUrl: '/tac-btn.png', + btnUrl: captchaButtonUrl, }; window // @ts-ignore - .initTAC('/tac', config, style) + .initTAC(captchaAssetBase, config, style) .then((tac: any) => { tac.init(); // 调用init则显示验证码 }) diff --git a/easyflow-ui-admin/app/src/views/ai/model/modelUtils/defaultIcon.ts b/easyflow-ui-admin/app/src/views/ai/model/modelUtils/defaultIcon.ts index 0984990..6642f7f 100644 --- a/easyflow-ui-admin/app/src/views/ai/model/modelUtils/defaultIcon.ts +++ b/easyflow-ui-admin/app/src/views/ai/model/modelUtils/defaultIcon.ts @@ -1,5 +1,7 @@ import providerList from './providerList.json'; +const assetBase = import.meta.env.BASE_URL || '/'; + export interface ProviderModelPreset { description: string; label: string; @@ -28,8 +30,25 @@ export interface ProviderPreset { const providerOptions = providerList as ProviderPreset[]; -export const getProviderPresetByValue = (targetValue?: string) => - providerOptions.find((item) => item.value === targetValue); +const normalizeAssetUrl = (url?: string) => { + if (!url || !url.startsWith('/')) { + return url || ''; + } + return `${assetBase}${url.slice(1)}`; +}; + +export const getProviderPresetByValue = (targetValue?: string) => { + const preset = providerOptions.find((item) => item.value === targetValue); + + if (!preset) { + return undefined; + } + + return { + ...preset, + icon: normalizeAssetUrl(preset.icon), + }; +}; /** * 根据传入的value,返回对应的icon属性 @@ -63,4 +82,7 @@ export const getProviderBadgeText = ( return source.replaceAll(/\s+/g, '').slice(0, 2).toUpperCase(); }; -export const providerPresets = providerOptions; +export const providerPresets = providerOptions.map((item) => ({ + ...item, + icon: normalizeAssetUrl(item.icon), +})); diff --git a/easyflow-ui-admin/packages/@core/preferences/src/config.ts b/easyflow-ui-admin/packages/@core/preferences/src/config.ts index d1c0d68..3596b47 100644 --- a/easyflow-ui-admin/packages/@core/preferences/src/config.ts +++ b/easyflow-ui-admin/packages/@core/preferences/src/config.ts @@ -142,7 +142,7 @@ const defaultPreferences: Preferences = { timezone: false, }, auth: { - sloganImage: '/slogan.svg', + sloganImage: `${assetBase}slogan.svg`, pageTitle: '', pageDescription: '', welcomeBack: '', diff --git a/easyflow-ui-usercenter/app/src/components/json/ShowJson.vue b/easyflow-ui-usercenter/app/src/components/json/ShowJson.vue index 6bfe22c..a864d49 100644 --- a/easyflow-ui-usercenter/app/src/components/json/ShowJson.vue +++ b/easyflow-ui-usercenter/app/src/components/json/ShowJson.vue @@ -14,6 +14,7 @@ defineProps({ }, }); +const emptyImageUrl = `${import.meta.env.BASE_URL || '/'}empty.png`; const themeMode = ref(preferences.theme.mode); watch( () => preferences.theme.mode, @@ -26,7 +27,7 @@ watch( diff --git a/easyflow-ui-usercenter/app/src/components/page/PageData.vue b/easyflow-ui-usercenter/app/src/components/page/PageData.vue index 2f14aaa..9905d19 100644 --- a/easyflow-ui-usercenter/app/src/components/page/PageData.vue +++ b/easyflow-ui-usercenter/app/src/components/page/PageData.vue @@ -17,6 +17,7 @@ const props = withDefaults(defineProps(), { pageSizes: () => [10, 20, 50, 100], extraQueryParams: () => ({}), }); +const emptyImageUrl = `${import.meta.env.BASE_URL || '/'}empty.png`; // 响应式数据 const pageList = ref([]); @@ -119,6 +120,6 @@ onMounted(() => { />
- +
diff --git a/easyflow-ui-usercenter/app/src/views/_core/authentication/login.vue b/easyflow-ui-usercenter/app/src/views/_core/authentication/login.vue index 392c5d4..c96087c 100644 --- a/easyflow-ui-usercenter/app/src/views/_core/authentication/login.vue +++ b/easyflow-ui-usercenter/app/src/views/_core/authentication/login.vue @@ -12,6 +12,9 @@ import { useAuthStore } from '#/store'; defineOptions({ name: 'Login' }); const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); const authStore = useAuthStore(); +const assetBase = import.meta.env.BASE_URL || '/'; +const captchaAssetBase = `${assetBase}tac`; +const captchaButtonUrl = `${assetBase}tac-btn.png`; const formSchema = computed((): EasyFlowFormSchema[] => { return [ @@ -69,11 +72,11 @@ function onSubmit(values: any) { const style = { logoUrl: null, // 去除logo // logoUrl: "/xx/xx/xxx.png" // 替换成自定义的logo - btnUrl: '/tac-btn.png', + btnUrl: captchaButtonUrl, }; window // @ts-ignore - .initTAC('/tac', config, style) + .initTAC(captchaAssetBase, config, style) .then((tac: any) => { tac.init(); // 调用init则显示验证码 }) diff --git a/easyflow-ui-usercenter/app/src/views/ai/workflow/components/ExecResult.vue b/easyflow-ui-usercenter/app/src/views/ai/workflow/components/ExecResult.vue index 255beb0..fbe41c8 100644 --- a/easyflow-ui-usercenter/app/src/views/ai/workflow/components/ExecResult.vue +++ b/easyflow-ui-usercenter/app/src/views/ai/workflow/components/ExecResult.vue @@ -19,6 +19,7 @@ const props = withDefaults(defineProps(), { showMessage: true, pollingData: {}, }); +const emptyImageUrl = `${import.meta.env.BASE_URL || '/'}empty.png`; const finalNode = computed(() => { const nodes = props.nodeJson; @@ -93,7 +94,7 @@ function getResult(res: any) {
- +
diff --git a/easyflow-ui-usercenter/app/src/views/chatHistory/share/index.vue b/easyflow-ui-usercenter/app/src/views/chatHistory/share/index.vue index e592a70..3d2d843 100644 --- a/easyflow-ui-usercenter/app/src/views/chatHistory/share/index.vue +++ b/easyflow-ui-usercenter/app/src/views/chatHistory/share/index.vue @@ -16,6 +16,7 @@ const ids = reactive({ const conversationInfo = ref(); const messageList = ref([]); const loading = ref(true); +const logoUrl = `${import.meta.env.BASE_URL || '/'}logo.svg`; onMounted(() => { if (route.params.id) { @@ -80,7 +81,7 @@ function getMessageList() {
- + diff --git a/easyflow-ui-usercenter/internal/vite-config/src/plugins/inject-app-loading/index.ts b/easyflow-ui-usercenter/internal/vite-config/src/plugins/inject-app-loading/index.ts index 6aa8862..1923a56 100644 --- a/easyflow-ui-usercenter/internal/vite-config/src/plugins/inject-app-loading/index.ts +++ b/easyflow-ui-usercenter/internal/vite-config/src/plugins/inject-app-loading/index.ts @@ -20,6 +20,7 @@ async function viteInjectAppLoadingPlugin( const { version } = await readPackageJSON(process.cwd()); const envRaw = isBuild ? 'prod' : 'dev'; const cacheName = `'${env.VITE_APP_NAMESPACE}-${version}-${envRaw}-preferences-theme'`; + const appBase = JSON.stringify(ensureTrailingSlash(env.VITE_BASE || '/')); // 获取缓存的主题 // 保证黑暗主题下,刷新页面时,loading也是黑暗主题 @@ -29,7 +30,7 @@ async function viteInjectAppLoadingPlugin( document.documentElement.classList.toggle('dark', /dark/.test(theme)); setTimeout(() => { if (/dark/.test(theme)) { - document.querySelector('#__app-loading__ img').src = '/logoDark.svg'; + document.querySelector('#__app-loading__ img').src = ${appBase} + 'logoDark.svg'; } }) @@ -68,4 +69,8 @@ async function getLoadingRawByHtmlTemplate(loadingTemplate: string) { return await fsp.readFile(appLoadingPath, 'utf8'); } +function ensureTrailingSlash(path: string) { + return path.endsWith('/') ? path : `${path}/`; +} + export { viteInjectAppLoadingPlugin }; diff --git a/easyflow-ui-usercenter/packages/@core/preferences/src/config.ts b/easyflow-ui-usercenter/packages/@core/preferences/src/config.ts index 91f6fc0..9925d78 100644 --- a/easyflow-ui-usercenter/packages/@core/preferences/src/config.ts +++ b/easyflow-ui-usercenter/packages/@core/preferences/src/config.ts @@ -1,5 +1,7 @@ import type { Preferences } from './types'; +const assetBase = import.meta.env.BASE_URL || '/'; + const defaultPreferences: Preferences = { app: { accessMode: 'frontend', @@ -65,8 +67,9 @@ const defaultPreferences: Preferences = { logo: { enable: true, fit: 'contain', - source: '/logo.svg', - sourceDark: '/logoDark.svg', + source: `${assetBase}logo.svg`, + sourceDark: `${assetBase}logoDark.svg`, + sourceMini: `${assetBase}logoMini.svg`, }, navigation: { accordion: true, diff --git a/easyflow-ui-usercenter/packages/@core/preferences/src/types.ts b/easyflow-ui-usercenter/packages/@core/preferences/src/types.ts index cf0206c..9f36261 100644 --- a/easyflow-ui-usercenter/packages/@core/preferences/src/types.ts +++ b/easyflow-ui-usercenter/packages/@core/preferences/src/types.ts @@ -148,6 +148,10 @@ interface LogoPreferences { source: string; /** 暗色主题logo地址 (可选,若不设置则使用 source) */ sourceDark?: string; + /** 侧边栏收起时 logo 地址 (可选,若不设置则使用 source) */ + sourceMini?: string; + /** 暗色主题下侧边栏收起 logo 地址 (可选,若不设置则按 sourceMini/sourceDark/source 回退) */ + sourceMiniDark?: string; } interface NavigationPreferences { diff --git a/easyflow-ui-usercenter/packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue b/easyflow-ui-usercenter/packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue index 3d7ba61..c430e15 100644 --- a/easyflow-ui-usercenter/packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue +++ b/easyflow-ui-usercenter/packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue @@ -30,6 +30,14 @@ interface Props { * @zh_CN 暗色主题 Logo 图标 (可选,若不设置则使用 src) */ srcDark?: string; + /** + * @zh_CN 侧边栏收起时 Logo 图标 (可选,若不设置则使用 src) + */ + srcMini?: string; + /** + * @zh_CN 暗色主题下侧边栏收起时 Logo 图标 (可选,若不设置则按 srcMini/srcDark/src 回退) + */ + srcMiniDark?: string; /** * @zh_CN Logo 文本 */ @@ -50,6 +58,8 @@ const props = withDefaults(defineProps(), { logoSize: 120, src: '', srcDark: '', + srcMini: '', + srcMiniDark: '', theme: 'light', fit: 'cover', }); @@ -59,7 +69,10 @@ const props = withDefaults(defineProps(), { */ const logoSrc = computed(() => { if (props.collapsed) { - return '/logoMini.svg'; + if (props.theme === 'dark' && props.srcMiniDark) { + return props.srcMiniDark; + } + return props.srcMini || props.src; } // 如果是暗色主题且提供了 srcDark,则使用暗色主题的 logo if (props.theme === 'dark' && props.srcDark) { diff --git a/easyflow-ui-usercenter/packages/effects/layouts/src/basic/layout.vue b/easyflow-ui-usercenter/packages/effects/layouts/src/basic/layout.vue index 46b4956..7860dc1 100644 --- a/easyflow-ui-usercenter/packages/effects/layouts/src/basic/layout.vue +++ b/easyflow-ui-usercenter/packages/effects/layouts/src/basic/layout.vue @@ -260,6 +260,14 @@ const headerSlots = computed(() => { :collapsed="logoCollapsed" :src="preferences.logo.source" :src-dark="preferences.logo.sourceDark" + :src-mini="preferences.logo.sourceMini ?? preferences.logo.source ?? ''" + :src-mini-dark=" + preferences.logo.sourceMiniDark ?? + preferences.logo.sourceMini ?? + preferences.logo.sourceDark ?? + preferences.logo.source ?? + '' + " :text="preferences.app.name" :theme="showHeaderNav ? headerTheme : theme" @click="clickLogo" @@ -353,6 +361,14 @@ const headerSlots = computed(() => { :fit="preferences.logo.fit" :src="preferences.logo.source" :src-dark="preferences.logo.sourceDark" + :src-mini="preferences.logo.sourceMini ?? preferences.logo.source ?? ''" + :src-mini-dark=" + preferences.logo.sourceMiniDark ?? + preferences.logo.sourceMini ?? + preferences.logo.sourceDark ?? + preferences.logo.source ?? + '' + " :text="preferences.app.name" :theme="theme" >