feat(web-admin): add OaAppIcon display for ep and image URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-06 13:07:25 +08:00
1 parent bfb495ee77
commit e4279dc953
1 file changed
+75
@@ -0,0 +1,75 @@
<template>
<span class="oa-app-icon" :class="`oa-app-icon--${size}`" :style="boxStyle">
<el-icon v-if="resolved.kind === 'ep'" :style="{ color: resolved.fg }">
<component :is="epComponent" />
</el-icon>
<img v-else :src="resolved.src" alt="" />
</span>
</template>
<script setup lang="ts">
import { computed, type Component } from 'vue'
import * as EpIcons from '@element-plus/icons-vue'
import { OA_APP_DEFAULT_EP_ICON, resolveOaAppIcon } from '@/utils/oa-app-icons'
const props = withDefaults(
defineProps<{
iconUrl?: string | null
/** sm=32 card, md=56 dialog */
size?: 'sm' | 'md'
}>(),
{ size: 'sm' }
)
const resolved = computed(() => resolveOaAppIcon(props.iconUrl))
const epComponent = computed<Component>(() => {
if (resolved.value.kind !== 'ep') return (EpIcons as any)[OA_APP_DEFAULT_EP_ICON]
const name = resolved.value.icon
return (EpIcons as any)[name] || (EpIcons as any)[OA_APP_DEFAULT_EP_ICON]
})
const boxStyle = computed(() => {
if (resolved.value.kind === 'ep') {
return { background: resolved.value.bg, color: resolved.value.fg }
}
return {}
})
</script>
<style scoped lang="scss">
.oa-app-icon {
display: grid;
flex-shrink: 0;
place-items: center;
overflow: hidden;
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
}
.oa-app-icon--sm {
width: 32px;
height: 32px;
border-radius: 8px;
.el-icon {
font-size: 16px;
}
}
.oa-app-icon--md {
width: 56px;
height: 56px;
border-radius: 12px;
box-shadow: 0 1px 3px rgb(15 23 42 / 8%);
.el-icon {
font-size: 26px;
}
}
</style>