chore: upgrade onlyoffice to 9.2.1

This commit is contained in:
liaibo
2025-12-26 07:52:40 +08:00
parent 8356734742
commit 9bd5c9c403
8 changed files with 364 additions and 12 deletions
@@ -94,7 +94,20 @@ const MediaBlockContent = ({ block, editor }: MediaBlockRenderProps) => {
const displayFileName = block.props.fileName ?? deriveFileName(fileUrl);
const captionRef = useRef<HTMLInputElement | null>(null);
const [captionEditing, setCaptionEditing] = useState(false);
const shouldShowCaption = captionEditing || Boolean(block.props.caption);
const shouldShowCaption = captionEditing || Boolean(block.props.caption);
const officeBase = process.env.NEXT_PUBLIC_ONLYOFFICE_BASE_URL;
const extension = useMemo(() => {
const name = (block.props.fileName || deriveFileName(fileUrl)).toLowerCase();
const match = /\.([a-z0-9]+)$/.exec(name);
return match?.[1] ?? "";
}, [block.props.fileName, fileUrl]);
const isOfficeDoc = useMemo(
() =>
["doc", "docx", "ppt", "pptx", "xls", "xlsx", "odp", "ods", "odt"].includes(
extension,
),
[extension],
);
const handleChoose = () => {
openPicker({
@@ -207,11 +220,38 @@ const MediaBlockContent = ({ block, editor }: MediaBlockRenderProps) => {
window.open(fileUrl, "_blank", "noopener,noreferrer");
};
const openWithOnlyOffice = async () => {
if (!fileUrl) return;
if (!officeBase) {
window.alert("缺少 ONLYOFFICE 地址,请在 .env.local 配置 NEXT_PUBLIC_ONLYOFFICE_BASE_URL");
return;
}
try {
const res = await fetch(
`/api/media/signed-url?fileUrl=${encodeURIComponent(fileUrl)}&fileName=${encodeURIComponent(
displayFileName,
)}&for=onlyoffice`,
);
if (!res.ok) {
const payload = await res.json().catch(() => null);
throw new Error(payload?.error ?? "生成签名链接失败");
}
const { signedUrl } = (await res.json()) as { signedUrl: string };
const target = new URL("/onlyoffice", window.location.origin);
target.searchParams.set("fileUrl", signedUrl);
target.searchParams.set("fileName", displayFileName);
target.searchParams.set("fileType", extension || "docx");
window.open(target.toString(), "_blank", "noopener,noreferrer");
} catch (error) {
window.alert((error as Error).message);
}
};
const downloadAsset = () => {
if (!fileUrl) return;
const anchor = document.createElement("a");
anchor.href = fileUrl;
anchor.download = block.props.fileName || block.props.caption || typeLabel;
anchor.download = block.props.fileName || block.props.caption || typeLabel;
anchor.click();
};
@@ -278,7 +318,7 @@ const MediaBlockContent = ({ block, editor }: MediaBlockRenderProps) => {
if (assetType === "file") {
return (
<div className="flex items-center gap-3 rounded-2xl border border-gray-200 bg-white p-4 shadow-sm">
<span className="rounded-full bg-[#2563eb]/10 p-3 text-[#2563eb]">
<span className="rounded-full bg-[#2563eb]/10 p-3 text-[#2563eb]">
<Paperclip className="h-5 w-5" />
</span>
<div className="flex-1">
@@ -361,7 +401,17 @@ const MediaBlockContent = ({ block, editor }: MediaBlockRenderProps) => {
return (
<div className="wolai-media" ref={mediaRef}>
<div className="wolai-media__canvas" style={resolvedWidth ? { width: `${resolvedWidth}px` } : undefined}>
<div
className="wolai-media__canvas"
style={resolvedWidth ? { width: `${resolvedWidth}px` } : undefined}
onDoubleClick={() => {
if (assetType === "file" && isOfficeDoc) {
void openWithOnlyOffice();
} else if (assetType === "file") {
viewOriginal();
}
}}
>
{block.props.linkUrl ? (
<a href={block.props.linkUrl} target="_blank" rel="noopener noreferrer">
{figure}
@@ -410,6 +460,9 @@ const MediaBlockContent = ({ block, editor }: MediaBlockRenderProps) => {
<DropdownMenuItem onClick={handleLink}>{dropdownLinkLabel}</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleCopyLink(fileUrl)}></DropdownMenuItem>
<DropdownMenuItem onClick={viewOriginal}></DropdownMenuItem>
{assetType === "file" && isOfficeDoc && (
<DropdownMenuItem onClick={() => void openWithOnlyOffice()}>使 ONLYOFFICE </DropdownMenuItem>
)}
<DropdownMenuItem onClick={downloadAsset}></DropdownMenuItem>
{canTriggerOcr && (
<>