/* eslint-disable */ import React from 'react'; import { resolveIcon, ResolvedIcon } from './iconRegistry'; // 为了在 useAntdIcon=true 时使用 antd 的 Icon,我们做一个条件导入 // 注意:如果项目没安装 @ant-design/icons,也不会报错,只是返回 undefined type AntdIconType = React.ComponentType<{ component: React.ComponentType; className?: string; style?: React.CSSProperties; }>; function tryLoadAntdIcon(): AntdIconType | undefined { try { const mod = require('@ant-design/icons') as { default?: AntdIconType }; return mod?.default; } catch { return undefined; } } export interface IconProps extends React.ImgHTMLAttributes { userId?: string; productId?: string; // 新增:产品ID module: string; name: string; // e.g. 'icon-nav-back' (不带状态与后缀) theme?: string; size?: '1x' | '2x' | '3x'; state?: string; alt?: string; useAntdIcon?: boolean; // 是否尝试用 @ant-design/icons 包裹 svg widthPx?: number; // 以像素指定大小(覆盖 class 控制) url?: string; // 新增:直接指定图标URL,优先级高于其他图标解析参数 } /** * 自定义 Icon 组件 */ const Icon: React.FC = ({ userId, productId, module, name, theme = 'default', size = '2x', state = 'default', alt, useAntdIcon = true, widthPx, className, style, url, // 新增:解构url属性 ...imgProps }) => { // 新增:优先处理URL图标 if (url) { // 类型安全:确保url是字符串 if (typeof url !== 'string') { console.warn('Icon组件: url属性必须是字符串类型'); return null; } // 基本URL格式验证 try { new URL(url); // 这会验证URL格式,但不要求必须是http/https } catch (e) { // 如果不是有效的URL,可能是相对路径,这是允许的 if (!url.startsWith('/') && !url.startsWith('./') && !url.startsWith('../')) { console.warn('Icon组件: url属性格式无效', url); } } return ( {alt { console.warn('Icon组件: URL图标加载失败', url); // 调用用户提供的onError回调(如果存在) if (imgProps.onError) { imgProps.onError(e); } }} {...imgProps} /> ); } const resolved: ResolvedIcon | undefined = resolveIcon({ userId, productId, module, name, theme, size, state, }); if (!resolved) { // 未找到图标,可以返回 null 或者 fallback return null; } // if (resolved.kind === 'svg') { // console.log(`解析到了svg图标`); // const Svg = resolved.Component; // console.log(`打印一下 resolved.Component 看是什么 === ${Svg}`) // if (useAntdIcon) { // const AntdIcon = tryLoadAntdIcon(); // if (AntdIcon) { // return ( // // ); // } // } // // 没有 antd 或 useAntdIcon=false,则直接渲染 svg // return ( // // ); // } if (resolved.kind === 'svg') { const Svg = resolved.Component; //运行时保护 — 若 resolved.Component 非函数/非组件(意外情况),尝试降级为 if (Svg == null || typeof Svg !== 'function') { // 尝试从 meta.source 拿到可用的 URL(可能是 svg 被打包为 URL 的情况) const maybeSrc = (resolved.meta && (resolved.meta.source as unknown)) ?? null; if (typeof maybeSrc === 'string') { return ( {alt ); } // 无法降级则安全返回 null return null; } if (useAntdIcon) { const AntdIcon = tryLoadAntdIcon(); if (AntdIcon) { return ( ); } } // 直接渲染 svg 组件 return ( ); } // raster 图片 return ( {alt ); }; export default Icon;