Appearance
AiFilePreview
AiFilePreview 是文件在线预览统一入口。它会根据文件类型或 provider 选择 PDF.js、OnlyOffice 或 unsupported fallback,并把 PDF 定位、搜索、缩略图和标注能力统一暴露给 Vue3 与 Vue2 SDK。
使用场景
- PDF 合同、报告、资料的前端预览、搜索和实体定位。
- Word、Excel、PPT 等 Office 文件通过后端生成 OnlyOffice 会话后预览。
- Vue2 存量页面通过 Lingxi SDK 挂载 Vue3 预览组件。
- 业务需要把实体列表、知识点、引用来源和 PDF bbox 高亮联动。
基础用法
vue
<script setup lang="ts">
import { ref } from 'vue'
import { AiFilePreview } from '@zhiyongui/lingxi-ui'
import '@zhiyongui/lingxi-ui/ai-file-preview/style.css'
const activeLocationId = ref('loc-contract-no')
const locations = [
{
id: 'loc-contract-no',
entityId: 'contract-no',
page: 1,
text: '合同编号',
bbox: [0.12, 0.18, 0.31, 0.22],
},
]
</script>
<template>
<AiFilePreview
file-id="contract-1"
provider="pdfjs"
:session="{ provider: 'pdfjs', url: '/files/demo.pdf' }"
:pdf-locations="locations"
:active-location-id="activeLocationId"
show-pdf-search
show-pdf-thumbnails
@location-click="activeLocationId = $event.id"
/>
</template>Vue2 SDK 用法
Vue2 页面必须在页面销毁时调用 unmount,Vue2 数据变化后用 instance.update 同步给 Vue3 组件,事件通过 onXxx props 传入。
js
import { mountLingxiComponent } from '@zhiyongui/lingxi-ui/sdk'
import { AiFilePreview } from '@zhiyongui/lingxi-ui'
import '@zhiyongui/lingxi-ui/ai-file-preview/style.css'
export default {
data() {
return {
instance: null,
activeLocationId: 'loc-1',
locations: [{ id: 'loc-1', page: 1, text: '金额', bbox: [0.2, 0.3, 0.4, 0.34] }],
}
},
mounted() {
this.instance = mountLingxiComponent(AiFilePreview, {
container: this.$refs.preview,
props: {
provider: 'pdfjs',
fileId: 'contract-1',
session: { provider: 'pdfjs', url: '/files/demo.pdf' },
pdfLocations: this.locations,
activeLocationId: this.activeLocationId,
showPdfSearch: true,
onLocationClick: (location) => {
this.activeLocationId = location.id
this.instance.update({ activeLocationId: location.id })
},
},
})
},
beforeDestroy() {
this.instance && this.instance.unmount()
},
methods: {
focusLocation(id) {
this.activeLocationId = id
this.instance.update({ activeLocationId: id })
this.instance.callMethod('scrollToLocation', id, { block: 'center', flash: true })
},
},
}html
<div ref="preview"></div>PDF 示例
PDF 能力依赖 pdfjs-dist。如果只使用 OnlyOffice,可以不安装 PDF 运行时。
bash
npm install pdfjs-dist完整示例包含 PDF 定位、搜索、缩略图、debug bbox、标注草稿和 Vue2 SDK 调用。
OnlyOffice 示例
生产环境中,OnlyOffice 的 document.key、document.url、callbackUrl、token 应由后端生成,前端只透传 documentServerUrl 和 config。
自定义 Provider 示例
sessionLoader 可以接入业务后端。返回 pdfjs 会话时由前端 PDF.js 渲染;返回 onlyoffice 会话时加载 OnlyOffice;无法预览时返回 unsupported fallback 或把 provider 设为 unsupported。
ts
const sessionLoader = async (fileId: string | number) => {
const res = await fetch(`/api/files/${fileId}/preview-session`)
if (!res.ok) throw new Error('Load preview session failed')
return await res.json()
}Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
file | AiPreviewFile | undefined | 文件基础信息。 |
fileId | string | number | undefined | 用于 sessionLoader 请求会话。 |
provider | 'auto' | 'onlyoffice' | 'pdfjs' | 'unsupported' | 'auto' | 预览方式。 |
session | AiFilePreviewSession | undefined | 外部直接传入的预览会话。 |
sessionLoader | (fileId, file?) => Promise<AiFilePreviewSession> | undefined | 异步加载预览会话。 |
pdfLocations | AiPdfLocation[] | [] | PDF 业务定位和 bbox 高亮列表。 |
activeLocationId | string | undefined | 当前激活的 PDF 定位。 |
pdfScale | 'page-width' | 'page-fit' | number | 'page-width' | PDF 缩放模式。 |
pdfMinScale | number | 0.5 | PDF 最小缩放。 |
pdfMaxScale | number | 2.5 | PDF 最大缩放。 |
pdfScaleStep | number | 0.2 | 缩放步长。 |
pdfHighlightMode | 'active-only' | 'all' | 'hover' | 'active-only' | bbox 高亮策略。 |
debugLocations | boolean | false | 显示 bbox 调试信息。 |
enablePdfTextLayer | boolean | true | 是否启用 PDF 文本层。 |
showPdfSearch | boolean | false | 是否显示内置 PDF 搜索栏。 |
pdfSearchKeyword | string | '' | 受控搜索关键字。 |
pdfSearchOptions | AiPdfSearchOptions | {} | 搜索选项。 |
showPdfThumbnails | boolean | false | 是否显示缩略图导航。 |
pdfThumbnailPlacement | 'left' | 'bottom' | 'left' | 缩略图位置。 |
enablePdfAnnotation | boolean | false | 是否启用 PDF 标注草稿。 |
showPdfAnnotationToolbar | boolean | 同 enablePdfAnnotation | 是否显示标注工具栏。 |
pdfAnnotationMode | 'none' | 'select-text' | 'draw-box' | 'edit' | 'none' | 标注模式。 |
pdfAnnotationMinBoxSize | number | 6 | 框选生成 bbox 的最小像素尺寸。 |
pdfAnnotationCreateId | (location) => string | undefined | 自定义新建标注 ID。 |
height | string | number | 640 | 预览区域高度。 |
showHeader | boolean | true | 是否显示文件头。 |
showToolbar | boolean | true | 是否显示刷新、下载、返回按钮。 |
labels | AiFilePreviewLabels | undefined | 顶层文案覆盖。 |
onlyOfficeLabels | AiOnlyOfficePreviewLabels | undefined | OnlyOffice 文案覆盖。 |
pdfLabels | AiPdfPreviewLabels | undefined | PDF 文案覆盖。 |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
ready | session | 预览会话加载完成。 |
error | unknown | 会话加载或渲染异常。 |
loading-change | boolean | 加载状态变化。 |
download | AiPreviewFile | 点击下载。 |
back | - | 点击返回。 |
refresh | - | 点击刷新。 |
location-click | AiPdfLocation | 点击 PDF bbox。 |
page-change | number | PDF 当前页变化。 |
pdf-search-change | AiPdfSearchState | 搜索状态变化。 |
pdf-search-match-change | AiPdfSearchMatch | undefined, AiPdfSearchState | 当前搜索命中变化。 |
pdf-annotation-mode-change | AiPdfAnnotationMode | 标注模式变化。 |
pdf-location-create | AiPdfLocationDraft, AiPdfLocationChange | 新建标注草稿。 |
pdf-location-update | AiPdfLocationDraft, AiPdfLocationChange | 更新标注草稿。 |
pdf-location-delete | AiPdfLocationDraft, AiPdfLocationChange | 删除标注草稿。 |
pdf-location-change | AiPdfLocationChange | 标注集合变化。 |
pdf-location-save-request | AiPdfLocationDraft[] | 点击保存,业务侧自行提交后端。 |
Slots
当前无公开 slot。需要自定义文件列表或实体面板时,建议在业务页面外部组合,并通过 activeLocationId、location-click 和 expose 方法联动。
Exposes
| 方法 | 参数 | 说明 |
|---|---|---|
refresh() | - | 重新加载预览会话。 |
scrollToPage(page, options?) | number, AiPdfScrollOptions | 滚动到 PDF 指定页。 |
scrollToLocation(locationId, options?) | string, AiPdfScrollOptions | 滚动到 PDF 指定定位。 |
highlightLocation(locationId, options?) | string, { flash?: boolean } | 激活指定定位。 |
resetPdfScale() | - | 重置 PDF 缩放。 |
searchPdf(keyword, options?) | string, AiPdfSearchOptions | 搜索 PDF 文本。 |
findNextPdfMatch() | - | 定位下一条搜索命中。 |
findPrevPdfMatch() | - | 定位上一条搜索命中。 |
clearPdfSearch() | - | 清空 PDF 搜索状态。 |
togglePdfFullscreen() | - | 切换 PDF 全屏。 |
setPdfAnnotationMode(mode) | AiPdfAnnotationMode | 设置标注模式。 |
createPdfLocationFromSelection() | - | 从当前文本选择生成标注。 |
updatePdfLocation(locationId, patch) | string, Partial<AiPdfLocation> | 更新标注草稿。 |
deletePdfLocation(locationId) | string | 删除标注草稿。 |
resetPdfLocationDrafts() | - | 恢复到 pdfLocations 初始状态。 |
getPdfLocationDrafts() | - | 获取当前全部标注草稿。 |
样式入口
| 接入方式 | 样式 |
|---|---|
| 全量包 | import '@zhiyongui/lingxi-ui/style.css' |
| 按需包 | import '@zhiyongui/lingxi-ui/ai-file-preview/style.css' |
| IIFE | 加载 lingxi-file-preview.css |
常见问题
PDF 搜索为什么没有命中?
搜索依赖 PDF 内置文本层。扫描件没有文本时不会自动 OCR;可以用 enablePdfAnnotation 的框选模式创建业务 bbox。
为什么 Vue2 修改数据后组件没有更新?
Vue2 外层数据变化不会自动同步到 Vue3 子应用。更新数组、对象或选中 ID 后必须调用 instance.update({ ...props })。
OnlyOffice 配置应该放在哪里生成?
生产环境必须由后端生成 OnlyOffice config 和 token,前端只负责透传和挂载。