feat(data-process): 增加 Office 原文件预览接口
This commit is contained in:
@@ -6,6 +6,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from docx import Document as WordDocument
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from openpyxl import Workbook
|
||||
@@ -1546,11 +1547,112 @@ def test_xlsx_upload_is_accepted_as_structured_records(tmp_path: Path) -> None:
|
||||
)
|
||||
assert content.status_code == 200
|
||||
assert '"answer":"答案二"' in content.json()["data"]["content"]
|
||||
office_preview_url = (
|
||||
f"/modelTF/data-process/{task_id}/source-files/{source['id']}/office-preview"
|
||||
)
|
||||
first_page = client.get(office_preview_url, params={"offset": 0, "limit": 1})
|
||||
assert first_page.status_code == 200
|
||||
preview_data = first_page.json()["data"]
|
||||
assert preview_data["format"] == "xlsx"
|
||||
assert preview_data["sheets"] == [{"index": 0, "name": "Sheet", "state": "visible"}]
|
||||
assert preview_data["active_sheet"]["columns"] == ["question", "answer"]
|
||||
assert preview_data["active_sheet"]["rows"][0]["record"] == {
|
||||
"question": "问题一",
|
||||
"answer": "答案一",
|
||||
}
|
||||
assert preview_data["active_sheet"]["has_more"] is True
|
||||
|
||||
second_page = client.get(office_preview_url, params={"offset": 1, "limit": 1})
|
||||
assert second_page.status_code == 200
|
||||
assert second_page.json()["data"]["active_sheet"]["rows"][0]["record"] == {
|
||||
"question": "问题二",
|
||||
"answer": "答案二",
|
||||
}
|
||||
assert second_page.json()["data"]["active_sheet"]["has_more"] is False
|
||||
|
||||
raw_preview = client.get(
|
||||
f"/modelTF/data-process/{task_id}/source-files/{source['id']}/raw"
|
||||
)
|
||||
assert raw_preview.status_code == 200
|
||||
assert raw_preview.content == original_bytes
|
||||
assert raw_preview.headers["content-type"].startswith(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
)
|
||||
preview = client.post(f"/modelTF/data-process/{task_id}/preview/build")
|
||||
assert preview.status_code == 200
|
||||
assert preview.json()["data"]["total"] == 2
|
||||
|
||||
|
||||
def test_docx_preview_preserves_document_block_order_and_source_offsets(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
client, store, _ = make_client(tmp_path)
|
||||
task_id = client.post(
|
||||
"/modelTF/data-process",
|
||||
json={"name": "Word 原件预览", "process_type": "unstructured", "config": {}},
|
||||
).json()["data"]["id"]
|
||||
document = WordDocument()
|
||||
document.add_heading("费用管理办法", level=1)
|
||||
document.add_paragraph("第一条 本办法用于规范费用报销。")
|
||||
table = document.add_table(rows=2, cols=2)
|
||||
table.cell(0, 0).text = "费用类型"
|
||||
table.cell(0, 1).text = "审批人"
|
||||
table.cell(1, 0).text = "差旅费"
|
||||
table.cell(1, 1).text = "部门负责人"
|
||||
output = BytesIO()
|
||||
document.save(output)
|
||||
original_bytes = output.getvalue()
|
||||
|
||||
uploaded = client.post(
|
||||
f"/modelTF/data-process/{task_id}/source-files",
|
||||
files={
|
||||
"files": (
|
||||
"费用 管理.docx",
|
||||
original_bytes,
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
)
|
||||
},
|
||||
).json()["data"]["files"][0]
|
||||
response = client.get(
|
||||
f"/modelTF/data-process/{task_id}/source-files/{uploaded['id']}/office-preview"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()["data"]
|
||||
assert data["format"] == "docx"
|
||||
assert data["file_name"] == "费用 管理.docx"
|
||||
assert data["truncated"] is False
|
||||
assert [block["type"] for block in data["blocks"]] == [
|
||||
"paragraph",
|
||||
"paragraph",
|
||||
"table",
|
||||
]
|
||||
assert data["blocks"][0]["heading_level"] == 1
|
||||
assert data["blocks"][0]["text"] == "费用管理办法"
|
||||
assert data["blocks"][2]["rows"][1]["cells"] == ["差旅费", "部门负责人"]
|
||||
|
||||
source_text = store.get_source_file(task_id, uploaded["id"])["content"]
|
||||
first_paragraph = data["blocks"][0]
|
||||
assert (
|
||||
source_text[first_paragraph["source_start"] : first_paragraph["source_end"]]
|
||||
== first_paragraph["text"]
|
||||
)
|
||||
table_row = data["blocks"][2]["rows"][1]
|
||||
assert (
|
||||
source_text[table_row["source_start"] : table_row["source_end"]]
|
||||
== "\t".join(table_row["cells"])
|
||||
)
|
||||
|
||||
raw_preview = client.get(
|
||||
f"/modelTF/data-process/{task_id}/source-files/{uploaded['id']}/raw"
|
||||
)
|
||||
assert raw_preview.status_code == 200
|
||||
assert raw_preview.content == original_bytes
|
||||
assert raw_preview.headers["content-type"].startswith(
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||
)
|
||||
|
||||
|
||||
def test_pdf_raw_preview_streams_original_file_and_supports_ranges(tmp_path: Path) -> None:
|
||||
client, store, _ = make_client(tmp_path)
|
||||
task_id = client.post(
|
||||
|
||||
Reference in New Issue
Block a user