From 8a6a6574bb46616dc8367465c51f88feabc77467 Mon Sep 17 00:00:00 2001 From: caoxiaozhu Date: Mon, 27 Jul 2026 16:24:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(data-process):=20=E5=AE=8C=E5=96=84=20Word?= =?UTF-8?q?=20=E4=B8=8E=20Excel=20=E5=8E=9F=E6=96=87=E4=BB=B6=E9=A2=84?= =?UTF-8?q?=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../regression-data-process-wizard.mjs | 22 +- frontend/src/api/modules/dataProcess.ts | 20 + frontend/src/types/dataProcess.ts | 61 ++ .../data-process/DataProcessCreateView.vue | 1 + .../create/OfficeSourceViewer.vue | 622 ++++++++++++++++++ .../create/PreviewCompareStep.vue | 20 +- 6 files changed, 743 insertions(+), 3 deletions(-) create mode 100644 frontend/src/views/data-process/create/OfficeSourceViewer.vue diff --git a/frontend/scripts/regression-data-process-wizard.mjs b/frontend/scripts/regression-data-process-wizard.mjs index defb491..e7a6530 100644 --- a/frontend/scripts/regression-data-process-wizard.mjs +++ b/frontend/scripts/regression-data-process-wizard.mjs @@ -109,16 +109,19 @@ for (const component of expectedComponents) { const typesPath = path.join(createDir, 'types.ts') const modelPath = path.join(createDir, 'previewModel.ts') const pdfViewerPath = path.join(createDir, 'PdfSourceViewer.vue') +const officeViewerPath = path.join(createDir, 'OfficeSourceViewer.vue') const resultEditorPath = path.join(createDir, 'ResultEditorStep.vue') assert.ok(existsSync(typesPath), '缺少向导类型定义') assert.ok(existsSync(modelPath), '缺少来源映射模型') assert.ok(existsSync(pdfViewerPath), '缺少 PDF 原文件预览组件') +assert.ok(existsSync(officeViewerPath), '缺少 Word/XLSX 原文件预览组件') -const [typesSource, modelSource, previewSource, pdfViewerSource, resultEditorSource] = await Promise.all([ +const [typesSource, modelSource, previewSource, pdfViewerSource, officeViewerSource, resultEditorSource] = await Promise.all([ readFile(typesPath, 'utf8'), readFile(modelPath, 'utf8'), readFile(path.join(createDir, 'PreviewCompareStep.vue'), 'utf8'), readFile(pdfViewerPath, 'utf8'), + readFile(officeViewerPath, 'utf8'), readFile(resultEditorPath, 'utf8'), ]) @@ -179,6 +182,8 @@ assert.match(previewSource, /\.preview-editor\s*\{[\s\S]*?flex:\s*1 1 auto[\s\S] assert.match(previewSource, /@media \(max-width: 900px\)/, '第四步缺少窄屏上下布局') assert.match(previewSource, / get( + `/data-process/${encodeURIComponent(taskId)}/source-files/${encodeURIComponent(fileId)}/office-preview`, + params, + { timeout: 60_000 }, +) + export const testDataProcessExternalSource = ( taskId: string | number, payload: DataProcessExternalSourcePayload, diff --git a/frontend/src/types/dataProcess.ts b/frontend/src/types/dataProcess.ts index b4bf17e..a70bf50 100644 --- a/frontend/src/types/dataProcess.ts +++ b/frontend/src/types/dataProcess.ts @@ -129,6 +129,67 @@ export interface DataProcessPdfPages { pages: DataProcessPdfPageRange[] } +export interface DataProcessDocxParagraph { + type: 'paragraph' + text: string + style: string + heading_level: number | null + alignment: 'left' | 'center' | 'right' | 'justify' | 'distribute' + is_list: boolean + source_start: number + source_end: number +} + +export interface DataProcessDocxTableRow { + cells: string[] + source_start: number + source_end: number +} + +export interface DataProcessDocxTable { + type: 'table' + rows: DataProcessDocxTableRow[] +} + +export interface DataProcessDocxPreview { + format: 'docx' + file_name: string + blocks: Array + truncated: boolean +} + +export interface DataProcessXlsxSheet { + index: number + name: string + state: string +} + +export interface DataProcessXlsxPreviewRow { + row_number: number + record_index: number + values: unknown[] + record: Record +} + +export interface DataProcessXlsxActiveSheet { + index: number + name: string + columns: string[] + rows: DataProcessXlsxPreviewRow[] + offset: number + limit: number + has_more: boolean +} + +export interface DataProcessXlsxPreview { + format: 'xlsx' + file_name: string + sheets: DataProcessXlsxSheet[] + active_sheet: DataProcessXlsxActiveSheet +} + +export type DataProcessOfficePreview = DataProcessDocxPreview | DataProcessXlsxPreview + export interface DataProcessExternalSourcePayload { type: 'postgresql' url: string diff --git a/frontend/src/views/data-process/DataProcessCreateView.vue b/frontend/src/views/data-process/DataProcessCreateView.vue index 66f708d..b8d3952 100644 --- a/frontend/src/views/data-process/DataProcessCreateView.vue +++ b/frontend/src/views/data-process/DataProcessCreateView.vue @@ -934,6 +934,7 @@ onMounted(() => { :items="activePreviewItems" :process-type="processType" :file-name="activePreviewFile?.name ?? ''" + :file-format="activePreviewFile?.fileFormat" :task-id="taskId" :source-file-id="activePreviewFile?.sourceFileId ?? activePreviewFile?.uid ?? null" :files="previewFiles" diff --git a/frontend/src/views/data-process/create/OfficeSourceViewer.vue b/frontend/src/views/data-process/create/OfficeSourceViewer.vue new file mode 100644 index 0000000..1dfe363 --- /dev/null +++ b/frontend/src/views/data-process/create/OfficeSourceViewer.vue @@ -0,0 +1,622 @@ + + + + + diff --git a/frontend/src/views/data-process/create/PreviewCompareStep.vue b/frontend/src/views/data-process/create/PreviewCompareStep.vue index a543ee5..47dc886 100644 --- a/frontend/src/views/data-process/create/PreviewCompareStep.vue +++ b/frontend/src/views/data-process/create/PreviewCompareStep.vue @@ -1,5 +1,6 @@