import { MoveStyleUtils, Rock, RockChildrenConfig, RockConfig } from "@ruiapp/move-style"; import RapidFileInfoRendererMeta from "./RapidFileInfoRendererMeta"; import type { RapidFileInfoRendererRockConfig } from "./rapid-file-info-renderer-types"; import { renderRock } from "@ruiapp/react-renderer"; import { isArray, isString, merge } from "lodash"; import { RapidFileInfo } from "../rapid-uploader-form-input/rapid-uploader-form-input-types"; import { formatFileSize } from "../../utils/format-utility"; import rapidAppDefinition from "../../rapidAppDefinition"; import { Button, Image, Modal, Space, message } from "antd"; import { useEffect, useState } from "react"; import { EyeOutlined, FilePdfOutlined, FileExcelOutlined, FileWordOutlined, FilePptOutlined, FileImageOutlined } from "@ant-design/icons"; export default { $type: "rapidFileInfoRenderer", Renderer(context, props: RapidFileInfoRendererRockConfig) { const { framework, scope, page } = context; const { value, showFileSize, fileSizeDecimalPlaces } = props; const me = framework.getExpressionVars().me; if (!value) { return null; } if (isArray(value)) { const arrayRendererProps = merge(props.arrayRendererProps || {}, { item: { $type: "rapidFileInfoRenderer", showFileSize, fileSizeDecimalPlaces, showPreview: props.showPreview, previewModalTitle: props.previewModalTitle, previewModalWidth: props.previewModalWidth, useBuiltInPreviewer: props.useBuiltInPreviewer, previewMode: props.previewMode, }, itemContainer: { $type: "box", }, noSeparator: true, }); return renderRock({ context, rockConfig: { $type: "rapidArrayRenderer", ...arrayRendererProps, value, }, }); } else { return ; } }, ...RapidFileInfoRendererMeta, } as Rock; function RenderFileInfo({ fileInfo, showFileSize, fileSizeDecimalPlaces, props, me, }: { fileInfo: RapidFileInfo; showFileSize: boolean | undefined; fileSizeDecimalPlaces: number | undefined; props?: RapidFileInfoRendererRockConfig; me?: any; }) { const [downloadUrl, setDownloadUrl] = useState(null); if (fileInfo && !fileInfo.key) { return ( <> {fileInfo.name.toString()} {showFileSize ? ({formatFileSize(fileInfo.size, fileSizeDecimalPlaces)}) : null} ); } useEffect(() => { const generateUrl = async () => { const userId = me?.profile?.id || 0; const apiBaseUrl = rapidAppDefinition.getApiBaseUrl(); const url = `${apiBaseUrl}/download/file?${fileInfo.id ? `fileId=${fileInfo.id}&` : ``}fileKey=${encodeURIComponent( fileInfo.key, )}&fileName=${encodeURIComponent(fileInfo.name)}`; setDownloadUrl(url); }; generateUrl(); }, [fileInfo.key, fileInfo.name, me?.profile?.id]); if (!downloadUrl) { return null; } // Determine file type for icon selection const fileExt = fileInfo.name.split(".").pop()?.toLowerCase() || ""; const isImage = ["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(fileExt); const isPdf = fileExt === "pdf"; const isExcel = ["xls", "xlsx"].includes(fileExt); const isWord = ["doc", "docx"].includes(fileExt); const isPpt = ["ppt", "pptx"].includes(fileExt); // Get appropriate icon const getIcon = () => { if (isImage) return ; if (isPdf) return ; if (isExcel) return ; if (isWord) return ; if (isPpt) return ; return ; }; // Determine if preview should be shown based on previewMode const previewMode = props?.previewMode || "auto"; let canPreview = false; if (props?.showPreview) { if (previewMode === "auto") { canPreview = isImage || isPdf; } else if (previewMode === "all") { canPreview = true; } else { canPreview = false; } } return ( ); } interface FileItemWithPreviewProps { fileInfo: RapidFileInfo; downloadUrl: string; showFileSize?: boolean; fileSizeDecimalPlaces?: number; canPreview: boolean; isImage: boolean; isPdf: boolean; icon: React.ReactNode; showPreview?: boolean; previewModalTitle?: string; previewModalWidth?: number | string; useBuiltInPreviewer?: boolean; previewMode?: "auto" | "all"; } function FileItemWithPreview(props: FileItemWithPreviewProps) { const { fileInfo, downloadUrl, showFileSize, fileSizeDecimalPlaces, canPreview = true, isImage, isPdf, icon, previewModalTitle = "文件预览", previewModalWidth = 1200, } = props; const [previewVisible, setPreviewVisible] = useState(false); const [previewLoading, setPreviewLoading] = useState(false); const handlePreview = () => { setPreviewVisible(true); }; const getPreviewContent = () => { // const apiBaseUrl = rapidAppDefinition.getApiBaseUrl(); const previewUrl = `${downloadUrl}&inline=true`; if (isImage) { return (
{fileInfo.name}
); } if (isPdf) { return (