提交 85aad0cf authored 作者: 伍姿英's avatar 伍姿英

Merge branch 'release/3.11.0'

...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
'views/cc_history_package_sync_log_view.xml', 'views/cc_history_package_sync_log_view.xml',
'views/history_tt_api_log.xml', 'views/history_tt_api_log.xml',
'views/res_partner_view.xml', 'views/res_partner_view.xml',
'views/config_setting.xml',
'views/menu_view.xml', 'views/menu_view.xml',
# 'views/cc_customers_declaration_order_view.xml', # 'views/cc_customers_declaration_order_view.xml',
'templates/login.xml', 'templates/login.xml',
......
...@@ -17,6 +17,15 @@ class ResConfigSettings(models.TransientModel): ...@@ -17,6 +17,15 @@ class ResConfigSettings(models.TransientModel):
is_package_scan = fields.Boolean( is_package_scan = fields.Boolean(
'一键全扫开关', default=False, config_parameter='is_package_scan') '一键全扫开关', default=False, config_parameter='is_package_scan')
# OCR 相关配置
baidu_ocr_app_id = fields.Char(string="Baidu OCR App ID", config_parameter='ocr.baidu_app_id')
baidu_ocr_api_key = fields.Char(string="Baidu OCR API Key", config_parameter='ocr.baidu_api_key')
baidu_ocr_secret_key = fields.Char(string="Baidu OCR Secret Key", config_parameter='ocr.baidu_secret_key')
ocr_enabled = fields.Boolean(string="是否启用 OCR", config_parameter='ocr.enabled', default=True)
ocr_timeout = fields.Integer(string="OCR 超时时间(秒)", config_parameter='ocr.timeout', default=30)
ocr_max_retries = fields.Integer(string="最大重试次数", config_parameter='ocr.max_retries', default=3)
@api.model @api.model
def get_values(self): def get_values(self):
""" """
......
差异被折叠。
{
"baidu_ocr_app_id": "118782515",
"baidu_ocr_api_key": "gWnGCmjJYzaYwhph8sJEdiRJ",
"baidu_ocr_secret_key": "mjgUUgbxXK8UHcRi5MTlPrb4BWM8NrOu",
"ocr_enabled": true,
"ocr_timeout": 30,
"max_retries": 3
}
\ No newline at end of file
#!/usr/bin/env python3
"""
百度OCR配置文件
用于管理百度OCR API的相关配置参数
"""
import os
import json
from typing import Dict, Optional
class BaiduOCRConfig:
"""百度OCR配置管理类"""
def __init__(self, config_file: str = None):
"""
初始化配置管理器
Args:
config_file: 配置文件路径,默认为当前目录下的baidu_ocr_config.json
"""
if config_file is None:
config_file = os.path.join(os.path.dirname(__file__), 'baidu_ocr_config.json')
self.config_file = config_file
self._config = self._load_config()
def _load_config(self) -> Dict:
"""
从配置文件加载配置
Returns:
配置字典
"""
# 默认配置
default_config = {
"baidu_ocr_app_id": "118782515",
"baidu_ocr_api_key": "gWnGCmjJYzaYwhph8sJEdiRJ",
"baidu_ocr_secret_key": "mjgUUgbxXK8UHcRi5MTlPrb4BWM8NrOu",
"ocr_enabled": True,
"ocr_timeout": 30,
"max_retries": 3
}
# 如果配置文件存在,则加载
if os.path.exists(self.config_file):
try:
with open(self.config_file, 'r', encoding='utf-8') as f:
file_config = json.load(f)
# 合并默认配置和文件配置
default_config.update(file_config)
except (json.JSONDecodeError, IOError) as e:
print(f"警告:无法读取配置文件 {self.config_file}: {e}")
print("使用默认配置")
else:
# 创建默认配置文件
self._save_config(default_config)
return default_config
def _save_config(self, config: Dict) -> None:
"""
保存配置到文件
Args:
config: 配置字典
"""
try:
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=4, ensure_ascii=False)
except IOError as e:
print(f"警告:无法保存配置文件 {self.config_file}: {e}")
def get(self, key: str, default=None):
"""
获取配置值
Args:
key: 配置键
default: 默认值
Returns:
配置值
"""
# 优先从环境变量获取
env_value = os.getenv(key.upper())
if env_value:
return env_value
return self._config.get(key, default)
def set(self, key: str, value) -> None:
"""
设置配置值
Args:
key: 配置键
value: 配置值
"""
self._config[key] = value
self._save_config(self._config)
def get_app_id(self) -> str:
"""获取百度OCR App ID"""
return self.get('baidu_ocr_app_id', '')
def get_api_key(self) -> str:
"""获取百度OCR API Key"""
return self.get('baidu_ocr_api_key', '')
def get_secret_key(self) -> str:
"""获取百度OCR Secret Key"""
return self.get('baidu_ocr_secret_key', '')
def is_ocr_enabled(self) -> bool:
"""检查OCR是否启用"""
return self.get('ocr_enabled', True)
def get_timeout(self) -> int:
"""获取OCR请求超时时间"""
return self.get('ocr_timeout', 30)
def get_max_retries(self) -> int:
"""获取最大重试次数"""
return self.get('max_retries', 3)
def is_configured(self) -> bool:
"""
检查百度OCR是否已正确配置
Returns:
True如果配置完整,False否则
"""
app_id = self.get_app_id()
api_key = self.get_api_key()
secret_key = self.get_secret_key()
return bool(app_id and api_key and secret_key)
def get_all_config(self) -> Dict:
"""获取所有配置"""
return self._config.copy()
# def update_config(self, config_dict: Dict) -> None:
# """
# 批量更新配置
#
# Args:
# config_dict: 配置字典
# """
# self._config.update(config_dict)
# self._save_config(self._config)
def update_config(self, config_dict: Dict, save_to_file: bool = True) -> None:
"""
批量更新配置
Args:
config_dict: 配置字典
save_to_file: 是否将配置持久化写入本地 JSON 文件
"""
self._config.update(config_dict)
if save_to_file:
self._save_config(self._config)
# 全局配置实例
baidu_ocr_config = BaiduOCRConfig()
def get_baidu_ocr_config() -> BaiduOCRConfig:
"""
获取百度OCR配置实例
Returns:
BaiduOCRConfig实例
"""
return baidu_ocr_config
def check_baidu_ocr_config() -> bool:
"""
检查百度OCR配置是否可用
Returns:
True如果配置可用,False否则
"""
try:
config = get_baidu_ocr_config()
# 检查基本配置
if not config.is_configured():
return False
# 检查是否启用OCR
if not config.is_ocr_enabled():
return False
# 尝试导入百度OCR SDK
try:
from aip import AipOcr
# 尝试初始化客户端
client = AipOcr(
config.get_app_id(),
config.get_api_key(),
config.get_secret_key()
)
# 如果能成功创建客户端,认为配置可用
return True
except ImportError as e:
import sys
print(f"警告: 百度OCR SDK (baidu-aip) 导入失败: {e}", file=sys.stderr)
print("请运行: pip install baidu-aip", file=sys.stderr)
# 如果是在Docker中,提示重建
if os.path.exists('/.dockerenv'):
print("提示: 检测到Docker环境,请尝试重新构建镜像: docker build --no-cache -t david-customs-data .", file=sys.stderr)
return False
except Exception as e:
print(f"警告: 百度OCR客户端初始化失败: {e}")
return False
except Exception as e:
print(f"警告: 百度OCR配置检查失败: {e}")
return False
def get_config_status() -> Dict:
"""
获取详细的配置状态信息
Returns:
配置状态字典
"""
config = get_baidu_ocr_config()
status = {
'app_id_configured': bool(config.get_app_id()),
'api_key_configured': bool(config.get_api_key()),
'secret_key_configured': bool(config.get_secret_key()),
'ocr_enabled': config.is_ocr_enabled(),
'timeout': config.get_timeout(),
'max_retries': config.get_max_retries(),
'fully_configured': config.is_configured()
}
# 添加部分配置信息(隐藏敏感信息)
if status['app_id_configured']:
app_id = config.get_app_id()
status['app_id_preview'] = app_id[:8] + '...' if len(app_id) > 8 else app_id
if status['api_key_configured']:
api_key = config.get_api_key()
status['api_key_preview'] = api_key[:8] + '...' if len(api_key) > 8 else api_key
if status['secret_key_configured']:
secret_key = config.get_secret_key()
status['secret_key_preview'] = secret_key[:8] + '...' if len(secret_key) > 8 else secret_key
# 检查SDK可用性
try:
from aip import AipOcr
status['sdk_available'] = True
except ImportError:
status['sdk_available'] = False
return status
if __name__ == "__main__":
# 测试配置
config = get_baidu_ocr_config()
print("百度OCR配置测试:")
print(f"App ID: {config.get_app_id()}")
print(f"API Key: {config.get_api_key()}")
print(f"Secret Key: {config.get_secret_key()}")
print(f"OCR启用: {config.is_ocr_enabled()}")
print(f"超时时间: {config.get_timeout()}秒")
print(f"最大重试: {config.get_max_retries()}次")
print(f"配置完整: {config.is_configured()}")
\ No newline at end of file
差异被折叠。
差异被折叠。
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="res_config_settings_view_form_ocr_inherit" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.ocr</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('app_settings_block')]/div" position="before">
<!-- OCR 配置板块 -->
<div id="ocr_baidu_config">
<h2>百度 OCR 接口配置</h2>
<div class="row mt16 o_settings_container">
<!-- 开启/关闭开关 -->
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="ocr_enabled"/>
</div>
<div class="o_setting_right_pane">
<label for="ocr_enabled"/>
<div class="text-muted">
开启后,系统将自动识别附件 PDF 中的提单号
</div>
</div>
</div>
<!-- 百度参数设置 -->
<div class="col-12 col-lg-6 o_setting_box" attrs="{'invisible': [('ocr_enabled', '=', False)]}">
<div class="o_setting_right_pane">
<div class="content-group">
<div class="row mt16">
<label for="baidu_ocr_app_id" string="App ID" class="col-lg-3 o_light_label"/>
<field name="baidu_ocr_app_id"/>
</div>
<div class="row">
<label for="baidu_ocr_api_key" string="API Key" class="col-lg-3 o_light_label"/>
<field name="baidu_ocr_api_key"/>
</div>
<div class="row">
<label for="baidu_ocr_secret_key" string="Secret Key" class="col-lg-3 o_light_label"/>
<field name="baidu_ocr_secret_key" password="True"/>
</div>
</div>
</div>
</div>
<!-- 超时与重试设置 -->
<div class="col-12 col-lg-6 o_setting_box" attrs="{'invisible': [('ocr_enabled', '=', False)]}">
<div class="o_setting_right_pane">
<div class="text-muted">
<label for="ocr_timeout" string="超时时间(秒)"/>
<field name="ocr_timeout" style="width: 50px;"/>
</div>
<div class="text-muted">
<label for="ocr_max_retries" string="最大重试次数"/>
<field name="ocr_max_retries" style="width: 50px;"/>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
...@@ -105,7 +105,8 @@ class TT(models.Model): ...@@ -105,7 +105,8 @@ class TT(models.Model):
} }
request_url = tt_url + url request_url = tt_url + url
logging.info('request_url: %s' % request_url) logging.info('request_url: %s' % request_url)
logging.info('request_data: %s' % parameter) if 'clearance_file_feedback' not in request_url:
logging.info('request_data: %s' % parameter)
response = requests.post(request_url, headers=headers, data=parameter) response = requests.post(request_url, headers=headers, data=parameter)
logging.info('response: %s' % response.text) logging.info('response: %s' % response.text)
# response = {'code': 0} # response = {'code': 0}
......
...@@ -6,6 +6,7 @@ numpy ...@@ -6,6 +6,7 @@ numpy
Pillow Pillow
tesseract tesseract
pytesseract pytesseract
baidu-aip
# 系统依赖安装说明: # 系统依赖安装说明:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论