提交 2e0670ae authored 作者: 贺阳's avatar 贺阳

同步失败的提示

上级 9e6a63bc
...@@ -6,12 +6,14 @@ import io ...@@ -6,12 +6,14 @@ import io
import json import json
import logging import logging
import time import time
from datetime import datetime, timedelta
import requests import requests
from odoo import models, fields, api, _ from odoo import models, fields, api, _
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from .ai_image_edit_service import AIImageEditService from .ai_image_edit_service import AIImageEditService
from datetime import datetime, timedelta
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
...@@ -44,7 +46,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -44,7 +46,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
skip_ocr_direct_ai = fields.Boolean( skip_ocr_direct_ai = fields.Boolean(
string='Skip OCR Direct AI', # 跳过OCR直接使用AI string='Skip OCR Direct AI', # 跳过OCR直接使用AI
default=False, default=False,
help='Whether to skip OCR processing and directly use AI processing (for testing AI)' # 是否跳过OCR处理,直接使用AI处理(用于测试AI) help='Whether to skip OCR processing and directly use AI processing (for testing AI)'
# 是否跳过OCR处理,直接使用AI处理(用于测试AI)
) )
sync_match_node = fields.Boolean( sync_match_node = fields.Boolean(
...@@ -69,7 +72,7 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -69,7 +72,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
help='Show error message' help='Show error message'
) )
# PDF相关字段 # PDF相关字段
pdf_file = fields.Binary(string='PDF文件',help='涂抹后的所有pdf文件合并为一个pdf文件') pdf_file = fields.Binary(string='PDF文件', help='涂抹后的所有pdf文件合并为一个pdf文件')
pdf_filename = fields.Char(string='PDF文件名称') pdf_filename = fields.Char(string='PDF文件名称')
processed_files_data = fields.Text(string='已处理的文件数据', help='存储已处理的文件信息(JSON格式)') processed_files_data = fields.Text(string='已处理的文件数据', help='存储已处理的文件信息(JSON格式)')
...@@ -146,7 +149,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -146,7 +149,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
successful_bl_nos_str = '、'.join(successful_bl_nos) if successful_bl_nos else '' successful_bl_nos_str = '、'.join(successful_bl_nos) if successful_bl_nos else ''
success_msg = f"\n成功处理的提单: {successful_bl_nos_str}" if successful_bl_nos_str else '' success_msg = f"\n成功处理的提单: {successful_bl_nos_str}" if successful_bl_nos_str else ''
self.show_error_message = f"{existing_error}{success_msg}" self.show_error_message = f"{existing_error}{success_msg}"
_logger.info(f"部分提单处理失败(成功:{len(successful_files)},失败:{len(failed_files)}),成功处理的提单号已显示") _logger.info(
f"部分提单处理失败(成功:{len(successful_files)},失败:{len(failed_files)}),成功处理的提单号已显示")
self.sync_successful_processed = False self.sync_successful_processed = False
# 序列化并存储处理后的文件数据(包括成功和失败的,但只有成功的才会合并PDF) # 序列化并存储处理后的文件数据(包括成功和失败的,但只有成功的才会合并PDF)
...@@ -257,11 +261,12 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -257,11 +261,12 @@ class BatchGetPodInfoWizard(models.TransientModel):
'view_mode': 'form', 'view_mode': 'form',
'res_id': self.id, 'res_id': self.id,
'target': 'new', 'target': 'new',
'context': {'active_id': bl_objs.ids,} 'context': {'active_id': bl_objs.ids, }
} }
# 检查是否有文字清除失败的错误 # 检查是否有文字清除失败的错误
if self.show_error_message and any('仍存在目标文字' in str(self.show_error_message) or '未完全清除文字' in str(self.show_error_message)): if self.show_error_message and any(
'仍存在目标文字' in str(self.show_error_message) or '未完全清除文字' in str(self.show_error_message)):
_logger.error(f"检测到文字清除失败,停止处理: {self.show_error_message}") _logger.error(f"检测到文字清除失败,停止处理: {self.show_error_message}")
return { return {
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
...@@ -303,7 +308,7 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -303,7 +308,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 同步推送匹配节点 # 同步推送匹配节点
if self.sync_match_node and successful_processed_files: if self.sync_match_node and successful_processed_files:
#且需先对比小包当前节点的操作时间是否小于提取时间(同时区对比)若大于则不能推送, # 且需先对比小包当前节点的操作时间是否小于提取时间(同时区对比)若大于则不能推送,
# 若需补推节点,则需判断提取时间-写入节点(不取写入第一个节点)的前序间隔时间是否大于小包当前节点的操作时间。 # 若需补推节点,则需判断提取时间-写入节点(不取写入第一个节点)的前序间隔时间是否大于小包当前节点的操作时间。
# 若不满足以上条件,则不执行生成和自动推送节点,并在小包上新增推送备注(新增该字段)回写备注信息:获取尾程POD,自动推送节点失败,有风险产生倒挂。请手动操作205-10-20 10:20:20(获取时间) # 若不满足以上条件,则不执行生成和自动推送节点,并在小包上新增推送备注(新增该字段)回写备注信息:获取尾程POD,自动推送节点失败,有风险产生倒挂。请手动操作205-10-20 10:20:20(获取时间)
valid_files = self._validate_node_push_conditions(successful_processed_files) valid_files = self._validate_node_push_conditions(successful_processed_files)
...@@ -315,7 +320,6 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -315,7 +320,6 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 清理所有临时文件(包括数据库记录和物理文件),不能删,不然回写的时候没有文件了 # 清理所有临时文件(包括数据库记录和物理文件),不能删,不然回写的时候没有文件了
self._cleanup_temp_attachments(bl_objs) self._cleanup_temp_attachments(bl_objs)
end_time = time.time() end_time = time.time()
_logger.info(f"批量获取POD信息操作完成,耗时: {end_time - start_time}秒") _logger.info(f"批量获取POD信息操作完成,耗时: {end_time - start_time}秒")
if self.show_error_message and not self._context.get('is_skip_raise_error'): if self.show_error_message and not self._context.get('is_skip_raise_error'):
...@@ -326,10 +330,9 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -326,10 +330,9 @@ class BatchGetPodInfoWizard(models.TransientModel):
'view_mode': 'form', 'view_mode': 'form',
'res_id': self.id, 'res_id': self.id,
'target': 'new', 'target': 'new',
'context': {'default_show_error_message': self.show_error_message,'active_id': bl_objs.ids} 'context': {'default_show_error_message': self.show_error_message, 'active_id': bl_objs.ids}
} }
def _validate_node_push_conditions(self, processed_files): def _validate_node_push_conditions(self, processed_files):
""" """
验证节点推送条件 验证节点推送条件
...@@ -428,7 +431,6 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -428,7 +431,6 @@ class BatchGetPodInfoWizard(models.TransientModel):
file_data = file_info.get('file_data', '') file_data = file_info.get('file_data', '')
if not file_data: if not file_data:
continue continue
# 如果有文件为空的就回写,否则就创建新的清关文件记录 # 如果有文件为空的就回写,否则就创建新的清关文件记录
...@@ -634,16 +636,23 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -634,16 +636,23 @@ class BatchGetPodInfoWizard(models.TransientModel):
""" """
# return False#测试 先不同步 # return False#测试 先不同步
# 同步尾程POD信息 # 同步尾程POD信息
is_fail = [] # 同步失败
for file_info in processed_files: for file_info in processed_files:
if not file_info['bl']: if not file_info['bl']:
continue continue
bl = file_info['bl'] bl = file_info['bl']
# 查找清关文件并执行同步 # 查找清关文件并执行同步
clearance_file = file_info.get('clearance_file') clearance_file = file_info.get('clearance_file')
if clearance_file: if clearance_file:
try:
clearance_file.action_sync() # 同步尾程POD clearance_file.action_sync() # 同步尾程POD
except Exception as e:
logging.info('_sync_last_mile_pod:%s' % e)
is_fail = True
break
_logger.info(f"Successfully synced POD for BL {bl.bl_no}") _logger.info(f"Successfully synced POD for BL {bl.bl_no}")
if is_fail:
raise ValidationError('本次同步失败,请重试!')
def _check_target_texts_exist(self, pdf_binary, bl_no): def _check_target_texts_exist(self, pdf_binary, bl_no):
""" """
...@@ -659,7 +668,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -659,7 +668,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
import re import re
# 定义目标文字(与_find_target_texts一致) # 定义目标文字(与_find_target_texts一致)
TARGET_TEXTS = ['AGN', 'ACN', 'UCLINK LOGISITICS LTD', 'UCLINK LOGISITICS', 'UCLINK', 'LOGISITICS', 'LOGISTICS', 'LTD', TARGET_TEXTS = ['AGN', 'ACN', 'UCLINK LOGISITICS LTD', 'UCLINK LOGISITICS', 'UCLINK', 'LOGISITICS', 'LOGISTICS',
'LTD',
'UCLINKLOGISITICSLTD'] 'UCLINKLOGISITICSLTD']
EXCLUDE_TEXTS = ['AIR EQK', 'ARN', 'EQK', 'AIR', 'Page 1 of 1', 'Page 2 of 2', 'Page 3 of 3', 'Page 4 of 4', EXCLUDE_TEXTS = ['AIR EQK', 'ARN', 'EQK', 'AIR', 'Page 1 of 1', 'Page 2 of 2', 'Page 3 of 3', 'Page 4 of 4',
'Page 5 of 5'] 'Page 5 of 5']
...@@ -744,7 +754,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -744,7 +754,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
exclude_upper = exclude_text.upper() exclude_upper = exclude_text.upper()
if exclude_upper in combined_text and target_upper in combined_text: if exclude_upper in combined_text and target_upper in combined_text:
# 检查是否是页码 # 检查是否是页码
if re.search(r'PAGE\s+\d+\s+OF\s+\d+', combined_text) or re.search(r'\d+\s*/\s*\d+', combined_text): if re.search(r'PAGE\s+\d+\s+OF\s+\d+', combined_text) or re.search(r'\d+\s*/\s*\d+',
combined_text):
is_excluded = True is_excluded = True
break break
# 检查是否是AIR EQK等排除项 # 检查是否是AIR EQK等排除项
...@@ -813,7 +824,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -813,7 +824,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 检查是否还存在目标文字 # 检查是否还存在目标文字
final_check_pdf = base64.b64decode(processed_file_data) final_check_pdf = base64.b64decode(processed_file_data)
text_still_exists, final_found_texts = self._check_target_texts_exist(final_check_pdf, bl.bl_no) text_still_exists, final_found_texts = self._check_target_texts_exist(final_check_pdf,
bl.bl_no)
if text_still_exists: if text_still_exists:
error_msg = f"提单 {bl.bl_no} 经过AI处理后仍存在目标文字: {', '.join(final_found_texts)},请取消该提单操作,手动处理" error_msg = f"提单 {bl.bl_no} 经过AI处理后仍存在目标文字: {', '.join(final_found_texts)},请取消该提单操作,手动处理"
...@@ -863,7 +875,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -863,7 +875,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 第四步:再次检查是否还存在目标文字 # 第四步:再次检查是否还存在目标文字
final_check_pdf = base64.b64decode(processed_file_data) final_check_pdf = base64.b64decode(processed_file_data)
text_still_exists, final_found_texts = self._check_target_texts_exist(final_check_pdf, bl.bl_no) text_still_exists, final_found_texts = self._check_target_texts_exist(
final_check_pdf, bl.bl_no)
if text_still_exists: if text_still_exists:
# 第五步:如果仍然存在,记录错误信息并停止处理 # 第五步:如果仍然存在,记录错误信息并停止处理
...@@ -877,7 +890,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -877,7 +890,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
_logger.warning(f"提单 {bl.bl_no} AI处理失败,检查OCR处理结果") _logger.warning(f"提单 {bl.bl_no} AI处理失败,检查OCR处理结果")
# AI处理失败,检查OCR结果是否真的清除了目标文字 # AI处理失败,检查OCR结果是否真的清除了目标文字
ocr_check_pdf = base64.b64decode(processed_file_data) ocr_check_pdf = base64.b64decode(processed_file_data)
text_still_exists, ocr_found_texts = self._check_target_texts_exist(ocr_check_pdf, bl.bl_no) text_still_exists, ocr_found_texts = self._check_target_texts_exist(
ocr_check_pdf, bl.bl_no)
if text_still_exists: if text_still_exists:
error_msg = f"提单 {bl.bl_no} 经过系统处理后仍存在目标文字: {', '.join(ocr_found_texts)},请取消该提单操作,手动处理" error_msg = f"提单 {bl.bl_no} 经过系统处理后仍存在目标文字: {', '.join(ocr_found_texts)},请取消该提单操作,手动处理"
error_messages.append(error_msg) error_messages.append(error_msg)
...@@ -890,7 +904,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -890,7 +904,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
_logger.error(f"提单 {bl.bl_no} AI处理异常: {str(e)}") _logger.error(f"提单 {bl.bl_no} AI处理异常: {str(e)}")
# AI处理失败,使用OCR结果,但需要检查 # AI处理失败,使用OCR结果,但需要检查
final_check_pdf = base64.b64decode(processed_file_data) final_check_pdf = base64.b64decode(processed_file_data)
text_still_exists, final_found_texts = self._check_target_texts_exist(final_check_pdf, bl.bl_no) text_still_exists, final_found_texts = self._check_target_texts_exist(
final_check_pdf, bl.bl_no)
if text_still_exists: if text_still_exists:
error_msg = f"提单 {bl.bl_no} 经过系统处理后仍存在目标文字: {', '.join(final_found_texts)},请取消该提单操作,手动处理" error_msg = f"提单 {bl.bl_no} 经过系统处理后仍存在目标文字: {', '.join(final_found_texts)},请取消该提单操作,手动处理"
error_messages.append(error_msg) error_messages.append(error_msg)
...@@ -991,7 +1006,6 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -991,7 +1006,6 @@ class BatchGetPodInfoWizard(models.TransientModel):
""" """
import fitz # PyMuPDF import fitz # PyMuPDF
import base64 import base64
import mimetypes
import gc import gc
import os import os
import tempfile import tempfile
...@@ -1085,15 +1099,18 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1085,15 +1099,18 @@ class BatchGetPodInfoWizard(models.TransientModel):
break break
else: else:
if attempt < max_retries: if attempt < max_retries:
_logger.warning(f"第{page_num + 1}页AI处理失败(第{attempt}次尝试),将重试,耗时: {attempt_time:.2f}秒") _logger.warning(
f"第{page_num + 1}页AI处理失败(第{attempt}次尝试),将重试,耗时: {attempt_time:.2f}秒")
else: else:
_logger.warning(f"第{page_num + 1}页AI处理失败(第{attempt}次尝试,已用尽重试),耗时: {attempt_time:.2f}秒") _logger.warning(
f"第{page_num + 1}页AI处理失败(第{attempt}次尝试,已用尽重试),耗时: {attempt_time:.2f}秒")
except Exception as e: except Exception as e:
ai_end_time = time.time() ai_end_time = time.time()
attempt_time = ai_end_time - ai_start_time attempt_time = ai_end_time - ai_start_time
ai_processing_time += attempt_time ai_processing_time += attempt_time
total_ai_time += attempt_time total_ai_time += attempt_time
_logger.error(f"第{page_num + 1}页AI处理异常(第{attempt}次尝试): {str(e)},耗时: {attempt_time:.2f}秒") _logger.error(
f"第{page_num + 1}页AI处理异常(第{attempt}次尝试): {str(e)},耗时: {attempt_time:.2f}秒")
if attempt < max_retries: if attempt < max_retries:
_logger.info(f"第{page_num + 1}页将进行第{attempt + 1}次重试") _logger.info(f"第{page_num + 1}页将进行第{attempt + 1}次重试")
edited_img_base64 = None edited_img_base64 = None
...@@ -1111,7 +1128,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1111,7 +1128,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
processed_images.append(edited_img) processed_images.append(edited_img)
_logger.info(f"第{page_num + 1}页AI处理最终成功,总耗时: {ai_processing_time:.2f}秒") _logger.info(f"第{page_num + 1}页AI处理最终成功,总耗时: {ai_processing_time:.2f}秒")
else: else:
_logger.warning(f"第{page_num + 1}页AI处理最终失败(已重试),使用原始页面,总耗时: {ai_processing_time:.2f}秒") _logger.warning(
f"第{page_num + 1}页AI处理最终失败(已重试),使用原始页面,总耗时: {ai_processing_time:.2f}秒")
# 如果AI处理失败,使用原始图片 # 如果AI处理失败,使用原始图片
processed_images.append(img.convert('RGB')) processed_images.append(img.convert('RGB'))
...@@ -1330,7 +1348,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1330,7 +1348,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
_logger.info(f"总处理时间: {total_time:.2f}秒") _logger.info(f"总处理时间: {total_time:.2f}秒")
_logger.info(f"AI总耗时: {total_ai_time:.2f}秒(累计所有页面的AI处理时间)") _logger.info(f"AI总耗时: {total_ai_time:.2f}秒(累计所有页面的AI处理时间)")
_logger.info(f"PDF创建时间: {pdf_creation_time:.2f}秒") _logger.info(f"PDF创建时间: {pdf_creation_time:.2f}秒")
_logger.info(f"平均每页AI处理时间: {total_ai_time/total_pages:.2f}秒" if total_pages > 0 else "平均每页AI处理时间: 0.00秒") _logger.info(
f"平均每页AI处理时间: {total_ai_time / total_pages:.2f}秒" if total_pages > 0 else "平均每页AI处理时间: 0.00秒")
return result_data return result_data
...@@ -1518,10 +1537,11 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1518,10 +1537,11 @@ class BatchGetPodInfoWizard(models.TransientModel):
total_time = time.time() - start_time total_time = time.time() - start_time
# 输出处理总结 # 输出处理总结
_logger.info(f"OCR处理完成 - 提单号: {bl_no}, 处理页数: {processed_pages}, 删除矩形数: {total_rectangles}, 检测到文字数: {len(detected_texts)}") _logger.info(
f"OCR处理完成 - 提单号: {bl_no}, 处理页数: {processed_pages}, 删除矩形数: {total_rectangles}, 检测到文字数: {len(detected_texts)}")
_logger.info(f"OCR总处理时间: {total_time:.2f}秒") _logger.info(f"OCR总处理时间: {total_time:.2f}秒")
_logger.info(f"PDF保存时间: {pdf_save_time:.2f}秒") _logger.info(f"PDF保存时间: {pdf_save_time:.2f}秒")
_logger.info(f"平均每页OCR处理时间: {total_time/total_pages:.2f}秒") _logger.info(f"平均每页OCR处理时间: {total_time / total_pages:.2f}秒")
if detected_texts: if detected_texts:
_logger.info(f"检测到的目标文字: {[text['text'] for text in detected_texts]}") _logger.info(f"检测到的目标文字: {[text['text'] for text in detected_texts]}")
except Exception as e: except Exception as e:
...@@ -1609,7 +1629,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1609,7 +1629,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
Find target texts using OCR results (完全按照HTML逻辑) # 使用OCR结果查找目标文字 Find target texts using OCR results (完全按照HTML逻辑) # 使用OCR结果查找目标文字
""" """
# 定义目标文字和排除文字(与HTML文件完全一致) # 定义目标文字和排除文字(与HTML文件完全一致)
TARGET_TEXTS = ['AGN', 'ACN', 'UCLINK LOGISITICS LTD', 'UCLINK LOGISITICS', 'UCLINK', 'LOGISITICS', 'LOGISTICS', 'LTD', TARGET_TEXTS = ['AGN', 'ACN', 'UCLINK LOGISITICS LTD', 'UCLINK LOGISITICS', 'UCLINK', 'LOGISITICS', 'LOGISTICS',
'LTD',
'UCLINKLOGISITICSLTD'] 'UCLINKLOGISITICSLTD']
EXCLUDE_TEXTS = ['AIR EQK', 'ARN', 'EQK', 'AIR', 'Page 1 of 1', 'Page 2 of 2', 'Page 3 of 3', 'Page 4 of 4', EXCLUDE_TEXTS = ['AIR EQK', 'ARN', 'EQK', 'AIR', 'Page 1 of 1', 'Page 2 of 2', 'Page 3 of 3', 'Page 4 of 4',
'Page 5 of 5'] 'Page 5 of 5']
...@@ -1819,7 +1840,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1819,7 +1840,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
if extracted_times: if extracted_times:
# 取最早的时间作为节点操作时间 # 取最早的时间作为节点操作时间
earliest_time = min(extracted_times) earliest_time = min(extracted_times)
_logger.info(f"提取到最早时间: {earliest_time},将作为节点操作时间,满足条件的小包数量: {len(valid_package_ids)},小包ID: {valid_package_ids}") _logger.info(
f"提取到最早时间: {earliest_time},将作为节点操作时间,满足条件的小包数量: {len(valid_package_ids)},小包ID: {valid_package_ids}")
ship_packages.append({ ship_packages.append({
'bl_id': bl.id, 'bl_id': bl.id,
'id': valid_package_ids, # 只包含满足条件的小包ID 'id': valid_package_ids, # 只包含满足条件的小包ID
...@@ -2056,7 +2078,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2056,7 +2078,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
import gc import gc
# 定义目标文字(与_find_target_texts一致) # 定义目标文字(与_find_target_texts一致)
TARGET_TEXTS = ['AGN', 'ACN', 'UCLINK LOGISITICS LTD', 'UCLINK LOGISITICS', 'UCLINK', 'LOGISITICS', 'LOGISTICS', 'LTD', TARGET_TEXTS = ['AGN', 'ACN', 'UCLINK LOGISITICS LTD', 'UCLINK LOGISITICS', 'UCLINK', 'LOGISITICS', 'LOGISTICS',
'LTD',
'UCLINKLOGISITICSLTD'] 'UCLINKLOGISITICSLTD']
EXCLUDE_TEXTS = ['AIR EQK', 'ARN', 'EQK', 'AIR', 'Page 1 of 1', 'Page 2 of 2', 'Page 3 of 3', 'Page 4 of 4', EXCLUDE_TEXTS = ['AIR EQK', 'ARN', 'EQK', 'AIR', 'Page 1 of 1', 'Page 2 of 2', 'Page 3 of 3', 'Page 4 of 4',
'Page 5 of 5'] 'Page 5 of 5']
...@@ -2199,7 +2222,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2199,7 +2222,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
exclude_upper = exclude_text.upper() exclude_upper = exclude_text.upper()
if exclude_upper in combined_text and target_upper in combined_text: if exclude_upper in combined_text and target_upper in combined_text:
# 检查是否是页码 # 检查是否是页码
if re.search(r'PAGE\s+\d+\s+OF\s+\d+', combined_text) or re.search(r'\d+\s*/\s*\d+', combined_text): if re.search(r'PAGE\s+\d+\s+OF\s+\d+', combined_text) or re.search(
r'\d+\s*/\s*\d+', combined_text):
is_excluded = True is_excluded = True
break break
# 检查是否是AIR EQK等排除项 # 检查是否是AIR EQK等排除项
...@@ -2262,8 +2286,7 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2262,8 +2286,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 检查失败时,假设不存在(避免误报) # 检查失败时,假设不存在(避免误报)
return False, [] return False, []
def _cleanup_temp_attachments(self, bl_objs=None):
def _cleanup_temp_attachments(self,bl_objs=None):
""" """
清理与当前向导相关的临时附件,包括服务器和本地开发环境的物理文件 清理与当前向导相关的临时附件,包括服务器和本地开发环境的物理文件
""" """
...@@ -2322,7 +2345,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2322,7 +2345,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
if len(original_decoded) == len(attachment_decoded): if len(original_decoded) == len(attachment_decoded):
_logger.info(f"附件数据验证成功,解码后长度: {len(original_decoded)}") _logger.info(f"附件数据验证成功,解码后长度: {len(original_decoded)}")
else: else:
_logger.warning(f"附件数据长度不匹配: 原始={len(original_decoded)}, 附件={len(attachment_decoded)}") _logger.warning(
f"附件数据长度不匹配: 原始={len(original_decoded)}, 附件={len(attachment_decoded)}")
except Exception as e: except Exception as e:
_logger.warning(f"附件数据验证失败: {str(e)}") _logger.warning(f"附件数据验证失败: {str(e)}")
else: else:
...@@ -2353,7 +2377,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2353,7 +2377,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
data['valid_package_ids'] = [p.id for p in valid_packages if hasattr(p, 'id')] data['valid_package_ids'] = [p.id for p in valid_packages if hasattr(p, 'id')]
else: else:
data['valid_package_ids'] = [] data['valid_package_ids'] = []
_logger.info(f"序列化时保存valid_packages: 提单 {bl.bl_no}, 满足条件的小包ID: {data['valid_package_ids']}") _logger.info(
f"序列化时保存valid_packages: 提单 {bl.bl_no}, 满足条件的小包ID: {data['valid_package_ids']}")
serialized_data.append(data) serialized_data.append(data)
return json.dumps(serialized_data, ensure_ascii=False) return json.dumps(serialized_data, ensure_ascii=False)
...@@ -2382,7 +2407,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2382,7 +2407,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
if attachment.exists(): if attachment.exists():
# attachment.datas 已经是 base64 编码的字符串 # attachment.datas 已经是 base64 编码的字符串
file_data = attachment.datas file_data = attachment.datas
_logger.info(f"从附件读取文件: {attachment.name}, ID: {attachment_id}, 数据长度: {len(file_data) if file_data else 0}") _logger.info(
f"从附件读取文件: {attachment.name}, ID: {attachment_id}, 数据长度: {len(file_data) if file_data else 0}")
# 验证数据格式 # 验证数据格式
if file_data: if file_data:
...@@ -2419,7 +2445,8 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2419,7 +2445,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 重建记录集对象 # 重建记录集对象
valid_packages = self.env['cc.ship.package'].browse(valid_package_ids) valid_packages = self.env['cc.ship.package'].browse(valid_package_ids)
file_info['valid_packages'] = valid_packages file_info['valid_packages'] = valid_packages
_logger.info(f"反序列化时恢复valid_packages: 提单 {bl.bl_no}, 满足条件的小包ID: {valid_package_ids}, 数量: {len(valid_packages)}") _logger.info(
f"反序列化时恢复valid_packages: 提单 {bl.bl_no}, 满足条件的小包ID: {valid_package_ids}, 数量: {len(valid_packages)}")
processed_files.append(file_info) processed_files.append(file_info)
return processed_files return processed_files
except Exception as e: except Exception as e:
...@@ -2435,7 +2462,7 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2435,7 +2462,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
try: try:
# 计算1天前的时间(前一天23:59:59) # 计算1天前的时间(前一天23:59:59)
today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
one_day_ago = today+ timedelta(days=2) - timedelta(seconds=1) # 前一天23:59:59 one_day_ago = today + timedelta(days=2) - timedelta(seconds=1) # 前一天23:59:59
_logger.info(f"开始执行定时清理临时附件任务,清理时间点: {one_day_ago.strftime('%Y-%m-%d %H:%M:%S')}") _logger.info(f"开始执行定时清理临时附件任务,清理时间点: {one_day_ago.strftime('%Y-%m-%d %H:%M:%S')}")
# 构建SQL查询 # 构建SQL查询
sql_query = """ sql_query = """
...@@ -2492,4 +2519,3 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -2492,4 +2519,3 @@ class BatchGetPodInfoWizard(models.TransientModel):
except Exception as e: except Exception as e:
_logger.error(f"定时清理临时附件失败: {str(e)}") _logger.error(f"定时清理临时附件失败: {str(e)}")
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论