Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
hh_ccs
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
贺阳
hh_ccs
Commits
ab556fae
提交
ab556fae
authored
11月 03, 2025
作者:
贺阳
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
如果又失败的也有成功的,增加同步成功的提单的标志
上级
46bba812
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
139 行增加
和
23 行删除
+139
-23
batch_get_pod_info_wizard.py
ccs_base/wizard/batch_get_pod_info_wizard.py
+128
-14
batch_get_pod_info_wizard_views.xml
ccs_base/wizard/batch_get_pod_info_wizard_views.xml
+11
-9
没有找到文件。
ccs_base/wizard/batch_get_pod_info_wizard.py
浏览文件 @
ab556fae
...
@@ -53,6 +53,12 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -53,6 +53,12 @@ class BatchGetPodInfoWizard(models.TransientModel):
help
=
'Whether to sync and push matched node information'
# 是否同步推送匹配节点信息
help
=
'Whether to sync and push matched node information'
# 是否同步推送匹配节点信息
)
)
sync_successful_processed
=
fields
.
Boolean
(
string
=
'是否同步成功涂抹的提单'
,
# 是否同步成功涂抹的提单
default
=
False
,
help
=
'勾选后显示同步尾程POD和同步匹配节点的字段以及确定按钮'
# 勾选后显示同步尾程POD和同步匹配节点的字段以及确定按钮
)
# debug_mode = fields.Boolean(
# debug_mode = fields.Boolean(
# string='Debug Mode', # 调试模式
# string='Debug Mode', # 调试模式
# default=False,
# default=False,
...
@@ -95,14 +101,80 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -95,14 +101,80 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 如果启用了涂抹文字,进行处理
# 如果启用了涂抹文字,进行处理
if
self
.
remove_specified_text
and
processed_files
:
if
self
.
remove_specified_text
and
processed_files
:
processed_files
=
self
.
_remove_specified_text
(
processed_files
,
debug_mode
=
False
)
processed_files
=
self
.
_remove_specified_text
(
processed_files
,
debug_mode
=
False
)
# 合并PDF并保存到pdf_file字段
self
.
_merge_pdf_files
(
processed_files
)
# 分离成功和失败的文件
successful_files
=
[]
# 序列化并存储处理后的文件数据
failed_files
=
[]
if
processed_files
:
for
file_info
in
processed_files
:
self
.
processed_files_data
=
self
.
_serialize_processed_files
(
processed_files
)
if
file_info
.
get
(
'bl'
):
bl
=
file_info
.
get
(
'bl'
)
file_data
=
file_info
.
get
(
'file_data'
,
''
)
# 检查处理是否失败(通过processing_failed标记或错误消息)
processing_failed
=
file_info
.
get
(
'processing_failed'
,
False
)
has_error
=
False
if
self
.
show_error_message
:
error_msg
=
str
(
self
.
show_error_message
)
if
bl
and
bl
.
bl_no
in
error_msg
:
has_error
=
True
# 如果处理失败或者有错误,则认为失败
if
processing_failed
or
has_error
or
not
file_data
:
failed_files
.
append
(
file_info
)
else
:
# 文件数据存在且处理成功
successful_files
.
append
(
file_info
)
# 只合并成功的文件
if
successful_files
:
self
.
_merge_pdf_files
(
successful_files
)
# 如果所有文件都成功了(没有失败的文件),自动勾选"是否同步成功涂抹的提单"
if
len
(
successful_files
)
==
len
(
processed_files
)
and
not
failed_files
:
self
.
sync_successful_processed
=
True
_logger
.
info
(
f
"所有提单都处理成功,自动勾选同步选项"
)
else
:
# 有失败的文件,保持未勾选状态,让用户决定
# 将成功处理的提单信息追加到show_error_message中(使用特殊分隔符)
if
successful_files
:
successful_bl_data
=
[]
for
file_info
in
successful_files
:
if
file_info
.
get
(
'bl'
):
bl
=
file_info
[
'bl'
]
successful_bl_data
.
append
({
'bl_id'
:
bl
.
id
,
'bl_no'
:
bl
.
bl_no
})
# 在错误消息后面追加成功处理的提单信息(使用特殊分隔符,不会在UI中显示)
successful_bls_json
=
json
.
dumps
(
successful_bl_data
,
ensure_ascii
=
False
)
existing_error
=
self
.
show_error_message
or
''
# 使用特殊分隔符,方便后续解析,但在UI中不会显示这部分
self
.
show_error_message
=
f
"{existing_error}
\n
<!--SUCCESSFUL_BLS_START-->{successful_bls_json}<!--SUCCESSFUL_BLS_END-->"
_logger
.
info
(
f
"部分提单处理失败(成功:{len(successful_files)},失败:{len(failed_files)}),成功处理的提单信息已保存到错误消息中"
)
self
.
sync_successful_processed
=
False
# 序列化并存储处理后的文件数据(包括成功和失败的,但只有成功的才会合并PDF)
if
processed_files
:
self
.
processed_files_data
=
self
.
_serialize_processed_files
(
processed_files
)
else
:
self
.
processed_files_data
=
''
else
:
else
:
self
.
processed_files_data
=
''
# 如果没有涂抹文字,所有文件都视为成功
if
processed_files
:
self
.
processed_files_data
=
self
.
_serialize_processed_files
(
processed_files
)
successful_bl_data
=
[]
for
file_info
in
processed_files
:
if
file_info
.
get
(
'bl'
):
bl
=
file_info
[
'bl'
]
successful_bl_data
.
append
({
'bl_id'
:
bl
.
id
,
'bl_no'
:
bl
.
bl_no
})
# 没有涂抹文字,所有文件都成功,自动勾选
self
.
sync_successful_processed
=
True
_logger
.
info
(
f
"未启用涂抹文字,所有提单都成功,自动勾选同步选项"
)
else
:
self
.
processed_files_data
=
''
self
.
sync_successful_processed
=
False
# 返回表单视图
# 返回表单视图
return
{
return
{
...
@@ -204,21 +276,53 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -204,21 +276,53 @@ class BatchGetPodInfoWizard(models.TransientModel):
'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
}
}
}
# 只处理成功涂抹的提单
# 从show_error_message中获取成功处理的提单ID(如果有失败的话)
successful_bl_ids
=
[]
if
self
.
show_error_message
and
'<!--SUCCESSFUL_BLS_START-->'
in
str
(
self
.
show_error_message
):
try
:
# 从show_error_message中提取成功处理的提单信息
error_msg
=
str
(
self
.
show_error_message
)
start_marker
=
'<!--SUCCESSFUL_BLS_START-->'
end_marker
=
'<!--SUCCESSFUL_BLS_END-->'
start_idx
=
error_msg
.
find
(
start_marker
)
end_idx
=
error_msg
.
find
(
end_marker
)
if
start_idx
!=
-
1
and
end_idx
!=
-
1
:
successful_bls_json
=
error_msg
[
start_idx
+
len
(
start_marker
):
end_idx
]
successful_bl_data
=
json
.
loads
(
successful_bls_json
)
successful_bl_ids
=
[
item
[
'bl_id'
]
for
item
in
successful_bl_data
]
_logger
.
info
(
f
"从错误消息中解析出{len(successful_bl_ids)}个成功处理的提单ID"
)
except
Exception
as
e
:
_logger
.
warning
(
f
"解析成功处理的提单数据失败: {str(e)}"
)
# 过滤出成功处理的文件
successful_processed_files
=
[]
if
successful_bl_ids
:
# 如果有成功处理的提单ID(说明有失败),只处理成功的
if
processed_files
:
successful_bl_ids_set
=
set
(
successful_bl_ids
)
for
file_info
in
processed_files
:
if
file_info
.
get
(
'bl'
)
and
file_info
[
'bl'
]
.
id
in
successful_bl_ids_set
:
successful_processed_files
.
append
(
file_info
)
else
:
# 如果没有失败(没有成功处理的提单ID列表),说明全部成功,处理所有文件
successful_processed_files
=
processed_files
# 回写到附件信息
# 回写到附件信息
if
processed_files
and
(
self
.
sync_last_mile_pod
or
self
.
sync_match_node
):
if
successful_
processed_files
and
(
self
.
sync_last_mile_pod
or
self
.
sync_match_node
):
# 回写PDF文件到清关文件
# 回写PDF文件到清关文件
self
.
_write_pdf_file
(
processed_files
)
self
.
_write_pdf_file
(
successful_
processed_files
)
# 再同步和回写
# 再同步和回写
if
self
.
sync_last_mile_pod
and
processed_files
:
if
self
.
sync_last_mile_pod
and
successful_
processed_files
:
self
.
_sync_last_mile_pod
(
processed_files
)
self
.
_sync_last_mile_pod
(
successful_
processed_files
)
# 同步推送匹配节点
# 同步推送匹配节点
if
self
.
sync_match_node
and
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
(
processed_files
)
valid_files
=
self
.
_validate_node_push_conditions
(
successful_
processed_files
)
if
valid_files
:
if
valid_files
:
self
.
get_date_sync_match_node
(
valid_files
)
self
.
get_date_sync_match_node
(
valid_files
)
else
:
else
:
...
@@ -689,7 +793,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -689,7 +793,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
- 如果skip_ocr_direct_ai为False:先用OCR处理,检查是否还存在,如果存在则用AI处理,再次检查
- 如果skip_ocr_direct_ai为False:先用OCR处理,检查是否还存在,如果存在则用AI处理,再次检查
:param processed_files: 处理后的文件数组
:param processed_files: 处理后的文件数组
:param debug_mode: 是否显示调试标记
:param debug_mode: 是否显示调试标记
:return: 处理后的文件数组(包含处理后的PDF数据)
:return: 处理后的文件数组(包含处理后的PDF数据
,失败的文件会标记'processing_failed': True
)
"""
"""
updated_files
=
[]
updated_files
=
[]
error_messages
=
[]
error_messages
=
[]
...
@@ -702,6 +806,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -702,6 +806,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
bl
=
file_info
[
'bl'
]
bl
=
file_info
[
'bl'
]
file_data
=
file_info
[
'file_data'
]
file_data
=
file_info
[
'file_data'
]
processed_file_data
=
file_data
# 默认使用原始数据
processed_file_data
=
file_data
# 默认使用原始数据
processing_failed
=
False
# 标记处理是否失败
if
file_data
:
if
file_data
:
# 将base64数据转换为二进制
# 将base64数据转换为二进制
...
@@ -732,16 +837,19 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -732,16 +837,19 @@ class BatchGetPodInfoWizard(models.TransientModel):
error_messages
.
append
(
error_msg
)
error_messages
.
append
(
error_msg
)
# 不更新文件数据,保持原始状态
# 不更新文件数据,保持原始状态
processed_file_data
=
file_data
processed_file_data
=
file_data
processing_failed
=
True
else
:
else
:
_logger
.
info
(
f
"提单 {bl.bl_no} AI处理成功,目标文字已清除"
)
_logger
.
info
(
f
"提单 {bl.bl_no} AI处理成功,目标文字已清除"
)
else
:
else
:
error_msg
=
f
"提单 {bl.bl_no} AI处理失败"
error_msg
=
f
"提单 {bl.bl_no} AI处理失败"
_logger
.
error
(
error_msg
)
_logger
.
error
(
error_msg
)
error_messages
.
append
(
error_msg
)
error_messages
.
append
(
error_msg
)
processing_failed
=
True
except
Exception
as
e
:
except
Exception
as
e
:
_logger
.
error
(
f
"提单 {bl.bl_no} AI处理异常: {str(e)}"
)
_logger
.
error
(
f
"提单 {bl.bl_no} AI处理异常: {str(e)}"
)
error_msg
=
f
"提单 {bl.bl_no} AI处理异常: {str(e)}"
error_msg
=
f
"提单 {bl.bl_no} AI处理异常: {str(e)}"
error_messages
.
append
(
error_msg
)
error_messages
.
append
(
error_msg
)
processing_failed
=
True
else
:
else
:
# 原有逻辑:先用OCR处理,如果还存在则用AI处理
# 原有逻辑:先用OCR处理,如果还存在则用AI处理
# 第一步:使用OCR方法处理PDF
# 第一步:使用OCR方法处理PDF
...
@@ -780,6 +888,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -780,6 +888,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
error_messages
.
append
(
error_msg
)
error_messages
.
append
(
error_msg
)
# 不更新文件数据,保持原始状态
# 不更新文件数据,保持原始状态
processed_file_data
=
file_data
processed_file_data
=
file_data
processing_failed
=
True
else
:
else
:
_logger
.
warning
(
f
"提单 {bl.bl_no} AI处理失败,检查OCR处理结果"
)
_logger
.
warning
(
f
"提单 {bl.bl_no} AI处理失败,检查OCR处理结果"
)
# AI处理失败,检查OCR结果是否真的清除了目标文字
# AI处理失败,检查OCR结果是否真的清除了目标文字
...
@@ -790,6 +899,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -790,6 +899,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
error_messages
.
append
(
error_msg
)
error_messages
.
append
(
error_msg
)
# 不更新文件数据,保持原始状态
# 不更新文件数据,保持原始状态
processed_file_data
=
file_data
processed_file_data
=
file_data
processing_failed
=
True
else
:
else
:
_logger
.
info
(
f
"提单 {bl.bl_no} OCR处理成功,目标文字已清除"
)
_logger
.
info
(
f
"提单 {bl.bl_no} OCR处理成功,目标文字已清除"
)
except
Exception
as
e
:
except
Exception
as
e
:
...
@@ -802,18 +912,22 @@ class BatchGetPodInfoWizard(models.TransientModel):
...
@@ -802,18 +912,22 @@ class BatchGetPodInfoWizard(models.TransientModel):
error_messages
.
append
(
error_msg
)
error_messages
.
append
(
error_msg
)
# 不更新文件数据,保持原始状态
# 不更新文件数据,保持原始状态
processed_file_data
=
file_data
processed_file_data
=
file_data
processing_failed
=
True
else
:
else
:
_logger
.
info
(
f
"提单 {bl.bl_no} OCR处理成功,目标文字已清除"
)
_logger
.
info
(
f
"提单 {bl.bl_no} OCR处理成功,目标文字已清除"
)
else
:
else
:
_logger
.
warning
(
f
"提单 {bl.bl_no} OCR处理失败"
)
_logger
.
warning
(
f
"提单 {bl.bl_no} OCR处理失败"
)
error_messages
.
append
(
f
"提单 {bl.bl_no} OCR处理失败"
)
error_messages
.
append
(
f
"提单 {bl.bl_no} OCR处理失败"
)
processing_failed
=
True
except
Exception
as
e
:
except
Exception
as
e
:
_logger
.
error
(
f
"提单 {bl.bl_no} OCR处理异常: {str(e)}"
)
_logger
.
error
(
f
"提单 {bl.bl_no} OCR处理异常: {str(e)}"
)
error_messages
.
append
(
f
"提单 {bl.bl_no} OCR处理异常: {str(e)}"
)
error_messages
.
append
(
f
"提单 {bl.bl_no} OCR处理异常: {str(e)}"
)
processing_failed
=
True
# 更新文件信息,使用处理后的PDF数据
# 更新文件信息,使用处理后的PDF数据
updated_file_info
=
file_info
.
copy
()
updated_file_info
=
file_info
.
copy
()
updated_file_info
[
'file_data'
]
=
processed_file_data
updated_file_info
[
'file_data'
]
=
processed_file_data
updated_file_info
[
'processing_failed'
]
=
processing_failed
# 标记处理是否失败
updated_files
.
append
(
updated_file_info
)
updated_files
.
append
(
updated_file_info
)
# 如果有错误信息,合并到show_error_message中
# 如果有错误信息,合并到show_error_message中
...
...
ccs_base/wizard/batch_get_pod_info_wizard_views.xml
浏览文件 @
ab556fae
...
@@ -16,14 +16,15 @@
...
@@ -16,14 +16,15 @@
<field
name=
"skip_ocr_direct_ai"
readonly=
"0"
widget=
"boolean_toggle"
<field
name=
"skip_ocr_direct_ai"
readonly=
"0"
widget=
"boolean_toggle"
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
/>
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
/>
</group>
</group>
<group>
<group
attrs=
"{'invisible': ['|', ('pdf_file', '=', False), ('show_error_message', '=', False)]}"
>
<field
name=
"sync_last_mile_pod"
widget=
"boolean_toggle"
<field
name=
"sync_successful_processed"
widget=
"boolean_toggle"
/>
attrs=
"{'invisible': ['|',('pdf_file', '=', False),('show_error_message', '!=', False)]}"
/>
</group>
<group
attrs=
"{'invisible': ['|', ('pdf_file', '=', False), ('sync_successful_processed', '=', False)]}"
>
<field
name=
"sync_last_mile_pod"
widget=
"boolean_toggle"
/>
</group>
</group>
<group>
<group
attrs=
"{'invisible': ['|', ('pdf_file', '=', False), ('sync_successful_processed', '=', False)]}"
>
<field
name=
"sync_match_node"
widget=
"boolean_toggle"
<field
name=
"sync_match_node"
widget=
"boolean_toggle"
/>
attrs=
"{'invisible': ['|',('pdf_file', '=', False),('show_error_message', '!=', False)]}"
/>
</group>
</group>
<!-- </group> -->
<!-- </group> -->
...
@@ -34,13 +35,13 @@
...
@@ -34,13 +35,13 @@
<strong>
Remove Specified Text:
</strong>
<strong>
Remove Specified Text:
</strong>
Remove specified text (AGN, UCLINK LOGISITICS LTD) from PDF files
Remove specified text (AGN, UCLINK LOGISITICS LTD) from PDF files
</li>
<!-- 涂抹指定文字:对PDF文件中的指定文字进行涂抹处理 -->
</li>
<!-- 涂抹指定文字:对PDF文件中的指定文字进行涂抹处理 -->
<li
attrs=
"{'invisible': [
'|',('pdf_file', '=', False),('show_error_message', '!
=', False)]}"
>
<li
attrs=
"{'invisible': [
('sync_successful_processed', '
=', False)]}"
>
<strong>
Sync Last Mile POD:
</strong>
<strong>
Sync Last Mile POD:
</strong>
Synchronize POD (Proof of Delivery) attachment information with TK system, including
Synchronize POD (Proof of Delivery) attachment information with TK system, including
big package quantities and container numbers
big package quantities and container numbers
</li>
<!-- 同步尾程POD:向TK同步尾程交接POD(待大包数量和箱号)的附件信息 -->
</li>
<!-- 同步尾程POD:向TK同步尾程交接POD(待大包数量和箱号)的附件信息 -->
<li
attrs=
"{'invisible': [
'|',('pdf_file', '=', False),('show_error_message', '!
=', False)]}"
>
<li
attrs=
"{'invisible': [
('sync_successful_processed', '
=', False)]}"
>
<strong>
Sync Push Match Node:
</strong>
<strong>
Sync Push Match Node:
</strong>
Synchronize and push matched node information based on POD file, extract time from
Synchronize and push matched node information based on POD file, extract time from
red boxes as node operation time
red boxes as node operation time
...
@@ -60,8 +61,9 @@
...
@@ -60,8 +61,9 @@
<button
string=
"Preview"
type=
"object"
name=
"action_preview"
class=
"btn-primary"
<button
string=
"Preview"
type=
"object"
name=
"action_preview"
class=
"btn-primary"
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
/>
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
/>
<!-- 确认按钮:使用已处理的文件数据进行回写和同步 -->
<!-- 确认按钮:使用已处理的文件数据进行回写和同步 -->
<!-- 如果有失败的文件(show_error_message不为空),需要勾选sync_successful_processed才显示;如果全部成功,直接显示 -->
<button
string=
"Confirm"
type=
"object"
name=
"confirm"
class=
"btn-primary"
<button
string=
"Confirm"
type=
"object"
name=
"confirm"
class=
"btn-primary"
attrs=
"{'invisible': [
('pdf_file
', '=', False)]}"
/>
attrs=
"{'invisible': [
'|', ('pdf_file', '=', False), '&', ('show_error_message', '!=', False), ('sync_successful_processed
', '=', False)]}"
/>
<button
string=
"Close"
special=
"cancel"
/>
<button
string=
"Close"
special=
"cancel"
/>
</footer>
</footer>
</sheet>
</sheet>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论