Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
hh_ccs
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
贺阳
hh_ccs
Commits
065ffcc3
提交
065ffcc3
authored
10月 30, 2025
作者:
贺阳
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
定时清理向导生成的临时附件
上级
d9d75008
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
98 行增加
和
64 行删除
+98
-64
timer.xml
ccs_base/data/timer.xml
+14
-0
ai_image_edit_service.py
ccs_base/wizard/ai_image_edit_service.py
+1
-19
batch_get_pod_info_wizard.py
ccs_base/wizard/batch_get_pod_info_wizard.py
+80
-42
batch_get_pod_info_wizard_views.xml
ccs_base/wizard/batch_get_pod_info_wizard_views.xml
+3
-3
没有找到文件。
ccs_base/data/timer.xml
浏览文件 @
065ffcc3
...
...
@@ -25,5 +25,18 @@
<field
name=
"active"
eval=
"True"
/>
</record>
<!-- 清理向导生成的临时附件-->
<record
id=
"cron_cleanup_temp_attachments"
model=
"ir.cron"
>
<field
name=
"name"
>
清理向导临时附件
</field>
<field
name=
"model_id"
ref=
"model_batch_get_pod_info_wizard"
/>
<field
name=
"state"
>
code
</field>
<field
name=
"code"
>
model.cron_cleanup_temp_attachments()
</field>
<field
name=
'interval_number'
>
1
</field>
<field
name=
'interval_type'
>
days
</field>
<field
name=
"nextcall"
eval=
"(DateTime.now().replace(hour=0, minute=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"
/>
<field
name=
"numbercall"
>
-1
</field>
<field
name=
"active"
eval=
"True"
/>
</record>
</data>
</odoo>
\ No newline at end of file
ccs_base/wizard/ai_image_edit_service.py
浏览文件 @
065ffcc3
...
...
@@ -32,8 +32,7 @@ class AIImageEditService:
start_time
=
time
.
time
()
_logger
.
info
(
f
"开始AI图片编辑,目标文字: {text_to_remove}"
)
print
(
f
"开始AI图片编辑,目标文字: {text_to_remove}"
)
# 添加print输出
try
:
# 根据要移除的文字构建不同的提示词,强调保持清晰度
if
"AGN"
in
text_to_remove
and
"UCLINK"
in
text_to_remove
:
...
...
@@ -70,23 +69,18 @@ class AIImageEditService:
if
rsp
.
status_code
==
HTTPStatus
.
OK
:
# 检查返回结果结构
_logger
.
info
(
f
"API响应结构: {rsp}"
)
print
(
f
"API响应结构: {rsp}"
)
# 检查任务状态
if
hasattr
(
rsp
,
'output'
)
and
hasattr
(
rsp
.
output
,
'task_status'
):
task_status
=
rsp
.
output
.
task_status
_logger
.
info
(
f
"AI任务状态: {task_status}"
)
print
(
f
"AI任务状态: {task_status}"
)
if
task_status
==
"FAILED"
:
error_code
=
getattr
(
rsp
.
output
,
'code'
,
'Unknown'
)
error_message
=
getattr
(
rsp
.
output
,
'message'
,
'Unknown error'
)
_logger
.
error
(
f
"AI任务失败 - 错误码: {error_code}, 错误信息: {error_message}"
)
print
(
f
"AI任务失败 - 错误码: {error_code}, 错误信息: {error_message}"
)
return
None
elif
task_status
!=
"SUCCEEDED"
:
_logger
.
warning
(
f
"AI任务状态异常: {task_status}"
)
print
(
f
"AI任务状态异常: {task_status}"
)
return
None
# 安全地获取处理后图片的URL
...
...
@@ -94,35 +88,23 @@ class AIImageEditService:
if
hasattr
(
rsp
,
'output'
)
and
hasattr
(
rsp
.
output
,
'results'
)
and
len
(
rsp
.
output
.
results
)
>
0
:
image_url
=
rsp
.
output
.
results
[
0
]
.
url
_logger
.
info
(
f
"AI图片编辑成功,图片URL: {image_url}"
)
print
(
f
"AI图片编辑成功,图片URL: {image_url}"
)
# 添加print输出
# 下载图片并转换为base64
download_start_time
=
time
.
time
()
edited_image_base64
=
self
.
download_and_convert_to_base64
(
image_url
)
download_end_time
=
time
.
time
()
download_time
=
download_end_time
-
download_start_time
_logger
.
info
(
f
"图片下载耗时: {download_time:.2f}秒"
)
total_time
=
time
.
time
()
-
start_time
_logger
.
info
(
f
"AI图片编辑总耗时: {total_time:.2f}秒"
)
print
(
f
"AI图片编辑总耗时: {total_time:.2f}秒"
)
# 添加print输出
return
edited_image_base64
else
:
_logger
.
error
(
f
"API返回结果结构异常: {rsp}"
)
print
(
f
"API返回结果结构异常: {rsp}"
)
return
None
except
(
IndexError
,
AttributeError
)
as
e
:
_logger
.
error
(
f
"解析API返回结果失败: {str(e)}"
)
_logger
.
error
(
f
"完整响应: {rsp}"
)
print
(
f
"解析API返回结果失败: {str(e)}"
)
print
(
f
"完整响应: {rsp}"
)
return
None
else
:
_logger
.
error
(
f
"AI图片编辑失败,HTTP返回码:{rsp.status_code}"
)
_logger
.
error
(
f
"错误码:{rsp.code}"
)
_logger
.
error
(
f
"错误信息:{rsp.message}"
)
print
(
f
"AI图片编辑失败,HTTP返回码:{rsp.status_code}"
)
# 添加print输出
return
None
except
Exception
as
e
:
...
...
ccs_base/wizard/batch_get_pod_info_wizard.py
浏览文件 @
065ffcc3
...
...
@@ -8,10 +8,10 @@ import logging
import
time
import
requests
from
odoo
import
models
,
fields
,
_
from
odoo
import
models
,
fields
,
api
,
_
from
odoo.exceptions
import
ValidationError
from
.ai_image_edit_service
import
AIImageEditService
from
datetime
import
datetime
,
timedelta
_logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -19,6 +19,82 @@ class BatchGetPodInfoWizard(models.TransientModel):
_name
=
'batch.get.pod.info.wizard'
_description
=
'Batch Get POD Info Wizard'
# 批量获取POD信息向导
@api.model
def
cron_cleanup_temp_attachments
(
self
):
"""
定时清理向导生成的临时附件
每天早上8点执行,删除1天之前创建的temp_pod_开头的附件
"""
try
:
# 计算1天前的时间(前一天23:59:59)
today
=
datetime
.
now
()
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
)
one_day_ago
=
today
-
timedelta
(
seconds
=
1
)
# 前一天23:59:59
_logger
.
info
(
f
"开始执行定时清理临时附件任务,清理时间点: {one_day_ago.strftime('
%
Y-
%
m-
%
d
%
H:
%
M:
%
S')}"
)
# 使用SQL查询查找1天之前创建的临时附件
_logger
.
info
(
"使用SQL查询查找临时附件"
)
# 构建SQL查询
sql_query
=
"""
SELECT id, name, res_model, res_id, create_date, store_fname
FROM ir_attachment
WHERE res_model = 'batch.get.pod.info.wizard'
AND create_date < '
%
s'
ORDER BY create_date DESC
"""
%
(
one_day_ago
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
))
# 执行SQL查询
self
.
env
.
cr
.
execute
(
sql_query
)
sql_results
=
self
.
env
.
cr
.
fetchall
()
# 将SQL结果转换为Odoo记录集
if
sql_results
:
attachment_ids
=
[
result
[
0
]
for
result
in
sql_results
]
temp_attachments
=
self
.
env
[
'ir.attachment'
]
.
sudo
()
.
browse
(
attachment_ids
)
attachment_count
=
len
(
temp_attachments
)
attachment_names
=
[
att
.
name
for
att
in
temp_attachments
]
_logger
.
info
(
f
"找到 {attachment_count} 个{one_day_ago.strftime('
%
Y-
%
m-
%
d')}之前创建的临时附件,开始清理"
)
# 删除物理文件
for
attachment
in
temp_attachments
:
try
:
# 获取附件的物理文件路径
if
hasattr
(
attachment
,
'store_fname'
)
and
attachment
.
store_fname
:
# Odoo 12+ 使用 store_fname
file_path
=
attachment
.
store_fname
elif
hasattr
(
attachment
,
'datas_fname'
)
and
attachment
.
datas_fname
:
# 旧版本使用 datas_fname
file_path
=
attachment
.
datas_fname
else
:
# 尝试从 name 字段构建路径
file_path
=
attachment
.
name
# 构建完整的文件路径
import
os
from
odoo.tools
import
config
# 获取 Odoo 数据目录
data_dir
=
config
.
filestore
(
self
.
env
.
cr
.
dbname
)
if
data_dir
and
file_path
:
full_path
=
os
.
path
.
join
(
data_dir
,
file_path
)
if
os
.
path
.
exists
(
full_path
):
os
.
remove
(
full_path
)
_logger
.
info
(
f
"已删除物理文件: {full_path}"
)
else
:
_logger
.
warning
(
f
"物理文件不存在: {full_path}"
)
except
Exception
as
file_e
:
_logger
.
warning
(
f
"删除物理文件失败 {attachment.name}: {str(file_e)}"
)
# 删除数据库记录
temp_attachments
.
unlink
()
_logger
.
info
(
f
"定时清理完成,共删除 {attachment_count} 个{one_day_ago.strftime('
%
Y-
%
m-
%
d')}之前创建的临时附件: {', '.join(attachment_names[:5])}{'...' if len(attachment_names) > 5 else ''}"
)
else
:
_logger
.
info
(
f
"没有找到{one_day_ago.strftime('
%
Y-
%
m-
%
d')}之前创建的临时附件需要清理"
)
except
Exception
as
e
:
_logger
.
error
(
f
"定时清理临时附件失败: {str(e)}"
)
def
get_order
(
self
):
"""
得到单据
...
...
@@ -201,7 +277,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
}
# 回写到附件信息
if
processed_files
:
if
processed_files
and
(
self
.
sync_last_mile_pod
or
self
.
sync_match_node
)
:
logging
.
info
(
f
"回写PDF文件到清关文件,共 {len(processed_files)} 个文件"
)
# 回写PDF文件到清关文件
self
.
_write_pdf_file
(
processed_files
)
...
...
@@ -817,33 +893,10 @@ class BatchGetPodInfoWizard(models.TransientModel):
mat
=
fitz
.
Matrix
(
3.0
,
3.0
)
# 进一步提高分辨率,从2.0提升到3.0
pix
=
page
.
get_pixmap
(
matrix
=
mat
)
img_data
=
pix
.
tobytes
(
"png"
)
# 转换为base64
img_base64
=
base64
.
b64encode
(
img_data
)
.
decode
(
'utf-8'
)
# 保存AI转换前的图片用于对比
try
:
import
os
from
datetime
import
datetime
timestamp
=
datetime
.
now
()
.
strftime
(
'
%
Y
%
m
%
d_
%
H
%
M
%
S'
)
before_ai_filename
=
f
"before_ai_{bl_no}_page{page_num + 1}_{timestamp}.png"
# 创建保存目录
save_dir
=
os
.
path
.
join
(
os
.
getcwd
(),
"ai_comparison_images"
)
if
not
os
.
path
.
exists
(
save_dir
):
os
.
makedirs
(
save_dir
)
before_ai_path
=
os
.
path
.
join
(
save_dir
,
before_ai_filename
)
# 保存原始图片
with
open
(
before_ai_path
,
'wb'
)
as
f
:
f
.
write
(
img_data
)
_logger
.
info
(
f
"已保存AI转换前的图片: {before_ai_path}"
)
print
(
f
"已保存AI转换前的图片: {before_ai_path}"
)
# 添加print输出
except
Exception
as
e
:
_logger
.
warning
(
f
"保存AI转换前图片失败: {str(e)}"
)
print
(
f
"保存AI转换前图片失败: {str(e)}"
)
# 添加print输出
# 使用AI编辑图片,移除指定文字
ai_start_time
=
time
.
time
()
edited_img_base64
=
ai_service
.
edit_image_remove_text
(
...
...
@@ -856,21 +909,6 @@ class BatchGetPodInfoWizard(models.TransientModel):
if
edited_img_base64
:
# 解码base64图片数据
edited_img_data
=
base64
.
b64decode
(
edited_img_base64
)
# 保存AI转换后的图片用于对比
try
:
after_ai_filename
=
f
"after_ai_{bl_no}_page{page_num + 1}_{timestamp}.png"
after_ai_path
=
os
.
path
.
join
(
save_dir
,
after_ai_filename
)
# 保存AI处理后的图片
with
open
(
after_ai_path
,
'wb'
)
as
f
:
f
.
write
(
edited_img_data
)
_logger
.
info
(
f
"已保存AI转换后的图片: {after_ai_path}"
)
print
(
f
"已保存AI转换后的图片: {after_ai_path}"
)
# 添加print输出
except
Exception
as
e
:
_logger
.
warning
(
f
"保存AI转换后图片失败: {str(e)}"
)
print
(
f
"保存AI转换后图片失败: {str(e)}"
)
# 添加print输出
# 保存处理后的图片数据
processed_pages
.
append
({
'img_data'
:
edited_img_data
,
...
...
ccs_base/wizard/batch_get_pod_info_wizard_views.xml
浏览文件 @
065ffcc3
...
...
@@ -28,16 +28,16 @@
<div
class=
"alert alert-info"
role=
"alert"
>
<strong>
Description:
</strong>
<!-- 说明: -->
<ul>
<li>
<li
attrs=
"{'invisible': [('pdf_file', '!=', False)]}"
>
<strong>
Sync Last Mile POD:
</strong>
Synchronize POD (Proof of Delivery) attachment information with TK system, including
big package quantities and container numbers
</li>
<!-- 同步尾程POD:向TK同步尾程交接POD(待大包数量和箱号)的附件信息 -->
<li>
<li
attrs=
"{'invisible': ['|',('pdf_file', '=', False),('show_error_message', '!=', False)]}"
>
<strong>
Remove Specified Text:
</strong>
Remove specified text (AGN, UCLINK LOGISITICS LTD) from PDF files
</li>
<!-- 涂抹指定文字:对PDF文件中的指定文字进行涂抹处理 -->
<li>
<li
attrs=
"{'invisible': ['|',('pdf_file', '=', False),('show_error_message', '!=', False)]}"
>
<strong>
Sync Push Match Node:
</strong>
Synchronize and push matched node information based on POD file, extract time from
red boxes as node operation time
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论