zhou zhou
17 小时以前 5454bbe86b1a22e9f05b6bc43f7ed7e9d6c4dc14
rsf-design/src/components/core/base/art-logo/index.vue
@@ -1,14 +1,76 @@
<!-- 系统logo -->
<template>
  <div class="flex-cc">
    <img :style="logoStyle" src="@imgs/common/logo.webp" alt="logo" class="w-full h-full" />
  <div class="flex-cc" :style="wrapperStyle">
    <img :style="logoStyle" :src="logoSrc" alt="logo" class="w-full h-full object-contain" />
  </div>
</template>
<script setup>
  import defaultLogo from '@imgs/common/logo.webp'
  import { fetchPublicProjectLogoConfig } from '@/api/system-manage'
  const PROJECT_LOGO_UPDATED_EVENT = 'project-logo-updated'
  let cachedLogoSrc = ''
  let logoRequest = null
  defineOptions({ name: 'ArtLogo' })
  const props = defineProps({
    size: { required: false, default: 36 }
    size: { required: false, default: 36 },
    fill: { type: Boolean, default: false }
  })
  const logoStyle = computed(() => ({ width: `${props.size}px` }))
  const logoSrc = ref(cachedLogoSrc || defaultLogo)
  const wrapperStyle = computed(() => (props.fill ? { width: '100%', height: '100%' } : {}))
  const logoStyle = computed(() => {
    if (props.fill) {
      return { width: '100%', height: '100%' }
    }
    return { width: resolveLogoSize(props.size) }
  })
  function resolveLogoSize(size) {
    if (typeof size === 'number') return `${size}px`
    const normalizedSize = String(size || '').trim()
    if (!normalizedSize) return '36px'
    return /^\d+(\.\d+)?$/.test(normalizedSize) ? `${normalizedSize}px` : normalizedSize
  }
  function normalizeLogoSrc(value) {
    const normalized = String(value || '').trim()
    return normalized || defaultLogo
  }
  async function loadProjectLogo(force = false) {
    if (cachedLogoSrc && !force) {
      logoSrc.value = cachedLogoSrc
      return
    }
    if (!logoRequest || force) {
      logoRequest = fetchPublicProjectLogoConfig()
        .then((response) => normalizeLogoSrc(response?.val))
        .catch(() => defaultLogo)
        .then((resolvedLogo) => {
          cachedLogoSrc = resolvedLogo
          return resolvedLogo
        })
    }
    logoSrc.value = await logoRequest
  }
  function handleProjectLogoUpdated(event) {
    const nextLogoSrc = normalizeLogoSrc(event?.detail?.url)
    cachedLogoSrc = nextLogoSrc
    logoRequest = Promise.resolve(nextLogoSrc)
    logoSrc.value = nextLogoSrc
  }
  onMounted(() => {
    loadProjectLogo()
    window.addEventListener(PROJECT_LOGO_UPDATED_EVENT, handleProjectLogoUpdated)
  })
  onBeforeUnmount(() => {
    window.removeEventListener(PROJECT_LOGO_UPDATED_EVENT, handleProjectLogoUpdated)
  })
</script>