// 文档查看器(4.4 → 预览能力收敛):格式渲染统一交给 @ui FilePreview // (md/图片/pdf/代码/数据/docx/xlsx/pptx/URL 一套分派),这里只保留 OverlayHost // 容器、工具栏与文本族的在线编辑保存。 import { useEffect, useState } from 'react' import { api } from '../api' import { store } from '../store' import { OverlayHost, Icon, Btn, FilePreview } from '@ui' import type { Artifact } from '../contracts' import { humanSize } from '../messageparts' export function DocViewer({ artifact }: { artifact: Artifact }) { const [content, setContent] = useState(null) const [editing, setEditing] = useState(false) const [dirty, setDirty] = useState(false) const textKind = isTextKind(artifact) useEffect(() => { if (!textKind) return setContent(null) fetch(api.artifactContentUrl(artifact.id)).then(r => r.text()).then(setContent).catch(() => setContent('(读取失败)')) }, [artifact.id]) const source = { kind: 'artifact' as const, id: artifact.id, name: artifact.name, mime: artifact.mime, contentUrl: api.artifactContentUrl(artifact.id), downloadUrl: api.artifactDownloadUrl(artifact.id), } return ( store.viewArtifact(null)}>
{artifact.kind}{humanSize(artifact.size) ? ` · ${humanSize(artifact.size)}` : ''} {dirty && 未保存} {textKind && ( <> setEditing(e => !e)}>{editing ? '预览' : '编辑'} {editing && { await api.saveArtifactContent(artifact.id, content ?? '') setDirty(false) store.toast('已保存') }}>保存} )} 下载
{editing && textKind ? (