增强 Word 文档 AI 解析和模板填充功能

This commit is contained in:
zzz
2026-04-10 09:48:57 +08:00
parent 7f67fa89de
commit bedf1af9c0
13 changed files with 2285 additions and 139 deletions

View File

@@ -764,6 +764,41 @@ export const backendApi = {
}
},
/**
* 填充原始模板并导出
*
* 直接打开原始模板文件,将数据填入模板的表格/单元格中,然后导出
* 适用于比赛场景:保持原始模板格式不变
*/
async fillAndExportTemplate(
templatePath: string,
filledData: Record<string, any>,
format: 'xlsx' | 'docx' = 'xlsx'
): Promise<Blob> {
const url = `${BACKEND_BASE_URL}/templates/fill-and-export`;
try {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
template_path: templatePath,
filled_data: filledData,
format,
}),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || '填充模板失败');
}
return await response.blob();
} catch (error) {
console.error('填充模板失败:', error);
throw error;
}
},
// ==================== Excel 专用接口 (保留兼容) ====================
/**
@@ -1259,4 +1294,84 @@ export const aiApi = {
throw error;
}
},
// ==================== Word AI 解析 ====================
/**
* 使用 AI 解析 Word 文档,提取结构化数据
*/
async analyzeWordWithAI(
file: File,
userHint: string = ''
): Promise<{
success: boolean;
type?: string;
headers?: string[];
rows?: string[][];
key_values?: Record<string, string>;
list_items?: string[];
summary?: string;
error?: string;
}> {
const formData = new FormData();
formData.append('file', file);
if (userHint) {
formData.append('user_hint', userHint);
}
const url = `${BACKEND_BASE_URL}/ai/analyze/word`;
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Word AI 解析失败');
}
return await response.json();
} catch (error) {
console.error('Word AI 解析失败:', error);
throw error;
}
},
/**
* 使用 AI 解析 Word 文档并填写模板
* 一次性完成AI解析 + 填表
*/
async fillTemplateFromWordAI(
file: File,
templateFields: TemplateField[],
userHint: string = ''
): Promise<FillResult> {
const formData = new FormData();
formData.append('file', file);
formData.append('template_fields', JSON.stringify(templateFields));
if (userHint) {
formData.append('user_hint', userHint);
}
const url = `${BACKEND_BASE_URL}/ai/analyze/word/fill-template`;
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Word AI 填表失败');
}
return await response.json();
} catch (error) {
console.error('Word AI 填表失败:', error);
throw error;
}
},
};

View File

@@ -152,13 +152,27 @@ const TemplateFill: React.FC = () => {
};
const handleExport = async () => {
if (!templateFile || !filledResult) return;
if (!templateFile || !filledResult) {
console.error('handleExport 失败: templateFile=', templateFile, 'filledResult=', filledResult);
toast.error('数据不完整,无法导出');
return;
}
console.log('=== handleExport 调试 ===');
console.log('templateFile:', templateFile);
console.log('templateId:', templateId);
console.log('filledResult:', filledResult);
console.log('filledResult.filled_data:', filledResult.filled_data);
console.log('=========================');
const ext = templateFile.name.split('.').pop()?.toLowerCase();
try {
const blob = await backendApi.exportFilledTemplate(
templateId || 'temp',
// 使用新的 fillAndExportTemplate 直接填充原始模板
const blob = await backendApi.fillAndExportTemplate(
templateId || '',
filledResult.filled_data || {},
'xlsx'
ext === 'docx' ? 'docx' : 'xlsx'
);
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
@@ -168,6 +182,7 @@ const TemplateFill: React.FC = () => {
URL.revokeObjectURL(url);
toast.success('导出成功');
} catch (err: any) {
console.error('导出失败:', err);
toast.error('导出失败: ' + (err.message || '未知错误'));
}
};