Skip to content

[bug] 知识库上传 .doc(Word 97-2003)文档点预览必然失败:被错误路由到 docx-preview #2155

Closed

Description

@ezjbc

问题描述

知识库中上传 .doc(Word 97-2003 二进制格式)文档后,点击「预览」必然失败,弹窗显示「无法加载预览」,只有「重试 / 下载」两个按钮。

复现步骤

  1. 进入「知识库」,任意知识库上传一个 .doc 文件(Word 97-2003,非 .docx)
  2. 等待解析状态变为 ready
  3. 鼠标悬停该文档卡片,点「预览」

实际行为

弹窗显示「无法加载预览」。Console 报错:

[DocumentPreviewCore] preview failed [object Object]
TypeError: Cannot read properties of undefined (reading 'body')

Network 面板可见请求链:

  • GET /api/knowledge-bases/{kb}/documents/{doc}/file?disposition=inline → 200
  • GET /assets/docx-preview.*.js → 200

即后端已正常返回文件,失败发生在前端富预览渲染阶段。

期望行为

.doc 应降级为「抽取文本预览」,与现有 .ppt 的处理保持一致。

根因

前端把 .doc 与 .docx 当作同一族格式,但两者的容器结构完全不同:

格式 容器 魔数
.docx OOXML(ZIP) 50 4b 03 04
.doc OLE 复合文档 d0 cf 11 e0

docx-preview@^0.3.2 是纯 OOXML 渲染器,只解析 ZIP 内的 word/document.xml,遇到 .doc 无法解析(JSZip 解包直接抛 BadZipFile)。

具体涉及三处:

  1. dashboard/src/utils/knowledgeDocPreview.ts 的 RICH_PREVIEW_EXTS 含 doc
    → canRichPreviewKnowledgeDocument() 返回 true,放行到富预览
  2. dashboard/src/utils/docKind.ts:10:WORD_EXT = new Set(["docx", "doc"])
    → getDocKind() 把 .doc 映射为 "word"
  3. dashboard/src/components/DocumentPreviewCore.tsx 的 word 分支
    → await import("docx-preview") → renderAsync() 解析失败

上游已有先例

knowledgeDocPreview.ts 的 TEXT_PREVIEW_EXTS 里已把 ppt 降级,注释写着:

Legacy PowerPoint: no in-browser slide renderer — use extracted text.

同一份单测 knowledgeDocPreview.test.ts 也断言 a.ppt → false,但紧邻的 a.doc → true 却没有对应降级 —— 说明这是遗漏,不是有意设计。

建议修复

 const RICH_PREVIEW_EXTS = new Set([
   "pdf",
-  "doc",
   "docx",
   "pptx",
   "xls",
   "xlsx",
   "xlsm",
 ]);
   "tsv",
   // Legacy PowerPoint: no in-browser slide renderer — use extracted text.
   "ppt",
+  // Legacy Word (OLE compound document): docx-preview only parses OOXML.
+  "doc",
 ]);

同时把 knowledgeDocPreview.test.ts 中 a.doc 的断言改为 false。

注意:.xls 不应一并降级 —— SheetJS 原生支持 BIFF 格式,.xls 富预览是正常的。

已在实际部署上验证

在 v1.0.2b9 的构建产物上按上述方案打补丁(RICH_PREVIEW_EXTS 移除 doc、TEXT_PREVIEW_EXTS 追加 doc)后实测:

  • .doc《内部审计管理制度》→ 弹窗正常渲染后端抽取文本,Console 零报错
  • .docx《专项工程竣(交)工验收管理细则》→ 仍走 docx-preview,2 页 / 4 张表格 / 8,745 字符,版式完整
  • .xls → 仍走 SheetJS 富预览,未受影响
  • .ppt → 维持原有抽取文本行为

环境

  • Octop 版本:v1.0.2b9
  • 部署方式:Docker(ghcr.nju.edu.cn/tencentcloud/octop:latest)
  • 浏览器:Chrome
  • 影响范围:所有上传 .doc 的用户,与该文件内容无关,100% 复现

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions