From a2787c51a14ef06584670f4aba2f1e6d8660adde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cls=5F=E5=AE=81=E6=B3=A2=E6=9C=AC=E6=9C=BA?= <908705107@qq.com> Date: Fri, 12 Jun 2026 19:42:38 +0800 Subject: [PATCH] fix: keep admin icons local --- .../zq-form/zq-icon-picker/icons.ts | 41 ++++++++ .../@core/base/icons/src/iconify-icon.ts | 94 +++++++++++++++++++ web/packages/@core/base/icons/src/index.ts | 9 +- .../shadcn-ui/src/components/icon/icon.vue | 37 +------- .../src/components/icon-picker/icons.ts | 41 ++++++++ 5 files changed, 180 insertions(+), 42 deletions(-) create mode 100644 web/packages/@core/base/icons/src/iconify-icon.ts diff --git a/web/apps/web-ele/src/components/zq-form/zq-icon-picker/icons.ts b/web/apps/web-ele/src/components/zq-form/zq-icon-picker/icons.ts index 694e904..909b285 100644 --- a/web/apps/web-ele/src/components/zq-form/zq-icon-picker/icons.ts +++ b/web/apps/web-ele/src/components/zq-form/zq-icon-picker/icons.ts @@ -16,6 +16,43 @@ interface IconifyResponse { const PENDING_REQUESTS: Recordable> = {}; +const LOCAL_ICONS_MAP: Recordable = { + carbon: [ + 'carbon:agent-detached', + 'carbon:align-box-middle-right', + 'carbon:align-vertical-top', + 'carbon:arrange', + 'carbon:arrange-horizontal', + 'carbon:checkmark', + 'carbon:chevron-down', + 'carbon:circle-dash', + 'carbon:close', + 'carbon:edit', + 'carbon:email', + 'carbon:renew', + 'carbon:reset', + 'carbon:user-multiple', + ], + ep: [ + 'ep:caret-right', + 'ep:delete', + 'ep:edit', + 'ep:plus', + 'ep:refresh', + ], + lucide: [ + 'lucide:bot', + 'lucide:check-square', + 'lucide:layout-grid', + 'lucide:library-big', + 'lucide:list', + 'lucide:megaphone', + 'lucide:square-check-big', + 'lucide:square-user', + 'lucide:workflow', + ], +}; + /** * 通过Iconify接口获取图标集数据。 * 同一时间多个图标选择器同时请求同一个图标集时,实际上只会发起一次请求(所有请求共享同一份结果)。 @@ -24,6 +61,10 @@ const PENDING_REQUESTS: Recordable> = {}; * @returns 图标集中包含的所有图标名称 */ export async function fetchIconsData(prefix: string): Promise { + if (LOCAL_ICONS_MAP[prefix]) { + ICONS_MAP[prefix] = LOCAL_ICONS_MAP[prefix]; + return ICONS_MAP[prefix]; + } if (Reflect.has(ICONS_MAP, prefix) && ICONS_MAP[prefix]) { return ICONS_MAP[prefix]; } diff --git a/web/packages/@core/base/icons/src/iconify-icon.ts b/web/packages/@core/base/icons/src/iconify-icon.ts new file mode 100644 index 0000000..2561415 --- /dev/null +++ b/web/packages/@core/base/icons/src/iconify-icon.ts @@ -0,0 +1,94 @@ +import type { Component, PropType } from 'vue'; + +import { defineComponent, h } from 'vue'; + +import { Icon } from '@iconify/vue'; + +import { + AlignEndHorizontal, + AlignHorizontalSpaceAround, + AlignStartVertical, + Bot, + BookOpen, + Check, + CheckCircle, + CheckSquare, + ChevronDown, + ChevronRight, + Circle, + Edit, + LayoutGrid, + List, + Mail, + Megaphone, + Plus, + RefreshCw, + SquareCheckBig, + Trash2, + TriangleAlert, + UserRound, + Users, + Workflow, + X, +} from './lucide'; + +const localIconMap: Record = { + 'carbon:agent-detached': Bot, + 'carbon:align-box-middle-right': AlignEndHorizontal, + 'carbon:align-vertical-top': AlignStartVertical, + 'carbon:arrange': LayoutGrid, + 'carbon:arrange-horizontal': AlignHorizontalSpaceAround, + 'carbon:checkmark': Check, + 'carbon:checkmark-filled': CheckCircle, + 'carbon:chevron-down': ChevronDown, + 'carbon:circle-dash': Circle, + 'carbon:close': X, + 'carbon:edit': Edit, + 'carbon:email': Mail, + 'carbon:renew': RefreshCw, + 'carbon:reset': RefreshCw, + 'carbon:user-multiple': Users, + 'carbon:warning-filled': TriangleAlert, + 'ep:caret-right': ChevronRight, + 'ep:delete': Trash2, + 'ep:edit': Edit, + 'ep:plus': Plus, + 'ep:refresh': RefreshCw, + 'ep:refresh-left': RefreshCw, + 'ep:refresh-right': RefreshCw, + 'lucide:bot': Bot, + 'lucide:check-square': CheckSquare, + 'lucide:layout-grid': LayoutGrid, + 'lucide:library-big': BookOpen, + 'lucide:list': List, + 'lucide:megaphone': Megaphone, + 'lucide:square-check-big': SquareCheckBig, + 'lucide:square-user': UserRound, + 'lucide:workflow': Workflow, +}; + +function normalizeIconName(icon: unknown) { + return typeof icon === 'string' ? icon.replace(/^i-/, '') : ''; +} + +const IconifyIcon = defineComponent({ + inheritAttrs: false, + name: 'IconifyIcon', + props: { + icon: { + type: [String, Object, Function] as PropType, + default: undefined, + }, + }, + setup(props, { attrs }) { + return () => { + const localIcon = localIconMap[normalizeIconName(props.icon)]; + if (localIcon) { + return h(localIcon, attrs); + } + return h(Icon, { ...attrs, icon: props.icon }); + }; + }, +}); + +export { IconifyIcon }; diff --git a/web/packages/@core/base/icons/src/index.ts b/web/packages/@core/base/icons/src/index.ts index 183c45d..09e7f39 100644 --- a/web/packages/@core/base/icons/src/index.ts +++ b/web/packages/@core/base/icons/src/index.ts @@ -1,11 +1,8 @@ export * from './create-icon'; +export * from './iconify-icon'; + export * from './lucide'; export type { IconifyIcon as IconifyIconStructure } from '@iconify/vue'; -export { - addCollection, - addIcon, - Icon as IconifyIcon, - listIcons, -} from '@iconify/vue'; +export { addCollection, addIcon, listIcons } from '@iconify/vue'; diff --git a/web/packages/@core/ui-kit/shadcn-ui/src/components/icon/icon.vue b/web/packages/@core/ui-kit/shadcn-ui/src/components/icon/icon.vue index 16f3e2d..80de0d7 100644 --- a/web/packages/@core/ui-kit/shadcn-ui/src/components/icon/icon.vue +++ b/web/packages/@core/ui-kit/shadcn-ui/src/components/icon/icon.vue @@ -3,21 +3,7 @@ import type { Component } from 'vue'; import { computed } from 'vue'; -import { - AlignEndHorizontal, - AlignHorizontalSpaceAround, - AlignStartVertical, - Bot, - BookOpen, - IconDefault, - IconifyIcon, - LayoutGrid, - Mail, - Megaphone, - UserRound, - Users, - Workflow, -} from '@vben-core/icons'; +import { IconDefault, IconifyIcon } from '@vben-core/icons'; import { isFunction, isHttpUrl, @@ -31,30 +17,10 @@ const props = defineProps<{ icon?: Component | Function | string; }>(); -const localIconMap: Record = { - 'carbon:agent-detached': Bot, - 'carbon:align-box-middle-right': AlignEndHorizontal, - 'carbon:align-vertical-top': AlignStartVertical, - 'carbon:arrange': LayoutGrid, - 'carbon:arrange-horizontal': AlignHorizontalSpaceAround, - 'carbon:email': Mail, - 'carbon:user-multiple': Users, - 'lucide:bot': Bot, - 'lucide:library-big': BookOpen, - 'lucide:megaphone': Megaphone, - 'lucide:square-user': UserRound, - 'lucide:workflow': Workflow, -}; - const isRemoteIcon = computed(() => { return isString(props.icon) && isHttpUrl(props.icon); }); -const localIcon = computed(() => { - if (!isString(props.icon)) return; - return localIconMap[props.icon.replace(/^i-/, '')]; -}); - const isComponent = computed(() => { const { icon } = props; return !isString(icon) && (isObject(icon) || isFunction(icon)); @@ -63,7 +29,6 @@ const isComponent = computed(() => {