Skip to content

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.keydocument.urlcallbackUrltoken 应由后端生成,前端只透传 documentServerUrlconfig

自定义 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

属性类型默认值说明
fileAiPreviewFileundefined文件基础信息。
fileIdstring | numberundefined用于 sessionLoader 请求会话。
provider'auto' | 'onlyoffice' | 'pdfjs' | 'unsupported''auto'预览方式。
sessionAiFilePreviewSessionundefined外部直接传入的预览会话。
sessionLoader(fileId, file?) => Promise<AiFilePreviewSession>undefined异步加载预览会话。
pdfLocationsAiPdfLocation[][]PDF 业务定位和 bbox 高亮列表。
activeLocationIdstringundefined当前激活的 PDF 定位。
pdfScale'page-width' | 'page-fit' | number'page-width'PDF 缩放模式。
pdfMinScalenumber0.5PDF 最小缩放。
pdfMaxScalenumber2.5PDF 最大缩放。
pdfScaleStepnumber0.2缩放步长。
pdfHighlightMode'active-only' | 'all' | 'hover''active-only'bbox 高亮策略。
debugLocationsbooleanfalse显示 bbox 调试信息。
enablePdfTextLayerbooleantrue是否启用 PDF 文本层。
showPdfSearchbooleanfalse是否显示内置 PDF 搜索栏。
pdfSearchKeywordstring''受控搜索关键字。
pdfSearchOptionsAiPdfSearchOptions{}搜索选项。
showPdfThumbnailsbooleanfalse是否显示缩略图导航。
pdfThumbnailPlacement'left' | 'bottom''left'缩略图位置。
enablePdfAnnotationbooleanfalse是否启用 PDF 标注草稿。
showPdfAnnotationToolbarbooleanenablePdfAnnotation是否显示标注工具栏。
pdfAnnotationMode'none' | 'select-text' | 'draw-box' | 'edit''none'标注模式。
pdfAnnotationMinBoxSizenumber6框选生成 bbox 的最小像素尺寸。
pdfAnnotationCreateId(location) => stringundefined自定义新建标注 ID。
heightstring | number640预览区域高度。
showHeaderbooleantrue是否显示文件头。
showToolbarbooleantrue是否显示刷新、下载、返回按钮。
labelsAiFilePreviewLabelsundefined顶层文案覆盖。
onlyOfficeLabelsAiOnlyOfficePreviewLabelsundefinedOnlyOffice 文案覆盖。
pdfLabelsAiPdfPreviewLabelsundefinedPDF 文案覆盖。

Events

事件参数说明
readysession预览会话加载完成。
errorunknown会话加载或渲染异常。
loading-changeboolean加载状态变化。
downloadAiPreviewFile点击下载。
back-点击返回。
refresh-点击刷新。
location-clickAiPdfLocation点击 PDF bbox。
page-changenumberPDF 当前页变化。
pdf-search-changeAiPdfSearchState搜索状态变化。
pdf-search-match-changeAiPdfSearchMatch | undefined, AiPdfSearchState当前搜索命中变化。
pdf-annotation-mode-changeAiPdfAnnotationMode标注模式变化。
pdf-location-createAiPdfLocationDraft, AiPdfLocationChange新建标注草稿。
pdf-location-updateAiPdfLocationDraft, AiPdfLocationChange更新标注草稿。
pdf-location-deleteAiPdfLocationDraft, AiPdfLocationChange删除标注草稿。
pdf-location-changeAiPdfLocationChange标注集合变化。
pdf-location-save-requestAiPdfLocationDraft[]点击保存,业务侧自行提交后端。

Slots

当前无公开 slot。需要自定义文件列表或实体面板时,建议在业务页面外部组合,并通过 activeLocationIdlocation-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,前端只负责透传和挂载。