Jelajahi Sumber

fix(sgsc-文件上传): 优化docx转PDF后的文件标识处理

## 问题
- 转换后文件名变为 .pdf,对用户造成误导
- 每次转换后 PDF 的 MD5 不一致,导致重复文件检测失效

## 修改
- convert_docx_to_pdf 返回原始文件名,不覆盖
- MD5 基于原始 docx 内容生成,确保同一文件重复上传可被检测
- 前端显示原始文件名,后端按 PDF 处理

## 效果
- 用户上传 xxx.docx → 前端显示 xxx.docx
- 后端处理:PDF 内容,file_type='pdf'
- 重复检测:同一 docx 文件 → 相同 MD5
WangXuMing 2 minggu lalu
induk
melakukan
2a7c97637c
1 mengubah file dengan 14 tambahan dan 19 penghapusan
  1. 14 19
      views/construction_review/file_upload.py

+ 14 - 19
views/construction_review/file_upload.py

@@ -66,10 +66,10 @@ def convert_docx_to_pdf(docx_content: bytes, filename: str) -> tuple[bytes, str]
 
     Args:
         docx_content: docx/doc 文件的二进制内容
-        filename: 原始文件名(用于生成新的 PDF 文件名)
+        filename: 原始文件名
 
     Returns:
-        tuple[bytes, str]: (PDF 文件内容, 新的 PDF 文件名)
+        tuple[bytes, str]: (PDF 文件内容, 原始文件名)
 
     Raises:
         Exception: 转换失败时抛出异常
@@ -91,13 +91,12 @@ def convert_docx_to_pdf(docx_content: bytes, filename: str) -> tuple[bytes, str]
 
 
 def _convert_via_docx2pdf(docx_content: bytes, filename: str, convert_func) -> tuple[bytes, str]:
-    """使用 docx2pdf (Microsoft Word COM) 转换"""
+    """使用 docx2pdf (Microsoft Word COM) 转换,返回 PDF 内容和原始文件名"""
     with tempfile.TemporaryDirectory() as temp_dir:
         temp_dir_path = Path(temp_dir)
 
         # 保存原始文件
         original_ext = Path(filename).suffix.lower()
-        base_name = Path(filename).stem
         temp_input = temp_dir_path / f"input{original_ext}"
         temp_output = temp_dir_path / "output.pdf"
         temp_input.write_bytes(docx_content)
@@ -110,15 +109,14 @@ def _convert_via_docx2pdf(docx_content: bytes, filename: str, convert_func) -> t
             raise Exception("转换后未找到 PDF 文件")
 
         pdf_content = temp_output.read_bytes()
-        pdf_filename = f"{base_name}.pdf"
 
-        logger.info(f"成功转换 {filename} -> {pdf_filename}, PDF 大小: {len(pdf_content) / 1024:.2f} KB")
+        logger.info(f"成功转换 {filename} 为 PDF, 大小: {len(pdf_content) / 1024:.2f} KB")
 
-        return pdf_content, pdf_filename
+        return pdf_content, filename  # 返回原始文件名
 
 
 def _convert_via_libreoffice(docx_content: bytes, filename: str) -> tuple[bytes, str]:
-    """使用 LibreOffice (soffice) 转换"""
+    """使用 LibreOffice (soffice) 转换,返回 PDF 内容和原始文件名"""
     # 创建临时目录
     with tempfile.TemporaryDirectory() as temp_dir:
         temp_dir_path = Path(temp_dir)
@@ -162,11 +160,10 @@ def _convert_via_libreoffice(docx_content: bytes, filename: str) -> tuple[bytes,
 
             pdf_file = pdf_files[0]
             pdf_content = pdf_file.read_bytes()
-            pdf_filename = f"{base_name}.pdf"
 
-            logger.info(f"成功转换 {filename} -> {pdf_filename}, PDF 大小: {len(pdf_content) / 1024:.2f} KB")
+            logger.info(f"成功转换 {filename} 为 PDF, 大小: {len(pdf_content) / 1024:.2f} KB")
 
-            return pdf_content, pdf_filename
+            return pdf_content, filename  # 返回原始文件名
 
         except subprocess.TimeoutExpired:
             raise Exception("LibreOffice 转换超时")
@@ -290,7 +287,7 @@ async def file_upload(
         if user is None or user not in valid_users:
             raise FileUploadErrors.invalid_user()
 
-        # 生成文件MD5ID
+        # 生成文件MD5ID(基于原始文件内容,用于重复检测)
         file_id = md5.md5_id(content)
 
 
@@ -315,16 +312,14 @@ async def file_upload(
             # 检测到 docx/doc 文件,转换为 PDF
             logger.info(f"检测到 {file_extension} 文件,正在转换为 PDF...")
             try:
-                pdf_content, pdf_filename = convert_docx_to_pdf(content, original_filename)
-                # 更新文件内容和相关信息
+                pdf_content, _ = convert_docx_to_pdf(content, original_filename)
+                # 更新文件内容(文件名和 MD5 保持不变,用于重复检测)
                 content = pdf_content
-                original_filename = pdf_filename
                 file_type = 'pdf'  # 标记为 PDF 类型,后续流程按 PDF 处理
                 file_size = len(pdf_content)
                 file_size_mb = round(file_size / (1024 * 1024), 2)
-                # 重新生成 MD5(基于转换后的 PDF)
-                file_id = md5.md5_id(content)
-                logger.info(f"文件已转换为 PDF: {pdf_filename}, 大小: {file_size_mb} MB")
+                # 注意:file_id 保持不变(基于原始 docx 内容),用于重复文件检测
+                logger.info(f"文件已转换为 PDF,大小: {file_size_mb} MB")
             except Exception as convert_error:
                 logger.error(f"docx 转 PDF 失败: {str(convert_error)}")
                 raise FileUploadErrors.internal_error(f"文档转换失败: {str(convert_error)}")
@@ -343,7 +338,7 @@ async def file_upload(
                 'user_id': user,
                 'file_type': file_type,
                 'callback_task_id': callback_task_id,
-                "file_name": original_filename,  # 使用转换后的文件名(docx 转 PDF 后会更新
+                "file_name": original_filename,  # 保持原始文件名(docx 转 PDF 后仍显示原始文件名
                 "file_size": file_size_mb,
                 'updated_at': created_at
             }